Add <functional> to files that use std::function
[lsnes.git] / src / core / queue.cpp
blob902bf93ee8a57da634c85f163cc4c34a622981a5
1 #include "core/misc.hpp"
2 #include "core/queue.hpp"
3 #include "core/random.hpp"
4 #include "library/command.hpp"
5 #include "library/threads.hpp"
6 #include <functional>
8 input_queue::input_queue(command::group& _command)
9 : command(_command)
11 functions_executed = 0;
12 next_function = 0;
13 system_thread_available = false;
14 queue_function_run = false;
18 keypress_info::keypress_info()
20 key1 = NULL;
21 key2 = NULL;
22 value = 0;
25 keypress_info::keypress_info(keyboard::modifier_set mod, keyboard::key& _key, short _value)
27 modifiers = mod;
28 key1 = &_key;
29 key2 = NULL;
30 value = _value;
33 keypress_info::keypress_info(keyboard::modifier_set mod, keyboard::key& _key, keyboard::key& _key2, short _value)
35 modifiers = mod;
36 key1 = &_key;
37 key2 = &_key2;
38 value = _value;
42 void input_queue::queue(const keypress_info& k) throw(std::bad_alloc)
44 threads::alock h(queue_lock);
45 keypresses.push_back(k);
46 queue_condition.notify_all();
49 void input_queue::queue(const std::string& c) throw(std::bad_alloc)
51 threads::alock h(queue_lock);
52 commands.push_back(std::make_pair(nullptr, c));
53 queue_condition.notify_all();
56 void input_queue::queue(const char* c, const std::string& a) throw(std::bad_alloc)
58 threads::alock h(queue_lock);
59 commands.push_back(std::make_pair(c, a));
60 queue_condition.notify_all();
63 void input_queue::queue(std::function<void()> f, std::function<void(std::exception& e)> onerror, bool sync)
64 throw(std::bad_alloc)
66 if(!system_thread_available) {
67 try {
68 f();
69 } catch(std::exception& e) {
70 onerror(e);
72 return;
74 threads::alock h(queue_lock);
75 ++next_function;
76 function_queue_entry entry;
77 entry.fn = f;
78 entry.onerror = onerror;
79 functions.push_back(entry);
80 queue_condition.notify_all();
81 if(sync)
82 while(functions_executed < next_function && system_thread_available) {
83 threads::cv_timed_wait(queue_condition, h, threads::ustime(10000));
84 random_mix_timing_entropy();
88 void input_queue::run_queue(bool unlocked) throw()
90 if(!unlocked)
91 queue_lock.lock();
92 try {
93 //Flush keypresses.
94 while(!keypresses.empty()) {
95 keypress_info k = keypresses.front();
96 keypresses.pop_front();
97 queue_lock.unlock();
98 if(k.key1)
99 k.key1->set_state(k.modifiers, k.value);
100 if(k.key2)
101 k.key2->set_state(k.modifiers, k.value);
102 queue_lock.lock();
103 queue_function_run = true;
105 //Flush commands.
106 while(!commands.empty()) {
107 auto c = commands.front();
108 commands.pop_front();
109 queue_lock.unlock();
110 if(c.first)
111 command.invoke(c.first, c.second);
112 else
113 command.invoke(c.second);
114 queue_lock.lock();
115 queue_function_run = true;
117 //Flush functions.
118 while(!functions.empty()) {
119 function_queue_entry f = functions.front();
120 functions.pop_front();
121 queue_lock.unlock();
122 try {
123 f.fn();
124 } catch(std::exception& e) {
125 f.onerror(e);
127 queue_lock.lock();
128 ++functions_executed;
129 queue_function_run = true;
131 queue_condition.notify_all();
132 } catch(std::bad_alloc& e) {
133 OOM_panic();
134 } catch(std::exception& e) {
135 std::cerr << "Fault inside platform::run_queues(): " << e.what() << std::endl;
136 exit(1);
138 if(!unlocked)
139 queue_lock.unlock();