Skip to content

Commit

Permalink
Added EventRegistry for types where an event is called
Browse files Browse the repository at this point in the history
  • Loading branch information
gtremper committed Aug 1, 2014
1 parent 36cf6d6 commit c8d5b1b
Show file tree
Hide file tree
Showing 7 changed files with 125 additions and 11 deletions.
1 change: 1 addition & 0 deletions autowiring/EventOutputStream.h
Expand Up @@ -5,6 +5,7 @@
#include <map>
#include <string>
#include <sstream>
#include <cassert>

#include MEMORY_HEADER
#include TYPE_TRAITS_HEADER
Expand Down
100 changes: 100 additions & 0 deletions autowiring/EventRegistry.h
@@ -0,0 +1,100 @@
// Copyright (C) 2012-2014 Leap Motion, Inc. All rights reserved.
#pragma once
#include <typeinfo>
#include STL_TUPLE_HEADER
#include MEMORY_HEADER

template<class T>
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<typename T>
struct EventIdentifier:
public EventIdentifierBase
{
// true if "obj" is an event receiver for T
bool Is(const Object* obj){
return !!dynamic_cast<const T*>(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;

/// <summary>
/// The runtime type information corresponding to this entry
/// </summary>
virtual const std::type_info& GetTypeInfo(void) const = 0;

/// <summary>
/// Constructor method, used to generate a new junction box
/// </summary>
virtual std::shared_ptr<JunctionBoxBase> NewJunctionBox(void) const = 0;

/// <summary>
/// Used to create a type identifier value, for use with AutoNet
/// </summary>
virtual std::shared_ptr<EventIdentifierBase> NewEventIdentifier(void) const = 0;
};

template<class T>
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<JunctionBoxBase> NewJunctionBox(void) const override {
return std::static_pointer_cast<JunctionBoxBase>(
std::make_shared<JunctionBox<T>>()
);
}

std::shared_ptr<EventIdentifierBase> NewEventIdentifier(void) const override {
return std::static_pointer_cast<EventIdentifierBase>(
std::make_shared<EventIdentifier<T>>()
);
}
};

extern const EventRegistryEntry* g_pFirstEventEntry;
extern size_t g_eventEntryCount;

/// <summary>
/// Adds the specified type to the universal event registry
/// </summary>
/// <remarks>
/// 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.
/// </remarks>
template<class T>
class RegEvent
{
public:
static const EventRegistryEntryT<T> r;
};

template<class T>
const EventRegistryEntryT<T> RegEvent<T>::r;
5 changes: 4 additions & 1 deletion 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"
Expand Down Expand Up @@ -33,10 +34,12 @@ class JunctionBoxManager {

template<typename T>
std::shared_ptr<JunctionBoxBase> Get(void) {
// Add this type to the event registry. All events call this function
(void)RegEvent<T>::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);
Expand Down
5 changes: 0 additions & 5 deletions autowiring/TypeRegistry.h
Expand Up @@ -46,11 +46,6 @@ struct TypeRegistryEntry {
/// </summary>
virtual const std::type_info& GetTypeInfo(void) const = 0;

/// <returns>
/// True if this type is an event receiver type
/// </returns>
//virtual bool IsEventReceiver(void) const = 0;

/// <summary>
/// Constructor method, used to generate a new junction box
/// </summary>
Expand Down
2 changes: 2 additions & 0 deletions src/autowiring/CMakeLists.txt
Expand Up @@ -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
Expand Down
16 changes: 16 additions & 0 deletions 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;
}
7 changes: 2 additions & 5 deletions src/autowiring/JunctionBoxManager.cpp
Expand Up @@ -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<AutowiringEvents>::r;


// Always allow internal events
m_junctionBoxes[typeid(AutowiringEvents)]->Initiate();
}
Expand Down

0 comments on commit c8d5b1b

Please sign in to comment.