diff --git a/autowiring/EventOutputStream.h b/autowiring/EventOutputStream.h index bf2b9815e..685156200 100644 --- a/autowiring/EventOutputStream.h +++ b/autowiring/EventOutputStream.h @@ -5,6 +5,7 @@ #include #include #include +#include #include MEMORY_HEADER #include TYPE_TRAITS_HEADER diff --git a/autowiring/EventRegistry.h b/autowiring/EventRegistry.h new file mode 100644 index 000000000..f289ccf67 --- /dev/null +++ b/autowiring/EventRegistry.h @@ -0,0 +1,100 @@ +// Copyright (C) 2012-2014 Leap Motion, Inc. All rights reserved. +#pragma once +#include +#include STL_TUPLE_HEADER +#include MEMORY_HEADER + +template +class JunctionBox; + +class JunctionBoxBase; +class Object; + +// Checks if an Object* listens to a event T; +struct EventIdentifierBase { + virtual bool Is(const Object* obj) = 0; + virtual const std::type_info& Type() = 0; +}; + +template +struct EventIdentifier: + public EventIdentifierBase +{ + // true if "obj" is an event receiver for T + bool Is(const Object* obj){ + return !!dynamic_cast(obj); + } + + const std::type_info& Type(){ + return typeid(T); + } +}; + +struct EventRegistryEntry { + EventRegistryEntry(const std::type_info& ti); + + // Next entry in the list: + const EventRegistryEntry* const pFlink; + + // Type of this entry: + const std::type_info& ti; + + /// + /// The runtime type information corresponding to this entry + /// + virtual const std::type_info& GetTypeInfo(void) const = 0; + + /// + /// Constructor method, used to generate a new junction box + /// + virtual std::shared_ptr NewJunctionBox(void) const = 0; + + /// + /// Used to create a type identifier value, for use with AutoNet + /// + virtual std::shared_ptr NewEventIdentifier(void) const = 0; +}; + +template +struct EventRegistryEntryT: + public EventRegistryEntry +{ + EventRegistryEntryT(void): + EventRegistryEntry(typeid(T)) + {} + + virtual const std::type_info& GetTypeInfo(void) const override { return typeid(T); } + + + virtual std::shared_ptr NewJunctionBox(void) const override { + return std::static_pointer_cast( + std::make_shared>() + ); + } + + std::shared_ptr NewEventIdentifier(void) const override { + return std::static_pointer_cast( + std::make_shared>() + ); + } +}; + +extern const EventRegistryEntry* g_pFirstEventEntry; +extern size_t g_eventEntryCount; + +/// +/// Adds the specified type to the universal event registry +/// +/// +/// Any instance of this event registry parameterized on type T will be added to the +/// global static event registry, and this registry is computed at link time. +/// +template +class RegEvent +{ +public: + static const EventRegistryEntryT r; +}; + +template +const EventRegistryEntryT RegEvent::r; diff --git a/autowiring/JunctionBoxManager.h b/autowiring/JunctionBoxManager.h index e97e861de..7494d2a2a 100644 --- a/autowiring/JunctionBoxManager.h +++ b/autowiring/JunctionBoxManager.h @@ -1,5 +1,6 @@ // Copyright (C) 2012-2014 Leap Motion, Inc. All rights reserved. #pragma once +#include "EventRegistry.h" #include "JunctionBoxBase.h" #include "JunctionBoxEntry.h" #include "uuid.h" @@ -33,10 +34,12 @@ class JunctionBoxManager { template std::shared_ptr Get(void) { + // Add this type to the event registry. All events call this function + (void)RegEvent::r; const std::type_index& pTypeIndex = typeid(T); auto box = m_junctionBoxes.find(pTypeIndex); - assert(box != m_junctionBoxes.end()); + assert(box != m_junctionBoxes.end() && "If junction box isn't found, EventRegistry isn't working"); //Check here if any listening marshals might be interested in receiving the fired args auto mapfinditerator = m_eventOutputStreams.find(pTypeIndex); diff --git a/autowiring/TypeRegistry.h b/autowiring/TypeRegistry.h index 235ca390a..7295de054 100644 --- a/autowiring/TypeRegistry.h +++ b/autowiring/TypeRegistry.h @@ -46,11 +46,6 @@ struct TypeRegistryEntry { /// virtual const std::type_info& GetTypeInfo(void) const = 0; - /// - /// True if this type is an event receiver type - /// - //virtual bool IsEventReceiver(void) const = 0; - /// /// Constructor method, used to generate a new junction box /// diff --git a/src/autowiring/CMakeLists.txt b/src/autowiring/CMakeLists.txt index 3d5bd5f33..2043b3f7e 100644 --- a/src/autowiring/CMakeLists.txt +++ b/src/autowiring/CMakeLists.txt @@ -60,6 +60,8 @@ set(Autowiring_SRCS EventInputStream.h EventOutputStream.h EventOutputStream.cpp + EventRegistry.h + EventRegistry.cpp fast_pointer_cast.h JunctionBox.h JunctionBoxBase.h diff --git a/src/autowiring/EventRegistry.cpp b/src/autowiring/EventRegistry.cpp new file mode 100644 index 000000000..e3010b9e9 --- /dev/null +++ b/src/autowiring/EventRegistry.cpp @@ -0,0 +1,16 @@ +// Copyright (C) 2012-2014 Leap Motion, Inc. All rights reserved. +#include "stdafx.h" +#include "EventRegistry.h" +#include "JunctionBox.h" + +// Head of a linked list which will have node for every event type +const EventRegistryEntry* g_pFirstEventEntry = nullptr; +size_t g_eventEntryCount = 0; + +EventRegistryEntry::EventRegistryEntry(const std::type_info& ti) : + pFlink(g_pFirstEventEntry), + ti(ti) +{ + g_eventEntryCount++; + g_pFirstEventEntry = this; +} diff --git a/src/autowiring/JunctionBoxManager.cpp b/src/autowiring/JunctionBoxManager.cpp index 283ef7164..b82ba9eaf 100644 --- a/src/autowiring/JunctionBoxManager.cpp +++ b/src/autowiring/JunctionBoxManager.cpp @@ -7,12 +7,9 @@ JunctionBoxManager::JunctionBoxManager(void) { // Enumerate all event types to initialize a new JunctionBox for each - for(auto p = g_pFirstEntry; p; p = p->pFlink) + for (auto p = g_pFirstEventEntry; p; p = p->pFlink) m_junctionBoxes[p->ti] = p->NewJunctionBox(); - - // Ensure that these two types are specially mentioned: - (void) RegType::r; - + // Always allow internal events m_junctionBoxes[typeid(AutowiringEvents)]->Initiate(); }