mirror of
https://github.com/Relintai/rcpp_framework.git
synced 2024-11-10 00:52:11 +01:00
Added a signal class.
This commit is contained in:
parent
b613349a11
commit
d42311356f
107
core/signal.cpp
Normal file
107
core/signal.cpp
Normal file
@ -0,0 +1,107 @@
|
||||
#include "signal.h"
|
||||
|
||||
void Signal::connect_static(void (*func)(Signal *)) {
|
||||
StaticSignalEntry *se = new StaticSignalEntry();
|
||||
se->func = func;
|
||||
|
||||
entries.push_back(se);
|
||||
}
|
||||
void Signal::disconnect_static(void (*func)(Signal *)) {
|
||||
for (int i = 0; i < entries.size(); ++i) {
|
||||
SignalEntry *e = entries[i];
|
||||
|
||||
if (e->type == SIGNAL_ENTRY_TYPE_STATIC) {
|
||||
StaticSignalEntry *se = static_cast<StaticSignalEntry *>(e);
|
||||
|
||||
if (se->func == func) {
|
||||
entries.remove_keep_order(i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
bool Signal::is_connected_static(void (*func)(Signal *)) {
|
||||
for (int i = 0; i < entries.size(); ++i) {
|
||||
SignalEntry *e = entries[i];
|
||||
|
||||
if (e->type == SIGNAL_ENTRY_TYPE_STATIC) {
|
||||
StaticSignalEntry *se = static_cast<StaticSignalEntry *>(e);
|
||||
|
||||
if (se->func == func) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void Signal::emit() {
|
||||
for (int i = 0; i < entries.size(); ++i) {
|
||||
entries[i]->call(this);
|
||||
}
|
||||
}
|
||||
|
||||
void Signal::emit(const Variant &p1) {
|
||||
params.push_back(p1);
|
||||
|
||||
for (int i = 0; i < entries.size(); ++i) {
|
||||
entries[i]->call(this);
|
||||
}
|
||||
|
||||
params.clear();
|
||||
}
|
||||
void Signal::emit(const Variant &p1, const Variant &p2) {
|
||||
params.push_back(p1);
|
||||
params.push_back(p2);
|
||||
|
||||
for (int i = 0; i < entries.size(); ++i) {
|
||||
entries[i]->call(this);
|
||||
}
|
||||
|
||||
params.clear();
|
||||
}
|
||||
void Signal::emit(const Variant &p1, const Variant &p2, const Variant &p3) {
|
||||
params.push_back(p1);
|
||||
params.push_back(p2);
|
||||
params.push_back(p3);
|
||||
|
||||
for (int i = 0; i < entries.size(); ++i) {
|
||||
entries[i]->call(this);
|
||||
}
|
||||
|
||||
params.clear();
|
||||
}
|
||||
|
||||
void Signal::emit(const Variant &p1, const Variant &p2, const Variant &p3, const Variant &p4) {
|
||||
params.push_back(p1);
|
||||
params.push_back(p2);
|
||||
params.push_back(p3);
|
||||
params.push_back(p4);
|
||||
|
||||
for (int i = 0; i < entries.size(); ++i) {
|
||||
entries[i]->call(this);
|
||||
}
|
||||
|
||||
params.clear();
|
||||
}
|
||||
|
||||
void Signal::emit(const Variant &p1, const Variant &p2, const Variant &p3, const Variant &p4, const Variant &p5) {
|
||||
params.push_back(p1);
|
||||
params.push_back(p2);
|
||||
params.push_back(p3);
|
||||
params.push_back(p4);
|
||||
params.push_back(p5);
|
||||
|
||||
for (int i = 0; i < entries.size(); ++i) {
|
||||
entries[i]->call(this);
|
||||
}
|
||||
|
||||
params.clear();
|
||||
}
|
||||
|
||||
Signal::Signal() :
|
||||
Object() {
|
||||
}
|
||||
Signal::~Signal() {
|
||||
}
|
174
core/signal.h
Normal file
174
core/signal.h
Normal file
@ -0,0 +1,174 @@
|
||||
#ifndef SIGNAL_H
|
||||
#define SIGNAL_H
|
||||
|
||||
#include "core/containers/vector.h"
|
||||
#include "core/string.h"
|
||||
#include "core/variant.h"
|
||||
|
||||
#include "reference.h"
|
||||
|
||||
class Signal : public Object {
|
||||
RCPP_OBJECT(Signal, Object);
|
||||
|
||||
public:
|
||||
Object *owner;
|
||||
Vector<Variant> params;
|
||||
Vector<Variant> static_data;
|
||||
|
||||
template <class T>
|
||||
void connect(T *obj, void (*func)(T*, Signal *));
|
||||
template <class T>
|
||||
void disconnect(T *obj, void (*func)(T*, Signal *));
|
||||
template <class T>
|
||||
bool is_connected(T *obj, void (*func)(T*, Signal *));
|
||||
|
||||
void connect_static(void (*func)(Signal *));
|
||||
void disconnect_static(void (*func)(Signal *));
|
||||
bool is_connected_static(void (*func)(Signal *));
|
||||
|
||||
void emit();
|
||||
void emit(const Variant &p1);
|
||||
void emit(const Variant &p1, const Variant &p2);
|
||||
void emit(const Variant &p1, const Variant &p2, const Variant &p3);
|
||||
void emit(const Variant &p1, const Variant &p2, const Variant &p3, const Variant &p4);
|
||||
void emit(const Variant &p1, const Variant &p2, const Variant &p3, const Variant &p4, const Variant &p5);
|
||||
|
||||
Signal();
|
||||
~Signal();
|
||||
|
||||
protected:
|
||||
enum SignalEntryType {
|
||||
SIGNAL_ENTRY_TYPE_NONE = 0,
|
||||
SIGNAL_ENTRY_TYPE_STATIC = 1,
|
||||
SIGNAL_ENTRY_TYPE_CLASS = 2,
|
||||
};
|
||||
|
||||
struct SignalEntry {
|
||||
SignalEntryType type;
|
||||
|
||||
virtual void call(Signal *s) {
|
||||
}
|
||||
|
||||
SignalEntry() {
|
||||
type = SIGNAL_ENTRY_TYPE_NONE;
|
||||
}
|
||||
};
|
||||
|
||||
struct StaticSignalEntry : public SignalEntry {
|
||||
void (*func)(Signal *);
|
||||
|
||||
virtual void call(Signal *s) {
|
||||
func(s);
|
||||
}
|
||||
|
||||
StaticSignalEntry() {
|
||||
type = SIGNAL_ENTRY_TYPE_STATIC;
|
||||
func = nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
struct ClassSignalEntry : public SignalEntry {
|
||||
|
||||
virtual void* get_obj_ptr() {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
virtual void* get_func_ptr() {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ClassSignalEntry() {
|
||||
type = SIGNAL_ENTRY_TYPE_CLASS;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct ClassSignalEntrySpec : public ClassSignalEntry {
|
||||
union {
|
||||
T* obj;
|
||||
void* obj_ptr;
|
||||
};
|
||||
union {
|
||||
void (*func)(T*, Signal *);
|
||||
void* func_ptr;
|
||||
};
|
||||
|
||||
virtual void call(Signal *s) {
|
||||
func(obj, s);
|
||||
}
|
||||
|
||||
void* get_obj_ptr() {
|
||||
return obj_ptr;
|
||||
}
|
||||
|
||||
void* get_func_ptr() {
|
||||
return func_ptr;
|
||||
}
|
||||
|
||||
ClassSignalEntrySpec() {
|
||||
obj = nullptr;
|
||||
func = nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
protected:
|
||||
Vector<SignalEntry *> entries;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
void Signal::connect(T *obj, void (*func)(T*, Signal *)) {
|
||||
ClassSignalEntrySpec<T> *ce = new ClassSignalEntrySpec<T>();
|
||||
ce->obj = obj;
|
||||
ce->func = func;
|
||||
|
||||
entries.push_back(ce);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void Signal::disconnect(T *obj, void (*func)(T*, Signal *)) {
|
||||
ClassSignalEntrySpec<T> t;
|
||||
t.obj = obj;
|
||||
t.func = func;
|
||||
|
||||
void* obj_ptr = t.obj_ptr;
|
||||
void* func_ptr = t.func_ptr;
|
||||
|
||||
for (int i = 0; i < entries.size(); ++i) {
|
||||
SignalEntry *e = entries[i];
|
||||
|
||||
if (e->type == SIGNAL_ENTRY_TYPE_CLASS) {
|
||||
ClassSignalEntry *se = static_cast<ClassSignalEntry *>(e);
|
||||
|
||||
if (se->get_obj_ptr() == obj_ptr && se->get_func_ptr() == func_ptr) {
|
||||
entries.remove_keep_order(i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool Signal::is_connected(T *obj, void (*func)(T*, Signal *)) {
|
||||
ClassSignalEntrySpec<T> t;
|
||||
t.obj = obj;
|
||||
t.func = func;
|
||||
|
||||
void* obj_ptr = t.obj_ptr;
|
||||
void* func_ptr = t.func_ptr;
|
||||
|
||||
for (int i = 0; i < entries.size(); ++i) {
|
||||
SignalEntry *e = entries[i];
|
||||
|
||||
if (e->type == SIGNAL_ENTRY_TYPE_CLASS) {
|
||||
ClassSignalEntry *se = static_cast<ClassSignalEntry *>(e);
|
||||
|
||||
if (se->get_obj_ptr() == obj_ptr && se->get_func_ptr() == func_ptr) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user