Skip to content

Commit

Permalink
Merge pull request #33 from leapmotion/ref-declarativeboltable
Browse files Browse the repository at this point in the history
Declarative Boltable refactor
  • Loading branch information
gtremper committed Aug 6, 2014
2 parents 04b3736 + 0f90253 commit 230b121
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 3 deletions.
2 changes: 1 addition & 1 deletion autowiring/CoreContext.h
Expand Up @@ -211,7 +211,7 @@ class CoreContext:
template<typename T, typename... Sigils>
void EnableInternal(T*, Boltable<Sigils...>*) {
bool dummy[] = {
false,
false, // Ensure non-zero array size
(AutoRequireMicroBolt<T, Sigils>(), false)...
};
(void) dummy;
Expand Down
15 changes: 13 additions & 2 deletions autowiring/MicroBolt.h
@@ -1,6 +1,8 @@
// Copyright (C) 2012-2014 Leap Motion, Inc. All rights reserved.
#pragma once
#include "Bolt.h"
#include "CoreContext.h"
#include "ContextEnumerator.h"

/// <summary>
/// Causes the class inheriting from this definition to be bolted to the specified contexts
Expand All @@ -16,11 +18,20 @@ struct MicroBolt:
public Bolt<Sigils...>
{
public:
MicroBolt(void) {
// ASSERT: Inject<T>() is idempotent.
// NOTE: Injection of T into all matching contexts may result in
// multiple calls to Inject<T>() if a matching context
// is created during traversal.
std::shared_ptr<CoreContext> rootContext = CoreContext::CurrentContext();
auto listSigils = {ContextEnumeratorT<Sigils>(rootContext)...};
for (auto findSigil : listSigils)
for (auto context : findSigil)
context->template Inject<T>();
}
void ContextCreated(void) override;
};

#include "CoreContext.h"

template<typename T, typename... Sigils>
void MicroBolt<T, Sigils...>::ContextCreated(void) {
CoreContext::InjectCurrent<T>();
Expand Down
51 changes: 51 additions & 0 deletions src/autowiring/test/BoltTest.cpp
Expand Up @@ -194,3 +194,54 @@ TEST_F(BoltTest, EmptyBolt) {
ASSERT_EQ(1, innerSo->count) << "ContextCreated() called incorrect number of times";
}
}

template<class target>
class TargetBoltable: public Boltable<target> {
static int numCons;
static int numDest;

public:
static void InitializeNum() {
numCons = 0;
numDest = 0;
}
static int ConstructedNum() {return numCons;}
static int DestructedNum() {return numDest;}

TargetBoltable() {++numCons;}
~TargetBoltable() {++numDest;}
};
template<class target>
int TargetBoltable<target>::numCons = 0;
template<class target>
int TargetBoltable<target>::numDest = 0;

TEST_F(BoltTest, BoltBeforeContext) {
AutoCurrentContext ctxt;
TargetBoltable<Pipeline>::InitializeNum();
AutoEnable<TargetBoltable<Pipeline>>();
ASSERT_EQ(0, TargetBoltable<Pipeline>::ConstructedNum()) << "Instantiated Boltable without context";
auto otherCtx = ctxt->Create<OtherContext>();
ASSERT_EQ(0, TargetBoltable<Pipeline>::ConstructedNum()) << "Instantiated on creation of unmatched context";

{
auto created = ctxt->Create<Pipeline>();
ASSERT_EQ(1, TargetBoltable<Pipeline>::ConstructedNum()) << "Failed to instantiate on creation of matching context";
}
ASSERT_EQ(1, TargetBoltable<Pipeline>::DestructedNum()) << "Failed to be destroyed with matching context";
}

TEST_F(BoltTest, BoltAfterContext) {
AutoCurrentContext ctxt;
TargetBoltable<OtherContext>::InitializeNum();
TargetBoltable<Pipeline>::InitializeNum();

{
auto created = ctxt->Create<Pipeline>();
AutoEnable<TargetBoltable<OtherContext>>();
ASSERT_EQ(0, TargetBoltable<OtherContext>::ConstructedNum()) << "Instantiated Boltable without context";
AutoEnable<TargetBoltable<Pipeline>>();
ASSERT_EQ(1, TargetBoltable<Pipeline>::ConstructedNum()) << "Failed to instantiate on creation of matching context";
}
ASSERT_EQ(1, TargetBoltable<Pipeline>::DestructedNum()) << "Failed to be destroyed with matching context";
}

0 comments on commit 230b121

Please sign in to comment.