Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
codemercenary committed Feb 4, 2015
2 parents b0035e0 + a386354 commit 15c7099
Show file tree
Hide file tree
Showing 57 changed files with 423 additions and 337 deletions.
7 changes: 2 additions & 5 deletions README.md
Expand Up @@ -72,16 +72,13 @@ via the [find_package](http://www.cmake.org/cmake/help/v3.0/command/find_package

### Arm-linux

Building on Android requires the use of a toolchain file. You will need to use an alternate prefix path if you are trying to cross-compile, the prefix path
should contain your version of the Boost libraries built for Android. To configure, use the following invocation:
Building on Android requires the use of a toolchain file. You will need to use an alternate prefix path if you are trying to cross-compile, the prefix path should contain your version of the Boost libraries built for Android. To configure, use the following invocation:

cmake . -DCMAKE_TOOLCHAIN_FILE=toolchain-arm.cmake -DCMAKE_PREFIX_PATH:PATH=/your/lib/path

### Android

Similar requirements to Arm-linux, you must specify a toolchain file. You must also specify the path to your Android toolchain directory. Make sure you update
/opt/android-standalone-toolchain to point to your actual Android standalone toolchain directory. If you aren't cross-compiling, then simply run cmake with
no options.
Similar requirements to Arm-linux, you must specify a toolchain file. You must also specify the path to your Android toolchain directory. Make sure you update `/opt/android-standalone-toolchain` to point to your actual Android standalone toolchain directory. To build for 64 bit android systems, export the environment variable `export ARMv8=true`. If you aren't cross-compiling, then simply run cmake with no options.

cmake . -DCMAKE_TOOLCHAIN_FILE=toolchain-android.cmake -DLLVM_ANDROID_TOOLCHAIN_DIR=/opt/android-standalone-toolchain

Expand Down
44 changes: 21 additions & 23 deletions autowiring/AutoFilterDescriptor.h
Expand Up @@ -178,7 +178,7 @@ struct AutoFilterDescriptor:
std::static_pointer_cast<typename Decompose<decltype(&T::AutoFilter)>::type>(subscriber)
),
&typeid(T),
Decompose<decltype(&T::AutoFilter)>::template Enumerate<AutoFilterDescriptorInput>::types,
Decompose<decltype(&T::AutoFilter)>::template Enumerate<AutoFilterDescriptorInput, AutoFilterDescriptorInputT>::types,
CallExtractor<decltype(&T::AutoFilter)>::deferred,
&CallExtractor<decltype(&T::AutoFilter)>::template Call<&T::AutoFilter>
)
Expand All @@ -195,7 +195,7 @@ struct AutoFilterDescriptor:
AutoFilterDescriptor(
AnySharedPointer(std::make_shared<Fn>(std::forward<Fn>(fn))),
&typeid(Fn),
CallExtractor<decltype(&Fn::operator())>::template Enumerate<AutoFilterDescriptorInput>::types,
CallExtractor<decltype(&Fn::operator())>::template Enumerate<AutoFilterDescriptorInput, AutoFilterDescriptorInputT>::types,
false,
&CallExtractor<decltype(&Fn::operator())>::template Call<&Fn::operator()>
)
Expand Down Expand Up @@ -240,7 +240,7 @@ struct AutoFilterDescriptor:
// The remainder is fairly straightforward
&typeid(pfn),

CallExtractor<decltype(pfn)>::template Enumerate<AutoFilterDescriptorInput>::types,
CallExtractor<decltype(pfn)>::template Enumerate<AutoFilterDescriptorInput, AutoFilterDescriptorInputT>::types,
false,
CallExtractor<decltype(pfn)>::Call
)
Expand Down Expand Up @@ -293,26 +293,24 @@ struct AutoFilterDescriptor:
bool operator>=(const AutoFilterDescriptor& rhs) const { return !(*this < rhs);}
};

template<class T, bool has_autofilter = has_autofilter<T>::value>
class AutoFilterDescriptorSelect:
public std::true_type
{
public:
AutoFilterDescriptorSelect(const std::shared_ptr<T>& subscriber) :
desc(subscriber)
{}

const AutoFilterDescriptor desc;
};
/// <summary>
/// Utility routine to support the creation of an AutoFilterDescriptor from T::AutoFilter
/// </summary>
/// <remarks>
/// This method will return an empty descriptor in the case that T::AutoFilter is not defined
/// </remarks>
template<class T>
AutoFilterDescriptor MakeAutoFilterDescriptor(const std::shared_ptr<T>& ptr) {
return MakeAutoFilterDescriptor(ptr, std::integral_constant<bool, has_autofilter<T>::value>());
}

/// <summary>
/// Alias for AutoFilterDescriptor(ptr)
/// </summary>
template<class T>
class AutoFilterDescriptorSelect<T, false>:
public std::false_type
{
public:
AutoFilterDescriptorSelect(const std::shared_ptr<T>&) {}
const AutoFilterDescriptor desc;
};
AutoFilterDescriptor MakeAutoFilterDescriptor(const std::shared_ptr<T>& ptr, std::true_type) {
return AutoFilterDescriptor(ptr);
}

/// <summary>
/// Utility routine to support the creation of an AutoFilterDescriptor from T::AutoFilter
Expand All @@ -321,8 +319,8 @@ class AutoFilterDescriptorSelect<T, false>:
/// This method will return an empty descriptor in the case that T::AutoFilter is not defined
/// </remarks>
template<class T>
AutoFilterDescriptor MakeAutoFilterDescriptor(const std::shared_ptr<T>& ptr) {
return std::move(AutoFilterDescriptorSelect<T>(ptr).desc);
AutoFilterDescriptor MakeAutoFilterDescriptor(const std::shared_ptr<T>&, std::false_type) {
return AutoFilterDescriptor();
}

namespace std {
Expand Down
45 changes: 30 additions & 15 deletions autowiring/AutoFilterDescriptorInput.h
Expand Up @@ -16,14 +16,20 @@ struct AutoFilterDescriptorInput {
tshift(0)
{}

template<class T>
AutoFilterDescriptorInput(auto_arg<T>*) :
is_input(auto_arg<T>::is_input),
is_output(auto_arg<T>::is_output),
is_shared(auto_arg<T>::is_shared),
is_multi(auto_arg<T>::is_multi),
ti(&typeid(typename auto_arg<T>::id_type)),
tshift(auto_arg<T>::tshift)
AutoFilterDescriptorInput(
bool is_input,
bool is_output,
bool is_shared,
bool is_multi,
const std::type_info* ti,
int tshift
) :
is_input(is_input),
is_output(is_output),
is_shared(is_shared),
is_multi(is_multi),
ti(ti),
tshift(tshift)
{}

const bool is_input;
Expand All @@ -36,11 +42,20 @@ struct AutoFilterDescriptorInput {
operator bool(void) const {
return !!ti;
}

template<class T>
struct rebind {
operator AutoFilterDescriptorInput() {
return AutoFilterDescriptorInput((auto_arg<T>*)nullptr);
}
};
};

template<typename T>
struct AutoFilterDescriptorInputT:
AutoFilterDescriptorInput
{
AutoFilterDescriptorInputT(void) :
AutoFilterDescriptorInput(
auto_arg<T>::is_input,
auto_arg<T>::is_output,
auto_arg<T>::is_shared,
auto_arg<T>::is_multi,
&typeid(typename auto_arg<T>::id_type),
auto_arg<T>::tshift
)
{}
};
14 changes: 10 additions & 4 deletions autowiring/AutoNetServer.h
Expand Up @@ -45,7 +45,7 @@ class AutoNetServer:
/// Send a custom event to all clients.
template<typename... Args>
void SendEvent(const std::string& event, Args... args) {
SendEvent(event, std::vector<std::string>{parse(args)...});
SendEvent(event, std::vector<std::string>{parseToString(args)...});
}

protected:
Expand All @@ -68,22 +68,22 @@ class AutoNetServer:
if (sizeof...(Args) != args.size())
// TODO: Return some kind of singal to the caller indicating that there is a problem
return;
(handler.*pfn)(parse<Args>(args[N])...);
(handler.*pfn)(parseFromString<typename std::decay<Args>::type>(args[N])...);
}
);
}

// parse type to string
template<class T>
std::string parse(const T& t){
std::string parseToString(const T& t){
std::ostringstream ss;
ss << t;
return ss.str();
}

// parse string to primative type
template<class T>
typename std::decay<T>::type parse(const std::string& str){
inline T parseFromString(const std::string& str){
std::istringstream ss(str);
typename std::decay<T>::type val;
ss >> std::boolalpha >> val;
Expand All @@ -95,3 +95,9 @@ class AutoNetServer:
return val;
}
};

// template specialization for a string to just return itself unparsed
template<>
inline std::string AutoNetServer::parseFromString<std::string>(const std::string& str) {
return str;
}
38 changes: 27 additions & 11 deletions autowiring/AutoPacket.h
Expand Up @@ -287,17 +287,30 @@ class AutoPacket:
}

/// <summary>
/// Returns a vector with a pointer to each decoration of type T, adding a nullptr to the end.
/// Returns a null-terminated temporary buffer containing all decorations
/// </summary>
/// <returns>The null-terminated temporary buffer</returns>
/// <remarks>
/// The returned buffer must be freed with std::return_temporary_buffer
/// </remarks>
template<class T>
std::vector<const T*> GetAll(int tshift = 0) {
std::vector<const T*> retval;
auto deco = m_decorations.find(DecorationKey(auto_id<T>::key(), tshift));
for (auto& dispo : deco->second.m_decorations) {
retval.push_back(dispo.as<T>().get().get());
const T** GetAll(int tshift = 0) const {
std::lock_guard<std::mutex> lk(m_lock);
auto q = m_decorations.find(DecorationKey(auto_id<T>::key(), tshift));

// If decoration doesn't exist, return empty null-terminated buffer
if (q == m_decorations.end()) {
const T** retVal = std::get_temporary_buffer<const T*>(1).first;
retVal[0] = nullptr;
return retVal;
}
retval.push_back(nullptr);
return retval;

const auto& decorations = q->second.m_decorations;
const T** retVal = std::get_temporary_buffer<const T*>(decorations.size() + 1).first;
for (size_t i = 0; i < decorations.size(); i++)
retVal[i] = static_cast<const T*>(decorations[i]->ptr());
retVal[decorations.size()] = nullptr;
return retVal;
}

/// <summary>Shares all broadcast data from this packet with the recipient packet</summary>
Expand Down Expand Up @@ -369,7 +382,10 @@ class AutoPacket:
void Decorate(std::shared_ptr<T> ptr) {
DecorationKey key(auto_id<T>::key());

/// Injunction to prevent existential loops:
// We don't want to see this overload used on a const T
static_assert(!std::is_const<T>::value, "Cannot decorate a shared pointer to const T with this overload");

// Injunction to prevent existential loops:
static_assert(!std::is_same<T, AutoPacket>::value, "Cannot decorate a packet with another packet");

// Either decorate, or prevent anyone from decorating
Expand Down Expand Up @@ -546,7 +562,7 @@ class AutoPacket:

// Add the filter that will ultimately be invoked
*this += std::move(autoFilter);
return Wait(cv, Decompose<decltype(&Fx::operator())>::template Enumerate<AutoFilterDescriptorInput>::types, duration);
return Wait(cv, Decompose<decltype(&Fx::operator())>::template Enumerate<AutoFilterDescriptorInput, AutoFilterDescriptorInputT>::types, duration);
}

/// <summary>
Expand All @@ -570,7 +586,7 @@ class AutoPacket:
bool Wait(std::chrono::nanoseconds duration, std::condition_variable& cv)
{
static const AutoFilterDescriptorInput inputs [] = {
static_cast<auto_arg<Args>*>(nullptr)...,
AutoFilterDescriptorInputT<Args>()...,
AutoFilterDescriptorInput()
};

Expand Down
6 changes: 4 additions & 2 deletions autowiring/AutoPacketFactory.h
Expand Up @@ -98,7 +98,7 @@ class AutoPacketFactory:
/// </summary>
template<class T>
void AddSubscriber(const std::shared_ptr<T>& rhs) {
AddSubscriber(MakeAutoFilterDescriptor<T>(rhs));
AddSubscriber(AutoFilterDescriptor(rhs));
}

/// <summary>
Expand Down Expand Up @@ -182,5 +182,7 @@ class AutoPacketFactory:
// exterior instantation of internally used template instances
extern template struct SlotInformationStump<AutoPacketFactory, false>;
extern template const std::shared_ptr<AutoPacketFactory>& SharedPointerSlot::as<AutoPacketFactory>(void) const;
extern template std::shared_ptr<AutoPacketFactory> autowiring::fast_pointer_cast<AutoPacketFactory, Object>(const std::shared_ptr<Object>& Other);
extern template std::shared_ptr<AutoPacketFactory> autowiring::fast_pointer_cast<AutoPacketFactory, CoreObject>(const std::shared_ptr<CoreObject>& Other);
extern template class RegType<AutoPacketFactory>;
extern template struct autowiring::fast_pointer_cast_blind<CoreObject, AutoPacketFactory>;
extern template struct autowiring::fast_pointer_cast_initializer<CoreObject, AutoPacketFactory>;
2 changes: 1 addition & 1 deletion autowiring/AutoRestarter.h
Expand Up @@ -135,7 +135,7 @@ class AutoRestarter:
GenerateContext();
}

void Filter(const JunctionBoxBase* pJunctionBox, Object* pRecipient) override {
void Filter(const JunctionBoxBase* pJunctionBox, CoreObject* pRecipient) override {
Filter();
}

Expand Down
10 changes: 5 additions & 5 deletions autowiring/AutowirableSlot.h
Expand Up @@ -9,7 +9,7 @@
class CoreContext;
class DeferrableAutowiring;
class GlobalCoreContext;
class Object;
class CoreObject;

// Utility routine, for users who need a function that does nothing
template<class T>
Expand Down Expand Up @@ -146,7 +146,7 @@ class AutowirableSlot:
// of this type MUST be available. The reason for this is that, if the user wishes to know if a
// type is autowired, they are required at a minimum to know what that type's inheritance relations
// are to other types in the system.
(void) autowiring::fast_pointer_cast_initializer<T, Object>::sc_init;
(void) autowiring::fast_pointer_cast_initializer<T, CoreObject>::sc_init;
return !!get();
}

Expand All @@ -155,7 +155,7 @@ class AutowirableSlot:
/// </remarks>
T* get(void) const {
// For now, we require that the full type be available to use this method
(void) autowiring::fast_pointer_cast_initializer<T, Object>::sc_init;
(void) autowiring::fast_pointer_cast_initializer<T, CoreObject>::sc_init;
return get_unsafe();
}

Expand Down Expand Up @@ -184,14 +184,14 @@ class AutowirableSlot:
// Initialize any blind fast casts to the actually desired type. This is one of a few points
// where we can guarantee that the type will be completely defined, because the user is about
// to make use of this type.
(void) autowiring::fast_pointer_cast_initializer<T, Object>::sc_init;
(void) autowiring::fast_pointer_cast_initializer<T, CoreObject>::sc_init;
return get();
}

T& operator*(void) const {
// We have to initialize here, in the operator context, because we don't actually know if the
// user will be making use of this type.
(void) autowiring::fast_pointer_cast_initializer<T, Object>::sc_init;
(void) autowiring::fast_pointer_cast_initializer<T, CoreObject>::sc_init;

return *get();
}
Expand Down

0 comments on commit 15c7099

Please sign in to comment.