![]() |
RTBKit
0.9
Open-source framework to create real-time ad bidding systems.
|
00001 /* signal.cc 00002 Jeremy Barnes, 15 November 2010 00003 Copyright (c) 2010 Datacratic. All rights reserved. 00004 00005 Code to deal with notifiers. 00006 */ 00007 00008 #include "signal.h" 00009 #include "jml/utils/pair_utils.h" 00010 #include "v8.h" 00011 #include "soa/js/js_utils.h" 00012 #include "soa/jsoncpp/json.h" 00013 00014 using namespace std; 00015 using namespace ML; 00016 00017 00018 namespace Datacratic { 00019 00020 /*****************************************************************************/ 00021 /* SIGNAL INFO */ 00022 /*****************************************************************************/ 00023 00024 Json::Value 00025 SignalInfo:: 00026 toJson() const 00027 { 00028 Json::Value result; 00029 result["name"] = eventName; 00030 result["callbackType"] = ML::demangle(*callbackType); 00031 result["objectType"] = ML::demangle(*objectType); 00032 result["inherited"] = inherited; 00033 return result; 00034 } 00035 00036 00037 /*****************************************************************************/ 00038 /* SIGNAL REGISTRY BASE */ 00039 /*****************************************************************************/ 00040 00041 SignalRegistryBase:: 00042 SignalRegistryBase() 00043 { 00044 } 00045 00046 SignalRegistryBase:: 00047 SignalRegistryBase(SignalRegistryBase & inheritFrom) 00048 { 00049 inheritSignals(inheritFrom); 00050 } 00051 00052 SignalRegistryBase:: 00053 ~SignalRegistryBase() 00054 { 00055 std::for_each(parentRegistrations.begin(), parentRegistrations.end(), 00056 [&] (boost::signals2::connection & conn) 00057 { conn.disconnect(); }); 00058 } 00059 00060 std::vector<std::string> 00061 SignalRegistryBase:: 00062 names() const 00063 { 00064 return vector<string>(ML::first_extractor(signals.begin()), 00065 ML::first_extractor(signals.end())); 00066 } 00067 00068 SignalInfo 00069 SignalRegistryBase:: 00070 info(const std::string & name) const 00071 { 00072 auto it = signals.find(name); 00073 if (it == signals.end()) 00074 throw Exception("no signal by name of " + name); 00075 return it->second; 00076 } 00077 00078 SlotDisconnector 00079 SignalRegistryBase:: 00080 doOn(const std::string & name, 00081 void * object, 00082 const std::type_info & objectType, 00083 const Slot & slot, 00084 int priority) const 00085 { 00086 auto it = signals.find(name); 00087 if (it == signals.end()) 00088 throw ML::Exception("no signal " + name); 00089 return it->second.registerFn(object, objectType, name, slot, priority, 0); 00090 } 00091 00092 void 00093 SignalRegistryBase:: 00094 inheritSignals(SignalRegistryBase & inheritFrom) 00095 { 00096 for (auto it = inheritFrom.signals.begin(), 00097 end = inheritFrom.signals.end(); 00098 it != end; ++it) 00099 addSignal(it->second, true /* inherited */); 00100 00101 parentRegistrations.push_back 00102 (inheritFrom.newEvent.connect 00103 (boost::bind(&SignalRegistryBase::addSignal, this, _2, true))); 00104 } 00105 00106 void 00107 SignalRegistryBase:: 00108 add(const std::string & eventName, 00109 //const std::string & description, // TODO: would be nice... 00110 const std::type_info & callbackType, 00111 const std::type_info & objectType, 00112 RegisterFn registerFn, void * data) 00113 { 00114 Info info; 00115 info.eventName = eventName; 00116 info.callbackType = &callbackType; 00117 info.objectType = &objectType; 00118 info.registerFn = registerFn; 00119 info.data = data; 00120 info.inherited = false; 00121 00122 addSignal(info, false /* inherited */); 00123 } 00124 00125 void 00126 SignalRegistryBase:: 00127 addSignal(const Info & signal, bool inherited) 00128 { 00129 std::string name = signal.eventName; 00130 bool exists = signals.count(name); 00131 Info & info = signals[name]; 00132 00133 if (exists) { 00134 if (info.inherited && inherited) 00135 throw ML::Exception("signal " + signal.eventName 00136 + " was inherited twice"); 00137 00138 if (!info.inherited && !inherited) 00139 throw ML::Exception("signal " + signal.eventName 00140 + " was added twice"); 00141 00142 if (info.callbackType != signal.callbackType) 00143 throw ML::Exception("signal " + signal.eventName 00144 + " had inherited callback type " 00145 + ML::demangle(*signal.callbackType) 00146 + " but local callback type " 00147 + ML::demangle(*info.callbackType)); 00148 00149 // The inherited version shouldn't override our local version 00150 if (!info.inherited && inherited) 00151 return; 00152 } 00153 00154 info = signal; 00155 info.inherited = inherited; 00156 00157 // Notify anything that needs to know that we have a new event 00158 newEvent(*this, info); 00159 } 00160 00161 } // namespace Datacratic