blob: f4cda60440d40f70ce1db5fe42850bd77e5f3edc [file] [log] [blame]
Alex Vakulenkoaa3a5592014-08-07 07:24:06 -07001// Copyright 2014 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "buffet/commands/command_queue.h"
6
Vitaly Bukaae0f3a12015-05-11 16:27:30 -07007#include <base/bind.h>
Vitaly Buka2a9b30f2015-04-01 10:51:59 -07008#include <base/time/time.h>
9
Alex Vakulenkoaa3a5592014-08-07 07:24:06 -070010namespace buffet {
11
Vitaly Buka2a9b30f2015-04-01 10:51:59 -070012namespace {
13const int kRemoveCommandDelayMin = 5;
14}
15
Vitaly Bukaae0f3a12015-05-11 16:27:30 -070016void CommandQueue::AddOnCommandAddedCallback(const Callback& callback) {
17 on_command_added_.push_back(callback);
Vitaly Buka72410b22015-05-13 13:48:59 -070018 // Send all pre-existed commands.
19 for (const auto& command : map_)
20 callback.Run(command.second.get());
Vitaly Bukaae0f3a12015-05-11 16:27:30 -070021}
22
23void CommandQueue::AddOnCommandRemovedCallback(const Callback& callback) {
24 on_command_removed_.push_back(callback);
25}
26
Anton Muhin5191e812014-10-30 17:49:48 +040027void CommandQueue::Add(std::unique_ptr<CommandInstance> instance) {
28 std::string id = instance->GetID();
29 LOG_IF(FATAL, id.empty()) << "Command has no ID";
Alex Vakulenkof6b38712014-09-03 16:23:38 -070030 instance->SetCommandQueue(this);
Alex Vakulenkoaa3a5592014-08-07 07:24:06 -070031 auto pair = map_.insert(std::make_pair(id, std::move(instance)));
32 LOG_IF(FATAL, !pair.second) << "Command with ID '" << id
33 << "' is already in the queue";
Vitaly Bukaae0f3a12015-05-11 16:27:30 -070034 for (const auto& cb : on_command_added_)
35 cb.Run(pair.first->second.get());
Vitaly Buka2a9b30f2015-04-01 10:51:59 -070036 Cleanup();
Alex Vakulenkoaa3a5592014-08-07 07:24:06 -070037}
38
Vitaly Buka2a9b30f2015-04-01 10:51:59 -070039void CommandQueue::DelayedRemove(const std::string& id) {
Alex Vakulenkoaa3a5592014-08-07 07:24:06 -070040 auto p = map_.find(id);
Vitaly Buka2a9b30f2015-04-01 10:51:59 -070041 if (p == map_.end())
42 return;
43 remove_queue_.push(std::make_pair(
44 base::Time::Now() + base::TimeDelta::FromMinutes(kRemoveCommandDelayMin),
45 id));
46 Cleanup();
47}
48
49bool CommandQueue::Remove(const std::string& id) {
50 auto p = map_.find(id);
51 if (p == map_.end())
52 return false;
53 std::unique_ptr<CommandInstance> instance{std::move(p->second)};
54 instance->SetCommandQueue(nullptr);
55 map_.erase(p);
Vitaly Bukaae0f3a12015-05-11 16:27:30 -070056 for (const auto& cb : on_command_removed_)
57 cb.Run(instance.get());
Vitaly Buka2a9b30f2015-04-01 10:51:59 -070058 return true;
59}
60
61void CommandQueue::Cleanup() {
62 while (!remove_queue_.empty() && remove_queue_.front().first < Now()) {
63 Remove(remove_queue_.front().second);
64 remove_queue_.pop();
Alex Vakulenkoaa3a5592014-08-07 07:24:06 -070065 }
Vitaly Buka2a9b30f2015-04-01 10:51:59 -070066}
67
68void CommandQueue::SetNowForTest(base::Time now) {
69 test_now_ = now;
70}
71
72base::Time CommandQueue::Now() const {
73 return test_now_.is_null() ? base::Time::Now() : test_now_;
Alex Vakulenkoaa3a5592014-08-07 07:24:06 -070074}
75
Alex Vakulenkofedc4872014-08-20 12:38:43 -070076CommandInstance* CommandQueue::Find(const std::string& id) const {
Alex Vakulenkoaa3a5592014-08-07 07:24:06 -070077 auto p = map_.find(id);
78 return (p != map_.end()) ? p->second.get() : nullptr;
79}
80
81} // namespace buffet