cwFlow.h/cpp : Added user_callback_t args to create() and set_variable_user_id().

Also added _make_flow_to_ui_callback() to exec_cycle() to implement flow callbacks to the UI.
This commit is contained in:
kevin 2024-10-14 14:20:13 -04:00
parent 805451d4d3
commit bad1d3953d
2 changed files with 62 additions and 6 deletions

View File

@ -754,6 +754,37 @@ namespace cw
return rc;
}
void _make_flow_to_ui_callback( flow_t* p )
{
// There is no concurrent contention for the linked list when
// this function is called and so all accesses use relaxed memory order.
// Get the first variable to send to the UI
variable_t* var = p->ui_var_tail->ui_var_link.load(std::memory_order_relaxed);
while( var!=nullptr)
{
// Send the var to the UI
if( p->ui_callback != nullptr )
p->ui_callback( p->ui_callback_arg, var->ui_var );
// Get the next var to send to the UI
variable_t* var0 = var->ui_var_link.load(std::memory_order_relaxed);
// Nullify the list links as they are used
var->ui_var_link.store(nullptr,std::memory_order_relaxed);
var = var0;
}
// Empty the UI message list.
p->ui_var_head.store(&p->ui_var_stub,std::memory_order_relaxed);
p->ui_var_tail = &p->ui_var_stub;
p->ui_var_stub.ui_var_link.store(nullptr,std::memory_order_relaxed);
}
}
}
@ -776,7 +807,9 @@ cw::rc_t cw::flow::create( handle_t& hRef,
const object_t* classCfg,
const object_t* pgmCfg,
const object_t* udpCfg,
const char* proj_dir )
const char* proj_dir,
ui_callback_t ui_callback,
void* ui_callback_arg)
{
rc_t rc = kOkRC;
bool printClassDictFl = false;
@ -810,6 +843,10 @@ cw::rc_t cw::flow::create( handle_t& hRef,
p->maxCycleCount = kInvalidCnt;
p->proj_dir = proj_dir;
p->printLogHdrFl = true;
p->ui_callback = ui_callback;
p->ui_callback_arg= ui_callback_arg;
p->ui_var_head.store(&p->ui_var_stub);
p->ui_var_tail = &p->ui_var_stub;
// parse the optional args
if((rc = pgmCfg->readv("network", 0, p->networkCfg,
@ -889,7 +926,8 @@ const char* cw::flow::preset_label( handle_t h, unsigned preset_idx )
if( preset_idx >= p->presetN )
{
cwLogError(kInvalidArgRC,"The preset index %i is invalid.",preset_idx);
return nullptr;
}
return p->presetA[ preset_idx ].label;
@ -1032,10 +1070,20 @@ cw::rc_t cw::flow::exec_cycle( handle_t h )
}
else
{
rc = exec_cycle(*p->net);
// Execute one cycle of the network
if((rc = exec_cycle(*p->net)) == kOkRC )
{
// During network execution variables which need to update the UI
// are collected in a linked list based on p->ui_var_tail.
// Callback to the UI with those variables here.
_make_flow_to_ui_callback(p);
}
p->cycleIndex += 1;
}
return rc;
}
@ -1069,6 +1117,8 @@ cw::rc_t cw::flow::apply_preset( handle_t h, const multi_preset_selector_t& mps
return network_apply_preset(*p->net,mps);
}
cw::rc_t cw::flow::set_variable_user_id( handle_t h, const ui_var_t* ui_var, unsigned user_id )
{ return set_variable_user_id( *_handleToPtr(h)->net, ui_var, user_id ); }
cw::rc_t cw::flow::set_variable_value( handle_t h, const char* inst_label, const char* var_label, unsigned chIdx, bool value )

View File

@ -18,8 +18,10 @@ namespace cw
rc_t create(handle_t& hRef,
const object_t* classCfg, // processor class dictionary
const object_t* pgmCfg, // top level program cfg
const object_t* udpCfg = nullptr,
const char* projDir = nullptr);
const object_t* udpCfg = nullptr,
const char* projDir = nullptr,
ui_callback_t ui_callback = nullptr,
void* ui_callback_arg = nullptr);
// Network cfg. information which is available following create().
bool is_non_real_time( handle_t h );
@ -32,6 +34,7 @@ namespace cw
const char* preset_label( handle_t h, unsigned preset_idx );
// Instantiate the network and prepare for runtime.
// The UI is not available until after initialization.
rc_t initialize( handle_t handle,
external_device_t* deviceA = nullptr,
unsigned deviceN = 0,
@ -66,6 +69,9 @@ namespace cw
rc_t get_variable_value( handle_t h, const char* inst_label, const char* var_label, unsigned chIdx, double& valueRef );
// The 'user_id' shows up as the 'user_id' in the ui_var field.
rc_t set_variable_user_id( handle_t h, const ui_var_t* ui_var, unsigned user_id );
rc_t set_variable_value( handle_t h, const ui_var_t* ui_var, bool value );
rc_t set_variable_value( handle_t h, const ui_var_t* ui_var, int value );
rc_t set_variable_value( handle_t h, const ui_var_t* ui_var, unsigned value );