18 template<
typename... Args>
class Slot;
24 template <
typename... Args>
28 using Function = std::function<void(Args... args)>;
67 template <
typename U,
typename F>
68 void connect(U*
object, F memberFunction) {
connect(std::bind(memberFunction,
object, std::placeholders::_1)); }
105 Slot<Args...>* mSlot;
109 enum class EType : uint8_t
119 std::vector<Data> mData;
120 std::unique_ptr<std::vector<Function>> mFunctionEffects;
128 template <
typename... Args>
132 using Function = std::function<void(Args... args)>;
143 mFunction(inFunction)
151 template <
typename U,
typename F>
152 Slot(U* parent, F memberFunction) :
153 mFunction(std::bind(memberFunction, parent, std::placeholders::_1))
162 template <
typename U,
typename F>
164 mFunction(std::bind(memberFunction, parent, std::placeholders::_1)) { signal.
connect(*
this); }
207 template<
typename... Args_>
friend class Signal;
208 typedef std::vector<
Signal<Args...>*> SignalList;
222 template <
typename... Args>
225 for (
auto& data : mData)
227 if (data.mType == Data::EType::SignalCause)
228 data.USignal.mSignal->disconnect(*
this);
229 else if (data.mType == Data::EType::SignalEffect)
230 data.USignal.mSignal->removeCause(*
this);
232 data.USlot.mSlot->removeCause(*
this);
236 template <
typename... Args>
240 data.mType = Data::EType::SignalCause;
241 data.USignal.mSignal = &signal;
242 mData.push_back(data);
245 template <
typename... Args>
246 void Signal<Args...>::removeCause(Signal<Args...>& event)
248 for (
int index = 0; index < mData.size(); ++index)
250 Data& value = mData[index];
251 if (value.mType == Data::EType::SignalCause && value.USignal.mSignal == &event)
253 mData.erase(mData.begin() + index);
259 template <
typename... Args>
263 data.mType = Data::EType::SignalEffect;
264 data.USignal.mSignal = &signal;
265 mData.push_back(data);
266 signal.addCause(*
this);
269 template <
typename... Args>
272 for (
int index = 0; index < mData.size(); ++index)
274 Data& value = mData[index];
275 if (value.mType == Data::EType::SignalEffect && value.USignal.mSignal == &signal)
277 value.USignal.mSignal->removeCause(*
this);
278 mData.erase(mData.begin() + index);
284 template <
typename... Args>
288 data.mType = Data::EType::SlotEffect;
289 data.USlot.mSlot = &slot;
290 mData.push_back(data);
291 slot.addCause(*
this);
294 template <
typename... Args>
297 for (
int index = 0; index < mData.size(); ++index)
299 Data& data = mData[index];
300 if (data.mType == Data::EType::SlotEffect && data.USlot.mSlot == &slot)
302 data.USlot.mSlot->removeCause(*
this);
303 mData.erase(mData.begin() + index);
310 template <
typename... Args>
313 if (!mFunctionEffects)
314 mFunctionEffects = std::make_unique<std::vector<Function>>();
316 mFunctionEffects->emplace_back(inFunction);
320 template <
typename... Args>
323 for (
auto& data : mData)
325 if (data.mType == Data::EType::SignalEffect)
326 data.USignal.mSignal->trigger(std::forward<Args>(args)...);
327 else if (data.mType == Data::EType::SlotEffect)
328 data.USlot.mSlot->trigger(std::forward<Args>(args)...);
331 if (mFunctionEffects)
332 for (
auto& effect : *mFunctionEffects)
333 effect(std::forward<Args>(args)...);
336 template <
typename... Args>
340 for (
auto cause : rhs.mCauses)
341 cause->connect(*
this);
344 template <
typename... Args>
348 mFunction = other.mFunction;
350 other.mFunction =
nullptr;
354 template <
typename... Args>
358 mFunction = other.mFunction;
362 template <
typename... Args>
366 mFunction(std::forward<Args>(args)...);
369 template <
typename... Args>
372 for (
int index = mCauses.size() - 1; index >= 0; --index)
376 template <
typename... Args>
379 mCauses.push_back(&event);
382 template <
typename... Args>
383 void Slot<Args...>::removeCause(Signal<Args...>& event)
385 for (
typename SignalList::iterator pos = mCauses.begin(); pos != mCauses.end(); ++pos)
387 if ((*pos) == &event)
404 #define NSLOT(NAME, TYPE, FUNCTION) nap::Slot<TYPE> NAME = {[&](TYPE inValue) -> void { FUNCTION(inValue); }};
407 #define CREATE_SLOT(NAME, TYPE) nap::Slot<TYPE> NAME;
410 #define BIND_SLOT(NAME, TYPE, FUNCTION) NAME([&](TYPE inValue) -> void { FUNCTION(inValue); })
413 #define NSIGNAL(NAME, TYPE) nap::Signal<TYPE> NAME;