RTBKit
0.9
Open-source framework to create real-time ad bidding systems.
|
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 }