Skip to content

Commit

Permalink
Merge pull request #557 from leapmotion/ref-isshared
Browse files Browse the repository at this point in the history
Eliminate is_shared from DecorationKey
  • Loading branch information
gtremper committed Jun 11, 2015
2 parents d16ee2d + b93518f commit 693bfd8
Show file tree
Hide file tree
Showing 7 changed files with 141 additions and 142 deletions.
37 changes: 15 additions & 22 deletions autowiring/AutoPacket.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ class AutoPacket:
/// A satisfaction pulse will call any AutoFilter instances which are satisfied by the
/// decoration of the passed decoration types.
/// </remarks>
void PulseSatisfaction(DecorationDisposition* pTypeSubs[], size_t nInfos);
void PulseSatisfactionUnsafe(std::unique_lock<std::mutex> lk, DecorationDisposition* pTypeSubs [], size_t nInfos);

/// <summary>Unsynchronized runtime counterpart to Has</summary>
bool HasUnsafe(const DecorationKey& key) const;
Expand Down Expand Up @@ -186,7 +186,7 @@ class AutoPacket:
template<class T>
bool Has(int tshift=0) const {
std::lock_guard<std::mutex> lk(m_lock);
return HasUnsafe(DecorationKey(auto_id<T>::key(), true, tshift));
return HasUnsafe(DecorationKey(auto_id<T>::key(), tshift));
}

/// <summary>
Expand All @@ -198,7 +198,7 @@ class AutoPacket:

const T* retVal;
if (!Get(retVal, tshift))
ThrowNotDecoratedException(DecorationKey(auto_id<T>::key(), false, tshift));
ThrowNotDecoratedException(DecorationKey(auto_id<T>::key(), tshift));
return *retVal;
}

Expand All @@ -211,7 +211,7 @@ class AutoPacket:
/// </remarks>
template<class T>
bool Get(const T*& out, int tshift=0) const {
DecorationKey key(auto_id<T>::key(), false, tshift);
DecorationKey key(auto_id<T>::key(), tshift);
const DecorationDisposition* pDisposition = GetDisposition(key);
if (pDisposition) {
switch (pDisposition->m_decorations.size()) {
Expand Down Expand Up @@ -251,7 +251,7 @@ class AutoPacket:
template<class T>
bool Get(const std::shared_ptr<const T>*& out, int tshift=0) const {
// Decoration must be present and the shared pointer itself must also be present
DecorationKey key(auto_id<T>::key(), true, tshift);
DecorationKey key(auto_id<T>::key(), tshift);
const DecorationDisposition* pDisposition = GetDisposition(key);
if (!pDisposition) {
out = nullptr;
Expand Down Expand Up @@ -314,7 +314,7 @@ class AutoPacket:
template<class T>
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(), true, tshift));
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()) {
Expand Down Expand Up @@ -351,8 +351,7 @@ class AutoPacket:
/// </remarks>
template<class T>
void Unsatisfiable(void) {
MarkUnsatisfiable(DecorationKey(auto_id<T>::key(), false, 0));
MarkUnsatisfiable(DecorationKey(auto_id<T>::key(), true, 0));
MarkUnsatisfiable(DecorationKey(auto_id<T>::key(), 0));
}

/// <summary>
Expand All @@ -369,7 +368,7 @@ class AutoPacket:
auto ptr = std::make_shared<T>(std::forward<T&&>(t));
Decorate(
AnySharedPointer(ptr),
DecorationKey(auto_id<T>::key(), true, 0)
DecorationKey(auto_id<T>::key(), 0)
);
return *ptr;
}
Expand All @@ -385,7 +384,7 @@ class AutoPacket:
/// </remarks>
template<class T>
void Decorate(std::shared_ptr<T> ptr) {
DecorationKey key(auto_id<T>::key(), true, 0);
DecorationKey key(auto_id<T>::key(), 0);

// 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");
Expand Down Expand Up @@ -435,11 +434,9 @@ class AutoPacket:
// Perform standard decoration with a short initialization:
std::unique_lock<std::mutex> lk(m_lock);
DecorationDisposition* pTypeSubs[1 + sizeof...(Ts)] = {
&DecorateImmediateUnsafe(DecorationKey(auto_id<T>::key(), false, 0), &immed),
&DecorateImmediateUnsafe(DecorationKey(auto_id<Ts>::key(), false, 0), &immeds)...
&DecorateImmediateUnsafe(DecorationKey(auto_id<T>::key(), 0), &immed),
&DecorateImmediateUnsafe(DecorationKey(auto_id<Ts>::key(), 0), &immeds)...
};
lk.unlock();


// Pulse satisfaction:
MakeAtExit([this, &pTypeSubs] {
Expand All @@ -451,12 +448,10 @@ class AutoPacket:
}

// Now trigger a rescan to hit any deferred, unsatisfiable entries:
for (const std::type_info* ti : {&auto_id<T>::key(), &auto_id<Ts>::key()...}) {
MarkUnsatisfiable(DecorationKey(*ti, true, 0));
MarkUnsatisfiable(DecorationKey(*ti, false, 0));
}
for (const std::type_info* ti : {&auto_id<T>::key(), &auto_id<Ts>::key()...})
MarkUnsatisfiable(DecorationKey(*ti, 0));
}),
PulseSatisfaction(pTypeSubs, 1 + sizeof...(Ts));
PulseSatisfactionUnsafe(std::move(lk), pTypeSubs, 1 + sizeof...(Ts));
}

/// <summary>
Expand Down Expand Up @@ -509,9 +504,7 @@ class AutoPacket:
/// <returns>True if the indicated type has been requested for use by some consumer</returns>
template<class T>
bool HasSubscribers(void) const {
return
HasSubscribers(DecorationKey(auto_id<T>::key(), false, 0)) ||
HasSubscribers(DecorationKey(auto_id<T>::key(), true, 0));
return HasSubscribers(DecorationKey(auto_id<T>::key(), 0));
}

struct SignalStub {
Expand Down
37 changes: 21 additions & 16 deletions autowiring/DecorationDisposition.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,39 +13,31 @@ struct DecorationKey {

DecorationKey(const DecorationKey& rhs) :
ti(rhs.ti),
is_shared(rhs.is_shared),
tshift(rhs.tshift)
{}

explicit DecorationKey(const std::type_info& ti, bool is_shared, int tshift) :
explicit DecorationKey(const std::type_info& ti, int tshift) :
ti(&ti),
is_shared(is_shared),
tshift(tshift)
{}

// The type index
const std::type_info* ti = nullptr;

// True if this decoration can be used with AutoFilters that accept a shared_ptr input type
bool is_shared = false;

// 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 ti == rhs.ti && is_shared == rhs.is_shared && tshift == rhs.tshift;
return ti == rhs.ti && tshift == rhs.tshift;
}
};

namespace std {
template<>
struct hash<DecorationKey> {
size_t operator()(const DecorationKey& key) const {
return
key.tshift +
(key.is_shared ? 0x80000 : 0x70000) +
key.ti->hash_code();
return key.tshift + key.ti->hash_code();
}
};
}
Expand All @@ -61,10 +53,6 @@ enum class DispositionState {
// Everything attached, ready to go
Satisfied,

// Unsatisfiable, and the callers on this decoration cannot accept a non-null
// entry--IE, they accept const references as inputs.
UnsatisfiableNoCall,

// This decoration will never be satisfied. Calls are generated with a null
// shared pointer passed as the value.
Unsatisfiable
Expand Down Expand Up @@ -100,7 +88,24 @@ struct DecorationDisposition
std::vector<SatCounter*> m_publishers;

// Satisfaction counters
std::vector<SatCounter*> m_subscribers;
struct Subscriber {
Subscriber(void) {}

Subscriber(bool is_optional, SatCounter* satCounter):
is_optional{is_optional},
satCounter{satCounter}
{}

// Optional flag. If this flag is set, it indicates that the referenced AutoFilter could still
// be called even if the decoration is not attached to the packet--IE, the AutoFilter accepts a
// shared pointer or an array
bool is_optional = false;

// The satisfaction counter itself
SatCounter* satCounter = nullptr;
};

std::vector<Subscriber> m_subscribers;

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

0 comments on commit 693bfd8

Please sign in to comment.