1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
|
#ifndef ODFAEG_OBJECT_HPP
#define ODFAEG_OBJECT_HPP
#include "signal.h"
#include "trigger.h"
#include "erreur.h"
#include "actionMap.h"
#include <thread>
#include <map>
#include <mutex>
#include <condition_variable>
#include "export.hpp"
namespace odfaeg {
class ODFAEG_CORE_API Listener {
public :
Listener() {
running = false, g_notified = true, one_triggered = false;
listen();
}
void connect(std::string key, Command command) {
std::map<std::string, Command*>::iterator it = commands.find(key);
if (it != commands.end()) {
throw(20, "This connection already exists!", 0);
}
commands.insert(std::pair<std::string, Command*>(key, new Command(command)));
}
template <typename O, typename...A> void setCommandParams (std::string key, O* object, A... args) {
std::map<std::string, Command*>::iterator it = commands.find(key);
if (it == commands.end())
throw Erreur(2, "No such connexion!", 6);
it->second->setParams(object, std::forward<A>(args)...);
}
template <typename O1, typename O2, typename...A> void setCommandParams (std::string key,O1* o1, O2* o2, A... args) {
std::map<std::string, Command*>::iterator it = commands.find(key);
if (it == commands.end()) {
throw Erreur(2, "No such connexion!", 6);
}
it->second->setParams(o1, std::forward<A>(args)..., o2, std::forward<A>(args)...);
}
template <typename...A> void setCommandParams (std::string key, A... args) {
std::map<std::string, Command*>::iterator it = commands.find(key);
if (it == commands.end()) {
throw Erreur(2, "No such connexion!", 6);
}
it->second->setParams(std::forward<A>(args)...);
}
template <typename F, typename O, typename...A> void setCommandParams (std::string key, O* object, A... args) {
std::map<std::string, Command*>::iterator it = commands.find(key);
if (it == commands.end())
throw Erreur(2, "No such connexion!", 6);
it->second->setParams<F>(object, std::forward<A>(args)...);
}
template <typename F1, typename F2, typename O1, typename O2, typename...A> void setCommandParams (std::string key,O1* o1, O2* o2, A... args,F1 f1 = nullptr, F2 f2 = nullptr) {
std::map<std::string, Command*>::iterator it = commands.find(key);
if (it == commands.end()) {
throw Erreur(2, "No such connexion!", 6);
}
it->second->setParams<F1, F2>(o1, std::forward<A>(args)..., o2, std::forward<A>(args)...);
}
template <typename F, typename...A> void setCommandParams (std::string key, A... args, F f = nullptr) {
std::map<std::string, Command*>::iterator it = commands.find(key);
if (it == commands.end()) {
throw Erreur(2, "No such connexion!", 6);
}
it->second->setParams<F>(std::forward<A>(args)...);
}
bool isOneTriggered() {
std::map<std::string, Command*>::iterator it;
for (it = commands.begin(); it != commands.end(); it++) {
if (it->second->isTriggered()) {
return true;
}
}
return false;
}
void run () {
std::map<std::string, Command*>::iterator it;
while (running) {
std::unique_lock<std::mutex> locker(g_lock_listen);
g_signal.wait(locker, [&](){return one_triggered || !running;});
for (it = commands.begin(); it != commands.end(); it++) {
if (it->second->isTriggered())
(*it->second)();
}
Command::clearEventsStack();
g_notified = true;
one_triggered = false;
g_signal.notify_one();
}
}
void pushEvent(sf::Event event) {
std::map<std::string, Command*>::iterator it;
for (it = commands.begin(); it != commands.end(); it++) {
if(it->second->containsBufferEvent(event) && !it->second->containsEvent(event)) {
Command::pushEvent(event);
}
}
}
void processEvents() {
g_notified = false;
one_triggered = true;
g_signal.notify_one();
std::unique_lock<std::mutex> locker(g_lock_listen);
g_signal.wait(locker, [&](){return g_notified;});
}
~Listener () {
stopListen();
}
private :
void listen () {
t = std::thread(&Listener::run, this);
running = true;
}
void stopListen() {
running = false;
g_signal.notify_one();
}
std::map<std::string, Command*> commands;
std::thread t;
bool running, g_notified, one_triggered;
std::mutex g_lock_listen;
std::condition_variable g_signal;
};
}
#endif |
Partager