Skip to content

Commit

Permalink
Make SignalBus faster (albeit unsafe) by removing size checks
Browse files Browse the repository at this point in the history
  • Loading branch information
MarcusTomlinson committed Mar 18, 2024
1 parent b6cf597 commit 05d4df5
Showing 1 changed file with 14 additions and 56 deletions.
70 changes: 14 additions & 56 deletions include/dspatch/SignalBus.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,34 +109,18 @@ inline fast_any::any* SignalBus::GetSignal( int signalIndex )
{
// You might be thinking: Why the raw pointer return here?

// This is for usability, design, and performance reasons. Usability, because a pointer allows
// the user to manipulate the contained value externally. Design, because DSPatch doesn't use
// exceptions - a nullptr return here is the equivalent of "signal does not exist".
// Performance, because returning a smart pointer means having to store the value as a smart
// pointer too - this adds yet another level of indirection to the value, as well as some
// reference counting overhead. These Get() and Set() methods are VERY frequently called, so
// doing as little as possible with the data here is best.

if ( (size_t)signalIndex < _signals.size() )
{
return &_signals[signalIndex];
}
else
{
return nullptr;
}
// This is for usability and performance reasons. Usability, because a pointer allows the user
// to manipulate the contained value externally. Performance, because returning a smart pointer
// means having to store the value as a smart pointer too - this adds yet another level of
// indirection to the value, as well as some reference counting overhead. These Get() and Set()
// methods are VERY frequently called, so doing as little as possible with the data here is best.

return &_signals[signalIndex];
}

inline bool SignalBus::HasValue( int signalIndex ) const
{
if ( (size_t)signalIndex < _signals.size() )
{
return _signals[signalIndex].has_value();
}
else
{
return false;
}
return _signals[signalIndex].has_value();
}

template <typename ValueType>
Expand All @@ -146,40 +130,24 @@ inline ValueType* SignalBus::GetValue( int signalIndex ) const

// See: GetSignal().

if ( (size_t)signalIndex < _signals.size() )
{
return _signals[signalIndex].as<ValueType>();
}
else
{
return nullptr;
}
return _signals[signalIndex].as<ValueType>();
}

template <typename ValueType>
inline void SignalBus::SetValue( int signalIndex, const ValueType& newValue )
{
if ( (size_t)signalIndex < _signals.size() )
{
_signals[signalIndex].emplace<ValueType>( newValue );
}
_signals[signalIndex].emplace<ValueType>( newValue );
}

template <typename ValueType>
inline void SignalBus::MoveValue( int signalIndex, ValueType&& newValue )
{
if ( (size_t)signalIndex < _signals.size() )
{
_signals[signalIndex].emplace<ValueType>( std::forward<ValueType>( newValue ) );
}
_signals[signalIndex].emplace<ValueType>( std::forward<ValueType>( newValue ) );
}

inline void SignalBus::SetSignal( int toSignalIndex, const fast_any::any& fromSignal )
{
if ( (size_t)toSignalIndex < _signals.size() )
{
_signals[toSignalIndex] = fromSignal;
}
_signals[toSignalIndex] = fromSignal;
}

inline void SignalBus::MoveSignal( int toSignalIndex, fast_any::any& fromSignal )
Expand All @@ -194,10 +162,7 @@ inline void SignalBus::MoveSignal( int toSignalIndex, fast_any::any& fromSignal
// signals such that, between these two points, just two value holders need to be constructed,
// and shared back and forth from then on.

if ( (size_t)toSignalIndex < _signals.size() )
{
_signals[toSignalIndex].swap( fromSignal );
}
_signals[toSignalIndex].swap( fromSignal );
}

inline void SignalBus::ClearAllValues()
Expand All @@ -210,14 +175,7 @@ inline void SignalBus::ClearAllValues()

inline fast_any::type_info SignalBus::GetType( int signalIndex ) const
{
if ( (size_t)signalIndex < _signals.size() )
{
return _signals[signalIndex].type();
}
else
{
return fast_any::type_id<void>;
}
return _signals[signalIndex].type();
}

} // namespace DSPatch

0 comments on commit 05d4df5

Please sign in to comment.