RTBKit  0.9
Open-source framework to create real-time ad bidding systems.
soa/sigslot/testing/signal_slot_test_module.cc
00001 /* signal_slot_test_module.cc
00002    Jeremy Barnes, 17 November 2010
00003    Copyright (c) 2010 Datacratic.  All rights reserved.
00004 
00005    Module for testing of signals/slots mechanism.
00006 */
00007 
00008 
00009 #include <signal.h>
00010 #include "soa/js/js_wrapped.h"
00011 #include "soa/js/js_utils.h"
00012 #include "soa/js/js_registry.h"
00013 #include "v8.h"
00014 #include "jml/compiler/compiler.h"
00015 #include "soa/sigslot/signal.h"
00016 #include "soa/sigslot/slot_impl_js.h"
00017 #include "soa/sigslot/slot_js.h"
00018 #include "jml/arch/rtti_utils.h"
00019 #include "jml/utils/string_functions.h"
00020 #include <cxxabi.h>
00021 #include "soa/js/js_call.h"
00022 #include "soa/jsoncpp/json.h"
00023 
00024 using namespace std;
00025 using namespace Datacratic;
00026 
00027 struct SignalSlotTest {
00028 
00029     SignalSlotTest()
00030     {
00031     }
00032 
00033     virtual ~SignalSlotTest()
00034     {
00035     }
00036 
00037     SlotDisconnector
00038     on(const std::string & event, const Slot & slot)
00039     {
00040         return signals().on(event, this, slot);
00041     }
00042 
00043     typedef void (Event1) (const std::string &);
00044 
00045     SlotDisconnector onEvent1(const boost::function<Event1> & fn,
00046                               int priority = 0)
00047     {
00048         return event1.connect(priority, fn);
00049     }
00050 
00051     boost::signals2::signal<Event1> event1;
00052 
00053     typedef void (Event2) (int i);
00054 
00055     virtual SlotDisconnector onEvent2(const boost::function<Event2> & fn,
00056                                       int priority = 0)
00057     {
00058         return event2.connect(priority, fn);
00059     }
00060     
00061     boost::signals2::signal<Event2> event2;
00062 
00063     static void addSignals()
00064     {
00065         signals_.add<Event1, &SignalSlotTest::onEvent1>("event1");
00066         signals_.add<Event2, &SignalSlotTest::onEvent2>("event2");
00067     }
00068 
00069     virtual std::string objectType() const
00070     {
00071         return "SignalSlotTest";
00072     }
00073 
00074     virtual const SignalRegistryBase & signals() const
00075     {
00076         return signals_;
00077     }
00078 
00079     void doEvent1(const std::string & s)
00080     {
00081         event1(s);
00082     }
00083 
00084     void doEvent2(int i)
00085     {
00086         event2(i);
00087     }
00088 
00089     static SignalRegistry<SignalSlotTest> signals_;
00090     static DoRegisterSignals reg;
00091 };
00092 
00093 RegisterJsOps<SignalSlotTest::Event1> reg1;
00094 RegisterJsOps<SignalSlotTest::Event2> reg2;
00095 
00096 SignalRegistry<SignalSlotTest> SignalSlotTest::signals_;
00097 DoRegisterSignals SignalSlotTest::reg(addSignals);
00098 
00099 using namespace Datacratic::JS;
00100 using namespace v8;
00101 
00102 const char * SignalSlotTestName = "SignalSlotTest";
00103 const char * SignalSlotTestModule = "sig";
00104 
00105 //struct SignalSlotTestJS
00106 //    : public JS::JSWrapped3<SignalSlotTest, SignalSlotTestJS, JS::ObjectJS,
00107 //                            SignalSlotTestName, SignalSlotTestModule>;
00108 
00109 struct SignalSlotTestJS
00110     : public JS::JSWrapped2<SignalSlotTest, SignalSlotTestJS,
00111                             SignalSlotTestName, SignalSlotTestModule> {
00112 
00113     SignalSlotTestJS(const v8::Arguments & args)
00114     {
00115         std::shared_ptr<SignalSlotTest> obj
00116             (new SignalSlotTest());
00117         
00118         wrap(args.This(), obj);
00119     }
00120 
00121     static v8::Persistent<v8::FunctionTemplate>
00122     Initialize()
00123     {
00124         v8::Persistent<FunctionTemplate> t = Register(New, Setup);
00125         
00126         // Instance methods
00127         NODE_SET_PROTOTYPE_METHOD(t, "event1", event1);
00128         NODE_SET_PROTOTYPE_METHOD(t, "event2", event2);
00129         NODE_SET_PROTOTYPE_METHOD(t, "checkCast", checkCast);
00130         NODE_SET_PROTOTYPE_METHOD(t, "on", on);
00131         NODE_SET_PROTOTYPE_METHOD(t, "signalNames", signalNames);
00132         NODE_SET_PROTOTYPE_METHOD(t, "signalInfo", signalInfo);
00133 
00134         t->InstanceTemplate()
00135             ->SetAccessor(String::NewSymbol("lastIndex"), lastIndexGetter);
00136         
00137         return t;
00138     }
00139 
00140     static v8::Handle<v8::Value>
00141     New(const Arguments & args)
00142     {
00143         try {
00144             new SignalSlotTestJS(args);
00145             return args.This();
00146         } HANDLE_JS_EXCEPTIONS;
00147     }
00148 
00149     static v8::Handle<v8::Value>
00150     on(const Arguments & args)
00151     {
00152         try {
00153             string event = getArg(args, 0, "event");
00154             v8::Local<v8::Function> fn = getArg(args, 1, "callback");
00155             
00156             Slot s(fn); // = Slot::fromJs(fn, args.This());
00157             
00158             SlotDisconnector result = getShared(args)->on(event, s);
00159             
00160             return JS::toJS(Slot(result));
00161         } HANDLE_JS_EXCEPTIONS;
00162     }
00163 
00164     static v8::Handle<v8::Value>
00165     signalNames(const Arguments & args)
00166     {
00167         try {
00168             const SignalRegistryBase & signals
00169                 = getShared(args)->signals();
00170             vector<string> names = signals.names();
00171             return JS::toJS(names);
00172         } HANDLE_JS_EXCEPTIONS;
00173     }
00174     
00175     static v8::Handle<v8::Value>
00176     signalInfo(const Arguments & args)
00177     {
00178         try {
00179             return JS::toJS(getShared(args)
00180                             ->signals()
00181                             .info(getArg(args, 0, "signalName"))
00182                             .toJson());
00183         } HANDLE_JS_EXCEPTIONS;
00184     }
00185 
00186     static v8::Handle<v8::Value>
00187     event1(const Arguments & args)
00188     {
00189         try {
00190             int ntimes = getArg(args, 1, 1, "numTimes");
00191             for (unsigned i = 0;  i < ntimes;  ++i) {
00192                 getWrapper(args)->lastIndex = i;
00193                 getShared(args)->event1(getArg(args, 0, "intArg"));
00194             }
00195             getWrapper(args)->lastIndex = ntimes;
00196             return NULL_HANDLE;
00197         } HANDLE_JS_EXCEPTIONS;
00198     }
00199 
00200     int lastIndex;
00201 
00202     static v8::Handle<v8::Value>
00203     lastIndexGetter(v8::Local<v8::String> property,
00204                     const AccessorInfo & info)
00205     {
00206         try {
00207             return v8::Integer::New(getWrapper(info.This())->lastIndex);
00208         } HANDLE_JS_EXCEPTIONS;
00209     }
00210     
00211     static v8::Handle<v8::Value>
00212     event2(const Arguments & args)
00213     {
00214         try {
00215             int ntimes = getArg(args, 1, 1, "numTimes");
00216             for (unsigned i = 0;  i < ntimes;  ++i)
00217                 getShared(args)->event2(getArg(args, 0, "stringArg"));
00218             return NULL_HANDLE;
00219         } HANDLE_JS_EXCEPTIONS;
00220     }
00221 
00222     static v8::Handle<v8::Value>
00223     checkCast(const Arguments & args)
00224     {
00225         try {
00226             SignalSlotTest * obj = getShared(args);
00227             const void * converted1
00228                 = ML::is_convertible(typeid(SignalSlotTest),
00229                                      typeid(SignalSlotTest),
00230                                      obj);
00231             
00232             SignalSlotTest * converted2
00233                 = dynamic_cast<SignalSlotTest *>(obj);
00234 
00235             v8::Local<v8::Array> result(v8::Array::New(2));
00236             result->Set(v8::Uint32::New(0),
00237                         v8::String::New(ML::format("%p", converted1).c_str()));
00238             result->Set(v8::Uint32::New(1),
00239                         v8::String::New(ML::format("%p", converted2).c_str()));
00240             
00241             return result;
00242         } HANDLE_JS_EXCEPTIONS;
00243     }
00244 
00245 };
00246 
00247 typedef void (DoSomething) ();
00248 RegisterJsOps<DoSomething> reg_void;
00249 
00250 extern "C" void
00251 init(Handle<v8::Object> target)
00252 {
00253     registry.init(target, SignalSlotTestModule);
00254 }
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator