Lua: Fix type confusion between signed and unsigned
[lsnes.git] / src / core / queue.cpp
blobf10266145ac6b10dd3f30ab900008314a601ca5e
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"
7 input_queue::input_queue(command::group& _command)
8 : command(_command)
10 functions_executed = 0;
11 next_function = 0;
12 system_thread_available = false;
13 queue_function_run = false;
17 keypress_info::keypress_info()
19 key1 = NULL;
20 key2 = NULL;
21 value = 0;
24 keypress_info::keypress_info(keyboard::modifier_set mod, keyboard::key& _key, short _value)
26 modifiers = mod;
27 key1 = &_key;
28 key2 = NULL;
29 value = _value;
32 keypress_info::keypress_info(keyboard::modifier_set mod, keyboard::key& _key, keyboard::key& _key2, short _value)
34 modifiers = mod;
35 key1 = &_key;
36 key2 = &_key2;
37 value = _value;
41 void input_queue::queue(const keypress_info& k) throw(std::bad_alloc)
43 threads::alock h(queue_lock);
44 keypresses.push_back(k);
45 queue_condition.notify_all();
48 void input_queue::queue(const std::string& c) throw(std::bad_alloc)
50 threads::alock h(queue_lock);
51 commands.push_back(std::make_pair(nullptr, c));
52 queue_condition.notify_all();
55 void input_queue::queue(const char* c, const std::string& a) throw(std::bad_alloc)
57 threads::alock h(queue_lock);
58 commands.push_back(std::make_pair(c, a));
59 queue_condition.notify_all();
62 void input_queue::queue(std::function<void()> f, std::function<void(std::exception& e)> onerror, bool sync)
63 throw(std::bad_alloc)
65 if(!system_thread_available) {
66 try {
67 f();
68 } catch(std::exception& e) {
69 onerror(e);
71 return;
73 threads::alock h(queue_lock);
74 ++next_function;
75 function_queue_entry entry;
76 entry.fn = f;
77 entry.onerror = onerror;
78 functions.push_back(entry);
79 queue_condition.notify_all();
80 if(sync)
81 while(functions_executed < next_function && system_thread_available) {
82 threads::cv_timed_wait(queue_condition, h, threads::ustime(10000));
83 random_mix_timing_entropy();
87 void input_queue::run_queue(bool unlocked) throw()
89 if(!unlocked)
90 queue_lock.lock();
91 try {
92 //Flush keypresses.
93 while(!keypresses.empty()) {
94 keypress_info k = keypresses.front();
95 keypresses.pop_front();
96 queue_lock.unlock();
97 if(k.key1)
98 k.key1->set_state(k.modifiers, k.value);
99 if(k.key2)
100 k.key2->set_state(k.modifiers, k.value);
101 queue_lock.lock();
102 queue_function_run = true;
104 //Flush commands.
105 while(!commands.empty()) {
106 auto c = commands.front();
107 commands.pop_front();
108 queue_lock.unlock();
109 if(c.first)
110 command.invoke(c.first, c.second);
111 else
112 command.invoke(c.second);
113 queue_lock.lock();
114 queue_function_run = true;
116 //Flush functions.
117 while(!functions.empty()) {
118 function_queue_entry f = functions.front();
119 functions.pop_front();
120 queue_lock.unlock();
121 try {
122 f.fn();
123 } catch(std::exception& e) {
124 f.onerror(e);
126 queue_lock.lock();
127 ++functions_executed;
128 queue_function_run = true;
130 queue_condition.notify_all();
131 } catch(std::bad_alloc& e) {
132 OOM_panic();
133 } catch(std::exception& e) {
134 std::cerr << "Fault inside platform::run_queues(): " << e.what() << std::endl;
135 exit(1);
137 if(!unlocked)
138 queue_lock.unlock();