cross-platform / dspatch

The Refreshingly Simple Cross-Platform C++ Dataflow / Patching / Pipelining / Graph Processing / Stream Processing / Reactive Programming Framework
https://flowbasedprogramming.com/
BSD 2-Clause "Simplified" License
216 stars 44 forks source link

Question : Handling similar types #27

Closed nyue closed 3 years ago

nyue commented 3 years ago

Hi,

Just discovered dspatch.

Is there some design-pattern/coding-wisdom for handling of similar types e.g. all the numerical POD (Plain Old Datatypes) e.g. int8_t, uint64_t, float, double etc, without having to write one for each type and types combination.

I am writing a component call Add and would like to be able to flexibly handle similar arithmetic types.

There are two sub cases, when input 1 and input 2 are of the same type and when input 1 and input 2 are of different types.

My testing reveal that GetValue(N) returns nullptr if "type" is different from the underlying type which I can understand.

` class Add final : public Component { public: // 2. Configure component IO buses // =============================== Add() { // add 2 inputs SetInputCount_( 2 );

    // add 1 output
    SetOutputCount_( 1 );
}

protected: // 3. Implement virtual Process() method // ====================================== virtual void Process( SignalBus const& inputs, SignalBus& outputs ) override { std::cout << "Add::_Proces()" << std::endl; // create some local pointers to hold our input values auto float1 = inputs.GetValue( 0 ); `

Cheers

MarcusTomlinson commented 3 years ago

There’s no internal mechanism for handling this no. You have some options client-side for this though, such as having all components pass around a union struct instead of raw values, or probably better, a helper class or function that takes a Signal in and spits out whatever values you need.

nyue commented 3 years ago

Any example code which illustrate the above I can study from ?

MarcusTomlinson commented 3 years ago

Something along these lines:

std::shared_ptr<float> GetFloat( Signal::SPtr const& fromSignal )
{
    if ( !fromSignal->HasValue() )
    {
        return nullptr;
    }

    auto const& signalType = fromSignal->GetType();

    if ( signalType == typeid( int ) )
    {
      return std::make_shared<float>( *fromSignal->GetValue<int>() );
    }
    else if ( signalType == typeid( double ) )
    {
      return std::make_shared<float>( *fromSignal->GetValue<double>() );
    }
    else if ( signalType == typeid( std::string ) )
    {
      return std::make_shared<float>( stof( *fromSignal->GetValue<std::string>() ) );
    }
    // ...

    return nullptr;
}

From Process_():

auto value = GetFloat( inputs.GetSignal(x) );
nyue commented 3 years ago

Thanks for the suggestion.