Skip to content

Commit

Permalink
Merge pull request #858 from leapmotion/feature-config2
Browse files Browse the repository at this point in the history
Add a configuration concept to Autowiring
  • Loading branch information
Veronica Zheng committed Mar 2, 2016
2 parents bead6e9 + c1fa2cd commit 179ad10
Show file tree
Hide file tree
Showing 30 changed files with 1,102 additions and 31 deletions.
Empty file.
Empty file added contrib/json11/stdafx.h
Empty file.
9 changes: 9 additions & 0 deletions src/autowiring/AnySharedPointer.h
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,15 @@ class AnySharedPointerT:
AnySharedPointer(std::shared_ptr<T>{})
{}

AnySharedPointerT(T&& value) :
AnySharedPointer(std::make_shared<T>(std::forward<T&&>(value)))
{}

template<typename U>
AnySharedPointerT(U&& value) :
AnySharedPointer(std::make_shared<T>(std::forward<U&&>(value)))
{}

T& operator*(void) { return *as<T>(); }
const T& operator*(void) const { return *as<T>(); }

Expand Down
2 changes: 1 addition & 1 deletion src/autowiring/Autowired.h
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ class Autowired:
};

template<typename U, typename... Args>
signal_relay<U,Args...> operator()(autowiring::signal<void(Args...)> U::*sig) {
signal_relay<U, Args...> operator()(autowiring::signal<void(Args...)> U::*sig) {
static_assert(std::is_base_of<U, T>::value, "Cannot reference member of unrelated type");
return signal_relay<U, Args... >(*this, sig);
}
Expand Down
11 changes: 11 additions & 0 deletions src/autowiring/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,13 @@ set(Autowiring_SRCS
callable.h
CallExtractor.h
CallExtractor.cpp
config.h
config_descriptor.h
config_descriptor.cpp
ConfigManager.h
ConfigManager.cpp
ConfigRegistry.h
ConfigRegistry.cpp
ContextEnumerator.cpp
ContextEnumerator.h
ContextMap.h
Expand Down Expand Up @@ -102,6 +109,7 @@ set(Autowiring_SRCS
hash_tuple.h
has_autofilter.h
has_autoinit.h
has_getconfigdescriptor.h
has_simple_constructor.h
has_static_new.h
has_validate.h
Expand All @@ -114,6 +122,7 @@ set(Autowiring_SRCS
is_shared_ptr.h
ManualThreadPool.h
ManualThreadPool.cpp
marshaller.h
member_new_type.h
MemoEntry.h
MemoEntry.cpp
Expand All @@ -125,8 +134,10 @@ set(Autowiring_SRCS
ObjectPool.h
ObjectPoolMonitor.cpp
ObjectPoolMonitor.h
observable.h
once.h
once.cpp
optional.h
Parallel.h
Parallel.cpp
registration.h
Expand Down
51 changes: 51 additions & 0 deletions src/autowiring/ConfigManager.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Copyright (C) 2012-2015 Leap Motion, Inc. All rights reserved.
#include "stdafx.h"
#include "ConfigManager.h"
#include <mutex>

using namespace autowiring;

ConfigManager::ConfigManager(void) :
m_empty("")
{}

void ConfigManager::Register(void* pObj, const config_descriptor& desc) {
std::lock_guard<autowiring::spin_lock> lk(m_lock);
for (const auto& field : desc.fields) {
Entry& entry = m_config[field.second.name];
entry.attached.push_back({
&field.second,
static_cast<uint8_t*>(pObj) + field.second.offset
});

if (entry.value)
entry.attached.back().field->marshaller->unmarshal(
entry.attached.back().pObj,
entry.value->c_str()
);
}
}

const std::string& ConfigManager::Get(std::string name) const {
auto q = m_config.find(name);
if (q == m_config.end())
return m_empty;

return *q->second.value;
}

void ConfigManager::Set(std::string&& name, std::string&& value) {
std::lock_guard<autowiring::spin_lock> lk(m_lock);
auto q = m_config.find(name);
if (q == m_config.end())
q = m_config.insert(q, { std::move(name), {} });

Entry& entry = q->second;
entry.value = std::move(value);

for (Entry::Attachment& attachment : entry.attached)
attachment.field->marshaller->unmarshal(
attachment.pObj,
entry.value->c_str()
);
}
57 changes: 57 additions & 0 deletions src/autowiring/ConfigManager.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// Copyright (C) 2012-2015 Leap Motion, Inc. All rights reserved.
#pragma once
#include "config_descriptor.h"
#include "optional.h"
#include "spin_lock.h"
#include <string>
#include <unordered_map>
#include <vector>

namespace autowiring {
class ConfigManager {
public:
ConfigManager(void);

private:
spin_lock m_lock;

// A single entry, which has a string representation part paired
// with a pointer to the value part
struct Entry {
// The value held here
optional<std::string> value;

struct Attachment {
const config_field* field;
void* pObj;
};

// Fields attached on this entry:
std::vector<Attachment> attached;
};

// Empty string sentry, used when a miss occurs
const std::string m_empty;

// All configuration values
std::unordered_map<std::string, Entry> m_config;

public:
/// <summary>
/// Registers a new configurable object
/// </summary>
/// <param name="pObj">The object that may be configured</param>
/// <param name="desc">A descriptor for the object</param>
void Register(void* pObj, const config_descriptor& desc);

/// <summary>
/// Gets the current configuration value from the map
/// </summary>
const std::string& Get(std::string name) const;

/// <summary>
/// Sets the named config value in the map
/// </summary>
void Set(std::string&& name, std::string&& value);
};
}
11 changes: 11 additions & 0 deletions src/autowiring/ConfigRegistry.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Copyright (C) 2012-2015 Leap Motion, Inc. All rights reserved.
#include "stdafx.h"
#include "ConfigRegistry.h"

using namespace autowiring;

std::atomic<config_registry_entry_base*> autowiring::g_pFirstEntry;

config_registry_entry_base::config_registry_entry_base(void) {
while (!g_pFirstEntry.compare_exchange_weak(pFlink, this));
}
64 changes: 64 additions & 0 deletions src/autowiring/ConfigRegistry.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// Copyright (C) 2012-2015 Leap Motion, Inc. All rights reserved.
#pragma once
#include "config_descriptor.h"
#include <atomic>

namespace autowiring {
struct config_registry_entry_base {
protected:
config_registry_entry_base(void);

public:
// Next entry in the registry:
config_registry_entry_base* pFlink = nullptr;
};

template<typename T, typename = void>
struct config_registry_entry {
static const config_descriptor* desc(void) { return nullptr; }
};

template<typename T>
struct config_registry_entry<T, typename std::enable_if<has_getconfigdescriptor<T>::value>::type> :
config_registry_entry_base
{
public:
static const config_descriptor* desc(void) {
static const config_descriptor desc = T::GetConfigDescriptor();
return &desc;
}
};

extern std::atomic<config_registry_entry_base*> g_pFirstEntry;

/// <summary>
/// Gets a string representation of the named configuration value
/// </summary>
template<typename T>
std::string ConfigGet(const char* name, T& obj) {
const config_descriptor& desc = *config_registry_entry<T>::desc();
auto q = desc.fields.find(name);
if (q == desc.fields.end())
throw std::invalid_argument("Configuration name not found in the specified object's configuration descriptor");

const autowiring::config_field& f = q->second;
return f.marshaller->marshal(reinterpret_cast<uint8_t*>(&obj) + f.offset);
}

/// <summary>
/// Sets the named configuration value to the specified string value
/// </summary>
template<typename T>
void ConfigSet(const char* name, T& obj, const char* value) {
const config_descriptor& desc = *config_registry_entry<T>::desc();
auto q = desc.fields.find(name);
if (q == desc.fields.end())
throw std::invalid_argument("Configuration name not found in the specified object's configuration descriptor");

const autowiring::config_field& f = q->second;
f.marshaller->unmarshal(
reinterpret_cast<uint8_t*>(&obj) + f.offset,
value
);
}
}
15 changes: 13 additions & 2 deletions src/autowiring/CoreContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "Bolt.h"
#include "CallExtractor.h"
#include "CoreRunnable.h"
#include "ConfigManager.h"
#include "ContextMember.h"
#include "CoreContextStateBlock.h"
#include "CoreObjectDescriptor.h"
Expand Down Expand Up @@ -133,6 +134,9 @@ class CoreContext:
// Asserted any time a new object is added to the context
autowiring::signal<void(const CoreObjectDescriptor&)> newObject;

// The one and only configuration manager type
autowiring::ConfigManager Config;

virtual ~CoreContext(void);

/// <summary>
Expand Down Expand Up @@ -235,7 +239,7 @@ class CoreContext:
typedef std::shared_ptr<CoreContext> (*t_pfnCreate)(
std::shared_ptr<CoreContext> pParent,
t_childList::iterator backReference
);
);

/// \internal
/// <summary>
Expand Down Expand Up @@ -606,13 +610,20 @@ class CoreContext:
std::shared_ptr<typename CreationRules::TActual> retVal(
CreationRules::New(*this, std::forward<Args>(args)...)
);
CoreObjectDescriptor objDesc(retVal, (T*)nullptr);

// Configure if the object is configurable, use a static check rather than checking the
// value of pConfigDesc because it's a little faster and one necessarily follows the other
// We also want this to happen before the AutoInit call is made
if(autowiring::has_getconfigdescriptor<T>::value)
Config.Register(static_cast<T*>(retVal.get()), *objDesc.pConfigDesc);

// AutoInit if sensible to do so:
CallAutoInit(*retVal, has_autoinit<T>());

try {
// Pass control to the insertion routine, which will handle injection from this point:
AddInternal(CoreObjectDescriptor(retVal, (T*)nullptr));
AddInternal(objDesc);
}
catch(autowiring_error&) {
// We know why this exception occurred. It's because, while we were constructing our
Expand Down
5 changes: 5 additions & 0 deletions src/autowiring/CoreObjectDescriptor.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "auto_id.h"
#include "AutoFilterDescriptor.h"
#include "BoltBase.h"
#include "ConfigRegistry.h"
#include "ContextMember.h"
#include "CoreObject.h"
#include "CoreRunnable.h"
Expand Down Expand Up @@ -49,6 +50,7 @@ struct CoreObjectDescriptor {
pBasicThread(autowiring::fast_pointer_cast<BasicThread>(value)),
pFilter(autowiring::fast_pointer_cast<ExceptionFilter>(value)),
pBoltBase(autowiring::fast_pointer_cast<BoltBase>(value)),
pConfigDesc(autowiring::config_registry_entry<T>::desc()),
primitiveOffset(
reinterpret_cast<size_t>(
static_cast<T*>(
Expand Down Expand Up @@ -123,6 +125,9 @@ struct CoreObjectDescriptor {
std::shared_ptr<ExceptionFilter> pFilter;
std::shared_ptr<BoltBase> pBoltBase;

// Configuration descriptor, if the object provides one
const autowiring::config_descriptor* pConfigDesc;

// Distance from TActual to T
size_t primitiveOffset;
};
3 changes: 0 additions & 3 deletions src/autowiring/Decompose.h
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
// Copyright (C) 2012-2015 Leap Motion, Inc. All rights reserved.
#pragma once
#include "is_any.h"
#include <tuple>
#include <typeinfo>

template<class... Ts>
struct TemplatePack {
static const int N = sizeof...(Ts);

typedef std::tuple<Ts...> t_args;

/// <returns>
/// An array of type T, parameterized by the bound function's arguments
/// </returns>
Expand Down
9 changes: 4 additions & 5 deletions src/autowiring/DecorationDisposition.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,24 @@
#include <cassert>
#include <set>
#include <vector>
#include TYPE_INDEX_HEADER

struct SatCounter;

struct DecorationKey {
DecorationKey(void) = default;

explicit DecorationKey(auto_id id, int tshift) :
id(id),
tshift(tshift)
{}

// The type index
auto_id id;

// Zero refers to a decoration created on this packet, a positive number [tshift] indicates
// a decoration attached [tshift] packets ago.
int tshift = -1;

bool operator==(const DecorationKey& rhs) const {
return id == rhs.id && tshift == rhs.tshift;
}
Expand Down Expand Up @@ -126,7 +125,7 @@ struct DecorationDisposition

// The current state of this disposition
DispositionState m_state = DispositionState::Unsatisfied;

/// <returns>
/// True if all publishers have run on this disposition
/// </summary>
Expand Down
1 change: 0 additions & 1 deletion src/autowiring/DispatchQueue.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
#include "DispatchThunk.h"
#include "once.h"
#include <atomic>
#include <list>
#include <queue>
#include MUTEX_HEADER
#include RVALUE_HEADER
Expand Down
1 change: 0 additions & 1 deletion src/autowiring/Parallel.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
#include "DispatchQueue.h"
#include <iterator>
#include <unordered_map>
#include <typeindex>
#include <deque>

class CoreContext;
Expand Down
Loading

0 comments on commit 179ad10

Please sign in to comment.