/*
 * Copyright 2015 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "cobalt/base/event_dispatcher.h"

#include "base/logging.h"

namespace base {

EventDispatcher::~EventDispatcher() {}

void EventDispatcher::AddEventCallback(TypeId type, const EventCallback& cb) {
  base::AutoLock lock(lock_);
  event_callbacks_[type].push_back(cb);
}

void EventDispatcher::RemoveEventCallback(TypeId type,
                                          const EventCallback& cb) {
  base::AutoLock lock(lock_);
  std::vector<EventCallback>& v = event_callbacks_[type];
  for (std::vector<EventCallback>::iterator it = v.begin(); it != v.end();
       ++it) {
    if (it->Equals(cb)) {
      v.erase(it);
      break;
    }
  }
}

void EventDispatcher::DispatchEvent(scoped_ptr<Event> event) const {
  base::AutoLock lock(lock_);
  const TypeId type = event->GetTypeId();
  CallbackMap::const_iterator hash_it = event_callbacks_.find(type);
  if (hash_it == event_callbacks_.end()) {
    return;
  }

  const std::vector<EventCallback>& v = hash_it->second;
  for (std::vector<EventCallback>::const_iterator it = v.begin(); it != v.end();
       ++it) {
    it->Run(event.get());
  }
}

}  // namespace base
