mirror of
https://github.com/Relintai/rcpp_framework.git
synced 2025-05-06 17:51:36 +02: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