+++ /dev/null
-
-#include "../core/WObject.h"
-#include "../core/WSignal.h"
-#include <string>
-
-using namespace TizenDisplayServer;
-
-using SignalAType = WSignal<int, int>;
-using SignalBType = WSignal<double, int>;
-
-class MJ : public WObject
-{
- public:
- MJ() : WObject("MJ"){ std::cout << "construct MJ" << std::endl;}
- MJ(std::string name) : WObject(name) {std::cout << "construct MJ" << name << std::endl;}
- ~MJ(){ std::cout << "destruct MJ" << std::endl;}
-
- struct SignalA : public SignalAType {
- int emit(int val) { return SignalAType::emit(val); }
- } signalA;
-
- struct SignalB : public SignalBType {
- double emit(int val) { return SignalBType::emit(val); }
- } signalB;
-};
-
-class Holder : public WObject {
- public:
- Holder() : WObject("Holder") {std::cout << "construct Holder" << std::endl;}
- Holder(std::string name) : WObject(name) {std::cout << "construct Holder" << std::endl;}
- ~Holder() {std::cout << "destruct Holder" << std::endl;}
-
- static int slotA(int a) { std::cout << "slotA invoked! a:" << a << std::endl; return 1; };
- static double slotB(int a) { std::cout << "slotB invoked! a:" << a << std::endl; return 123.456; };
- static int slotA2(int a) {std::cout << "slotA2 invoked! a:" << a << std::endl; return 2;}
-};
-
-int main (void)
-{
- MJ mj("mj");
- MJ mj2("mj2");
- Holder holder("h1");
- Holder holder2("h2");
-
- std::cout << "<<<<<<<< slotA connect to signala >>>>>>>>" << std::endl;
- mj.signalA.connect(&holder, Holder::slotA);
- std::cout << "<<<<<<<< slotA2 connect to signala >>>>>>>>" << std::endl;
- mj.signalA.connect(&holder, Holder::slotA2);
-
- std::cout << "<<<<<<<< slotB connect to signalB >>>>>>>>" << std::endl;
- mj.signalB.connect(&holder, Holder::slotB);
-
-
- int a = mj.signalA.emit(1234);
- double b = mj.signalB.emit(5678);
-
- return 0;
-}
\ No newline at end of file
--- /dev/null
+#include "../core/WObject.h"
+#include "../core/WSignal.h"
+#include "../core/WRefBase.h"
+#include <string>
+
+using namespace TizenDisplayServer;
+
+using SignalAType = WSignal<int>;
+using SignalBType = WSignal<double>;
+
+class Sender : public WObject
+{
+ public:
+ Sender() : WObject("Sender"){ std::cout << "construct Sender" << std::endl;}
+ Sender(std::string name) : WObject(name) {std::cout << "construct Sender " << name << std::endl;}
+ ~Sender(){ std::cout << "destruct Sender " << getName() << std::endl;}
+
+ struct SignalA : public SignalAType {
+ void emit(int val) { SignalAType::emit(val); }
+ } signalA;
+
+ struct SignalB : public SignalBType {
+ void emit(double val) { SignalBType::emit(val); }
+ } signalB;
+};
+
+class Receiver : public WObject, public WRefBase {
+ public:
+ Receiver() : WObject("Receiver"), WRefBase() { std::cout << "construct Receiver" << std::endl;}
+ Receiver(std::string name) : WObject(name), WRefBase() { std::cout << "construct Receiver " << name << std::endl;}
+ ~Receiver() { std::cout << "destruct Receiver(ref: " << getref() << ") " << getName() << std::endl; }
+
+ static void slotA(int a) { std::cout << "slotA invoked! a:" << a << std::endl; };
+ static void slotA2(int a) {std::cout << "slotA2 invoked! a:" << a << std::endl; }
+ static void slotB(double a) { std::cout << "slotB invoked! a:" << a << std::endl; };
+};
+
+int main (void)
+{
+ Sender *sender = new Sender("sender");
+ Sender *sender2 = new Sender("sender2");
+ Receiver *receiver = new Receiver("receiver1");
+ Receiver *receiver2 = new Receiver("receiver2");
+
+ sender->signalA.connect(receiver, Receiver::slotA);
+ sender->signalA.connect(receiver2, Receiver::slotA2);
+ sender->signalB.connect(receiver, Receiver::slotB);
+ sender->signalB.connect(receiver2, [](double val) {
+ std::cout << "Lambda slot invoked! val: " << val << std::endl;
+ });
+
+ sender->signalA.emit(1234);
+ sender->signalB.emit(45.67);
+
+ if (receiver2->getref() == 1)
+ {
+ receiver2->unref();
+ receiver2 = nullptr;
+ }
+
+ sender->signalB.emit(5678);
+ sender->signalA.emit(90.1);
+
+ delete sender;
+ delete sender2;
+ delete receiver;
+
+ return 0;
+}
\ No newline at end of file
WObjectPrivate::WObjectPrivate(WObject *p_ptr, std::string name) : p_ptr(p_ptr)
{
type_info.name = name;
- std::cout << "construct WObjectPrivate" << std::endl;
}
WObjectPrivate::~WObjectPrivate()
{
- std::cout << "destruct WObjectPrivate" << std::endl;
+ }
+
+ void WObjectPrivate::attachDestroyObserver(WObjectObserverIface *ob)
+ {
+ observers.push_back(ob);
+ }
+
+ void WObjectPrivate::detachDestroyObserver(WObjectObserverIface *ob)
+ {
+ observers.remove(ob);
+ }
+
+ bool WObjectPrivate::setProperty(std::string key, WProperty property)
+ {
+ }
+
+ WProperty& WObjectPrivate::getProperty(std::string key)
+ {
+ }
+
+ void WObjectPrivate::destroyNotify(void)
+ {
+ for (WObjectObserverIface* ob : observers)
+ {
+ ob->destroyed(p_ptr);
+ }
+ observers.clear();
+ }
+
+ std::string WObjectPrivate::getName(void)
+ {
+ return type_info.name;
}
WObject::WObject(std::string name)
{
- std::cout << "construct WOBject " << name <<std::endl;
std::unique_ptr<WObjectPrivate> ptr(new WObjectPrivate(this, name));
d_ptr = std::move(ptr);
}
WObject::~WObject(){
destroyNotify();
}
+
+ void WObject::destroyNotify(void)
+ {
+ d_func()->destroyNotify();
+ }
+
+ void WObject::attachDestroyObserver(WObjectObserverIface *ob)
+ {
+ d_func()->attachDestroyObserver(ob);
+ }
+
+ void WObject::detachDestroyObserver(WObjectObserverIface *ob)
+ {
+ d_func()->detachDestroyObserver(ob);
+ }
+
+ bool WObject::setProperty(std::string key, WProperty property)
+ {
+
+ }
+
+ WProperty& WObject::getProperty(std::string key)
+ {
+
+ }
+
+ std::string WObject::getName(void)
+ {
+ return d_func()->getName();
+ }
}
inline WObjectPrivate* d_func() { return d_ptr.get(); }
inline const WObjectPrivate* d_func() const { return d_ptr.get(); }
- friend class WObjectPrivate;
public:
- WObject(std::string name = "default");
+ WObject(std::string name = "WObject");
virtual ~WObject();
- void attachObserver(WObjectObserverIface *ob){}
- void detachObserver(WObjectObserverIface *ob){}
- void destroyNotify(void){}
- bool setProperty(std::string key, WProperty property){}
- WProperty& getProperty(std::string key){}
+ void attachDestroyObserver(WObjectObserverIface *ob);
+ void detachDestroyObserver(WObjectObserverIface *ob);
+ void destroyNotify(void);
+ bool setProperty(std::string key, WProperty property);
+ WProperty& getProperty(std::string key);
+
+ std::string getName(void);
};
class WObjectObserverIface {
class WObjectPrivate {
- struct {
+ struct TypeInfo{
std::string name;
-
- }type_info;
+ };
WObject *p_ptr;
std::list<WObjectObserverIface*> observers;
std::unordered_map<std::string, WProperty> properties;
+ TypeInfo type_info;
public:
WObjectPrivate() = delete;
inline const WObject *p_func() const{ return p_ptr;}
- void attachObserver(WObjectObserverIface *ob);
- void detachObserver(WObjectObserverIface *ob);
+ void attachDestroyObserver(WObjectObserverIface *ob);
+ void detachDestroyObserver(WObjectObserverIface *ob);
bool setProperty(std::string key, WProperty property);
WProperty& getProperty(std::string key);
+ void destroyNotify();
+
+ std::string getName(void);
};
}
#else
int mCount;
public:
- WRefBase() : mCount(0) {};
- virtual ~WRefBase();
+ WRefBase() : mCount(1) {}
+ virtual ~WRefBase() {}
- void ref() {++mCount;}
+ void ref() { ++mCount; }
void unref() {if (--mCount == 0) delete this;}
int getref() { return mCount; }
};
~WSlotsObserver(){}
virtual void destroyed(WObject *obj);
- void addSlot(WObject *slot);
+ virtual void addSlot(WObject *slot);
};
- template <typename R, typename... Args>
+ template <typename... Args>
class WSlotConnection : public WSlotsObserver{
//TODO: make callback as callback iface
//std::unique_ptr<WCallbackIface> callback;
- R (*callback)(Args...);
- template <typename _R, typename... _Args> friend class WSignal;
+ void (*callback)(Args...);
+ template <typename... _Args> friend class WSignal;
public:
WSlotConnection() {}
- WSlotConnection(WObject *slot, R (*func) (Args...)) : callback(func) {
+ WSlotConnection(WObject *slot, void (*func) (Args...)) : callback(func) {
//TODO: make callback as callback iface
//std::unique_ptr<WCallbackIface> ptr(new WCallbackIface(func));
//callback = std::move(ptr);
addSlot(slot);
}
- virtual ~WSlotConnection() {}
+ virtual ~WSlotConnection()
+ {
+ for (auto &&slot : slots)
+ slot->detachDestroyObserver(this);
+ slots.clear();
+ }
- void addSlot(WObject *slot)
+ void addSlot (WObject *slot) override
{
slots.push_back(slot);
+ slot->attachDestroyObserver(this);
}
- void destroyed(WObject *slot)
+ void destroyed(WObject *slot) override
{
slots.remove(slot);
if (slots.empty())
- delete this;
+ {
+ //TODO: detete from WSignal connections list with guarded pointer
+ }
}
- R invoke(Args... args)
+ void invoke(Args... args)
{
- if (!std::is_void<R>::value)
- {
- R ret = callback(args...);
- return ret;
- }
+ if (!slots.empty())
+ callback(args...);
}
};
- template <typename R, typename... Args>
+ template <typename... Args>
class WSignal {
- std::list<std::unique_ptr<WSlotConnection<R, Args...>>> connections;
- WSlotConnection<R, Args...> *findcon(R (*func)(Args...)) {
+ std::list<std::unique_ptr<WSlotConnection<Args...>>> connections;
+ WSlotConnection<Args...> *findcon(void (*func)(Args...)) {
for (auto&& con : connections)
{
if (con->callback == func)
WSignal() {}
virtual ~WSignal() {}
- WSignal<R, Args...>& operator()(void) { return *this; } // functor
+ WSignal<Args...>& operator()(void) { return *this; } // functor
- void connect(WObject *slot, R (*func)(Args...))
+ void connect(WObject *slot, void (*func)(Args...))
{
if ((!slot) || (!func))
return;
if (auto con = findcon(func))
+ {
con->addSlot(slot);
+ }
else
- connections.emplace_back(new WSlotConnection<R, Args...>(slot, func));
- }
-
- R emit(Args... args){
- if (!std::is_void<R>::value)
{
- R ret;
- for (auto &&con : connections)
- {
- ret = con->invoke(args...);
- }
- return ret;
+ connections.emplace_back(new WSlotConnection<Args...>(slot, func));
}
}
+
+ void emit(Args... args)
+ {
+ for (auto &&con : connections)
+ con->invoke(args...);
+ }
};
}
#else