cwIoFlowCtl.cpp,cwFlowDecl.h,cwFlowNet, cwFlowTypes: Added disable_fl,hide_fl, new_disable_fl and new_hide_fl to ui_var_t.

Added ui_create_fl to ui_net_t.
ui_var is now non-const in ui_callback().
Added hide/disable_fl handling in cwIoFlowCtl _ui_callback()
Added parsing of 'ui' cfg in cwFlowNet _proc_parse_ui_cfg().
Added ui_create_fl,ui_callback_,ui_callback_arg to flow_t.
Added class_preset_value_channel_count(), class_preset_has_var() and class_preset_value() to cwFlowTypes.
This commit is contained in:
kevin 2025-03-08 11:52:38 -05:00
parent 8926765c28
commit d57789ea74
5 changed files with 348 additions and 22 deletions

View File

@ -128,6 +128,13 @@ namespace cw
unsigned ch_cnt; // 0=kAnyChIdx only, kInvalidCnt=no channels, 1=mono, 2=stereo, ...
unsigned user_id; // uuId of the UI element that represents this var
bool disable_fl; // true if this ui var is disabled
bool hide_fl; // true if this ui var is hidden
bool new_disable_fl;
bool new_hide_fl;
} ui_var_t;
struct proc_str;
@ -157,6 +164,8 @@ namespace cw
{
struct network_str* net;
bool ui_create_fl; // Set via network flag 'ui_create_fl'.
ui_proc_t* procA; // procA[procN]
unsigned procN;
@ -168,7 +177,7 @@ namespace cw
} ui_net_t;
typedef rc_t (*ui_callback_t)( void* arg, const ui_var_t* ui_var );
typedef rc_t (*ui_callback_t)( void* arg, ui_var_t* ui_var );
}

View File

@ -97,6 +97,8 @@ namespace cw
io_stmt_t* oStmtA;
unsigned oStmtN;
const object_t* ui_cfg; // cfg. node to ui
} proc_inst_parse_state_t;
void _preset_value_destroy( preset_value_t* v )
@ -1462,6 +1464,37 @@ namespace cw
return rc1;
}
rc_t _proc_parse_ui_cfg(proc_t* proc, const proc_inst_parse_state_t& pstate)
{
rc_t rc = kOkRC;
bool ui_create_fl = false;
if( pstate.ui_cfg == nullptr )
goto errLabel;
if( pstate.ui_cfg->is_dict() == false )
{
rc = cwLogError(kSyntaxErrorRC,"The UI cfg. record is not a dictionary.");
goto errLabel;
}
if( pstate.ui_cfg->find("create_fl") == nullptr )
ui_create_fl = proc->ctx->ui_create_fl;
// parse the optional args
if((rc = pstate.ui_cfg->getv_opt("create_fl", ui_create_fl )) != kOkRC )
goto errLabel;
if( ui_create_fl )
proc->flags |= kUiCreateProcFl;
errLabel:
if( rc != kOkRC )
rc = cwLogError(kSyntaxErrorRC,"The proc instance cfg. '%s:%i' UI configuration parse failed.",pstate.proc_label,pstate.proc_label_sfx_id);
return rc;
}
rc_t _proc_verify_required_record_fields( const proc_t* proc )
{
rc_t rc = kOkRC;
@ -1610,6 +1643,7 @@ namespace cw
if((rc = proc_inst_cfg->pair_value()->getv_opt("args", arg_dict,
"in", pstate.in_dict_cfg,
"out", pstate.out_dict_cfg,
"ui", pstate.ui_cfg,
"preset", pstate.preset_labels,
"presets", pstate.presets_dict,
"log", pstate.log_labels )) != kOkRC )
@ -1859,6 +1893,7 @@ namespace cw
}
/*
rc_t _process_net_preset(proc_t* proc, const object_t* net_preset_cfgD)
{
rc_t rc = kOkRC;
@ -1893,7 +1928,7 @@ namespace cw
return rc;
}
*/
void _pstate_destroy( proc_inst_parse_state_t pstate )
{
@ -2070,6 +2105,11 @@ namespace cw
if((rc = _proc_call_value_func_on_all_variables( proc )) != kOkRC )
goto errLabel;
// parse the proc UI cfg record
if(pstate.ui_cfg != nullptr )
if((rc = _proc_parse_ui_cfg(proc,pstate)) != kOkRC )
goto errLabel;
// validate the proc's state.
if((rc = proc_validate(proc)) != kOkRC )
{
@ -3430,10 +3470,11 @@ namespace cw
ui_var->label = var->label;
ui_var->label_sfx_id = var->label_sfx_id;
ui_var->has_source_fl= is_connected_to_source( var );
ui_var->disable_fl = ui_var->has_source_fl;
ui_var->vid = var->vid;
ui_var->ch_cnt = var_channel_count( net.procA[i], var->label, var->label_sfx_id );
ui_var->ch_idx = var->chIdx;
ui_var->value_tid = var->type;
ui_var->value_tid = (var->varDesc->type & flow::kTypeMask) == kAllTFl ? kAllTFl : var->type;
ui_var->desc_flags = var->varDesc->flags;
ui_var->desc_cfg = var->varDesc->cfg;
ui_var->user_id = kInvalidId;
@ -3472,6 +3513,7 @@ namespace cw
goto errLabel;
ui_net_ref->poly_idx = net.poly_idx;
ui_net_ref->ui_create_fl = p->ui_create_fl;
if( net.poly_link != nullptr )
_form_net_ui_desc(p,*net.poly_link,ui_net_ref->poly_link);

View File

@ -33,6 +33,9 @@ namespace cw
{ kInitVarDescFl, "init" },
{ kMultVarDescFl, "mult" },
{ kUdpOutVarDescFl, "out" },
{ kUiCreateVarDescFl, "no_ui" }, // even if the proc ui is enabled, don't show this var
{ kUiDisableVarDescFl,"ui_disable" },
{ kUiHideVarDescFl, "ui_hide" },
{ kInvalidVarDescFl, "<invalid>" }
};
@ -644,6 +647,10 @@ cw::flow::class_desc_t* cw::flow::class_desc_find( flow_t* p, const char* label
return nullptr;
}
const cw::flow::class_desc_t* cw::flow::class_desc_find( const flow_t* p, const char* class_desc_label )
{ return class_desc_find( const_cast<flow_t*>(p), class_desc_label ); }
const cw::flow::var_desc_t* cw::flow::var_desc_find( const class_desc_t* cd, const char* label )
{
const var_desc_t* vd = cd->varDescL;
@ -681,6 +688,131 @@ const cw::flow::class_preset_t* cw::flow::class_preset_find( const class_desc_t*
return nullptr;
}
cw::rc_t cw::flow::class_preset_value_channel_count( const class_preset_t* class_preset, const char* var_label, unsigned& ch_cnt_ref )
{
rc_t rc = kOkRC;
const object_t* var_cfg;
ch_cnt_ref = 0;
if( class_preset->cfg == nullptr )
{
rc = cwLogError(rc,"The preset '%s' is not valid.", cwStringNullGuard(class_preset->label));
goto errLabel;
}
if((var_cfg = class_preset->cfg->find(var_label)) == nullptr )
{
rc = cwLogError(rc,"Preset variable '%s' not found on preset '%s'.",cwStringNullGuard(var_label),cwStringNullGuard(class_preset->label));
goto errLabel;
}
if( var_cfg->is_list() )
ch_cnt_ref = var_cfg->child_count();
else
ch_cnt_ref = 1;
errLabel:
return rc;
}
cw::rc_t cw::flow::class_preset_value_channel_count( const class_desc_t* class_desc, const char* class_preset_label, const char* var_label, unsigned& ch_cnt_ref )
{
rc_t rc = kOkRC;
const class_preset_t* class_preset = nullptr;
ch_cnt_ref = 0;
if((class_preset = class_preset_find(class_desc, class_preset_label)) == nullptr )
{
rc = cwLogError(kEleNotFoundRC,"The preset '%s' could not be found on the class description: '%s'.",cwStringNullGuard(class_preset_label),cwStringNullGuard(class_desc->label));
goto errLabel;
}
rc = class_preset_value_channel_count( class_preset, var_label, ch_cnt_ref );
errLabel:
return rc;
}
cw::rc_t cw::flow::class_preset_value_channel_count( const flow_t* p, const char* class_desc_label, const char* class_preset_label, const char* var_label, unsigned& ch_cnt_ref )
{
rc_t rc = kOkRC;
const class_desc_t* class_desc;
ch_cnt_ref = 0;
if((class_desc = class_desc_find(p,class_desc_label)) == nullptr )
{
rc = cwLogError(kEleNotFoundRC,"The class description '%s' could not be found.",cwStringNullGuard(class_desc_label));
goto errLabel;
}
rc = class_preset_value_channel_count(class_desc, class_preset_label, var_label, ch_cnt_ref );
errLabel:
return rc;
}
cw::rc_t cw::flow::class_preset_has_var( const class_preset_t* class_preset, const char* var_label, bool& fl_ref )
{
rc_t rc = kOkRC;
const object_t* var_cfg;
fl_ref = false;
if( class_preset->cfg == nullptr )
{
rc = cwLogError(rc,"The preset '%s' is not valid.", cwStringNullGuard(class_preset->label));
goto errLabel;
}
fl_ref = class_preset->cfg->find(var_label) != nullptr;
errLabel:
return rc;
}
cw::rc_t cw::flow::class_preset_has_var( const class_desc_t* class_desc, const char* class_preset_label, const char* var_label, bool& fl_ref )
{
rc_t rc = kOkRC;
const class_preset_t* class_preset = nullptr;
fl_ref = false;
if((class_preset = class_preset_find(class_desc, class_preset_label)) == nullptr )
{
rc = cwLogError(kEleNotFoundRC,"The preset '%s' could not be found on the class description: '%s'.",cwStringNullGuard(class_preset_label),cwStringNullGuard(class_desc->label));
goto errLabel;
}
rc = class_preset_has_var( class_preset, var_label, fl_ref );
errLabel:
return rc;
}
cw::rc_t cw::flow::class_preset_has_var( const flow_t* p, const char* class_desc_label, const char* class_preset_label, const char* var_label, bool& fl_ref )
{
rc_t rc = kOkRC;
const class_desc_t* class_desc;
fl_ref = false;
if((class_desc = class_desc_find(p,class_desc_label)) == nullptr )
{
rc = cwLogError(kEleNotFoundRC,"The class description '%s' could not be found.",cwStringNullGuard(class_desc_label));
goto errLabel;
}
rc = class_preset_has_var(class_desc, class_preset_label, var_label, fl_ref );
errLabel:
return rc;
}
void cw::flow::class_dict_print( flow_t* p )
{
for(unsigned i=0; i<p->classDescN; ++i)
@ -1569,6 +1701,33 @@ cw::rc_t cw::flow::var_send_to_ui( proc_t* proc, unsigned vid, unsigned chIdx
return rc;
}
cw::rc_t cw::flow::var_send_to_ui_enable( proc_t* proc, unsigned vid, unsigned chIdx, bool enable_fl )
{
rc_t rc = kOkRC;
variable_t* var = nullptr;
if((rc = var_find(proc, vid, chIdx, var )) == kOkRC )
{
var->ui_var->new_disable_fl = !enable_fl;
rc = var_send_to_ui(var);
}
return rc;
}
cw::rc_t cw::flow::var_send_to_ui_show( proc_t* proc, unsigned vid, unsigned chIdx, bool show_fl )
{
rc_t rc = kOkRC;
variable_t* var = nullptr;
if((rc = var_find(proc, vid, chIdx, var )) == kOkRC )
{
var->ui_var->new_hide_fl = !show_fl;
rc = var_send_to_ui(var);
}
return rc;
}
cw::rc_t cw::flow::var_register_and_set( proc_t* proc, const char* var_label, unsigned sfx_id, unsigned vid, unsigned chIdx, variable_t*& varRef )
{
return var_register( proc, var_label, sfx_id, vid, chIdx, nullptr, varRef );

View File

@ -14,13 +14,16 @@ namespace cw
// var_desc_t attribute flags
enum
{
kInvalidVarDescFl = 0x00,
kSrcVarDescFl = 0x01,
kSrcOptVarDescFl = 0x02,
kNoSrcVarDescFl = 0x04,
kInitVarDescFl = 0x08,
kMultVarDescFl = 0x10,
kUdpOutVarDescFl = 0x20
kInvalidVarDescFl = 0x000,
kSrcVarDescFl = 0x001,
kSrcOptVarDescFl = 0x002,
kNoSrcVarDescFl = 0x004,
kInitVarDescFl = 0x008,
kMultVarDescFl = 0x010,
kUdpOutVarDescFl = 0x020,
kUiCreateVarDescFl = 0x040,
kUiDisableVarDescFl = 0x080,
kUiHideVarDescFl = 0x100
};
typedef struct class_members_str
@ -75,7 +78,7 @@ namespace cw
kInvalidVarFl = 0x00,
kLogVarFl = 0x01,
kProxiedVarFl = 0x02,
kProxiedOutVarFl = 0x04
kProxiedOutVarFl = 0x04,
};
// Note: The concatenation of 'vid' and 'chIdx' should form a unique identifier among all variables
@ -115,11 +118,17 @@ namespace cw
struct network_str;
enum {
kUiCreateProcFl = 0x01
};
typedef struct proc_str
{
struct flow_str* ctx; // global system context
struct network_str* net; // network which owns this proc
unsigned flags; // See k???ProcFl
class_desc_t* class_desc; //
char* label; // instance label
@ -292,6 +301,7 @@ namespace cw
network_t* net; // The root of the network instance
bool ui_create_fl; // dflt: false Set by network flag: ui_create_fl, override with proc inst ui:{ create_fl }
ui_callback_t ui_callback;
void* ui_callback_arg;
@ -321,6 +331,7 @@ namespace cw
void class_desc_destroy( class_desc_t* class_desc);
class_desc_t* class_desc_find( flow_t* p, const char* class_desc_label );
const class_desc_t* class_desc_find( const flow_t* p, const char* class_desc_label );
var_desc_t* var_desc_find( class_desc_t* cd, const char* var_label );
const var_desc_t* var_desc_find( const class_desc_t* cd, const char* var_label );
@ -330,6 +341,87 @@ namespace cw
const class_preset_t* class_preset_find( const class_desc_t* cd, const char* preset_label );
template<class T>
rc_t class_preset_value( const class_preset_t* class_preset, const char* var_label, unsigned ch_idx, T& val )
{
rc_t rc = kOkRC;
const object_t* preset_val = nullptr;
if((rc = class_preset->cfg->get(var_label, preset_val )) != kOkRC )
{
rc = cwLogError(rc,"The preset variable '%s' on the preset '%s' could not be parsed.",cwStringNullGuard(var_label),cwStringNullGuard(class_preset->label));
goto errLabel;
}
if( preset_val->is_list() )
{
if( ch_idx >= preset_val->child_count() || (preset_val = preset_val->child_ele( ch_idx )) == nullptr )
{
rc = cwLogError(rc,"The channel index '%i' is invalid for the preset '%s:%s'.",ch_idx,cwStringNullGuard(class_preset->label),cwStringNullGuard(var_label));
goto errLabel;
}
}
//
if((rc = preset_val->value( val )) != kOkRC )
{
rc = cwLogError(rc,"The preset value '%s:%s ch:%i' could not be parsed.",cwStringNullGuard(class_preset->label),cwStringNullGuard(var_label),ch_idx);
goto errLabel;
}
errLabel:
return rc;
}
template<class T>
rc_t class_preset_value( const class_desc_t* class_desc, const char* class_preset_label, const char* var_label, unsigned ch_idx, T& val )
{
rc_t rc = kOkRC;
const class_preset_t* class_preset = nullptr;
if((class_preset = class_preset_find(class_desc, class_preset_label)) == nullptr )
{
rc = cwLogError(kEleNotFoundRC,"The preset '%s' could not be found on the class description: '%s'.",cwStringNullGuard(class_preset_label),cwStringNullGuard(class_desc->label));
goto errLabel;
}
rc = class_preset_value(class_preset, var_label, ch_idx, val );
errLabel:
return rc;
}
template<class T>
rc_t class_preset_value( const flow_t* p, const char* class_desc_label, const char* class_preset_label, const char* var_label, unsigned ch_idx, T& val )
{
rc_t rc = kOkRC;
const class_desc_t* class_desc;
if((class_desc = class_desc_find(p,class_desc_label)) == nullptr )
{
rc = cwLogError(kEleNotFoundRC,"The class description '%s' could not be found.",cwStringNullGuard(class_desc_label));
goto errLabel;
}
rc = class_preset_value( class_desc, class_preset_label, var_label, ch_idx, val );
errLabel:
return rc;
}
rc_t class_preset_value_channel_count( const class_preset_t* class_preset, const char* var_label, unsigned& ch_cnt_ref );
rc_t class_preset_value_channel_count( const class_desc_t* class_desc, const char* class_preset_label, const char* var_label, unsigned& ch_cnt_ref );
rc_t class_preset_value_channel_count( const flow_t* p, const char* class_desc_label, const char* class_preset_label, const char* var_label, unsigned& ch_cnt_ref );
rc_t class_preset_has_var( const class_preset_t* class_preset, const char* var_label, bool& fl_ref );
rc_t class_preset_has_var( const class_desc_t* class_desc, const char* class_preset_label, const char* var_label, bool& fl_ref );
rc_t class_preset_has_var( const flow_t* p, const char* class_desc_label, const char* class_preset_label, const char* var_label, bool& fl_ref );
//------------------------------------------------------------------------------------------------------------------------
//
// Flow
@ -443,6 +535,8 @@ namespace cw
// Send a variable value to the UI
rc_t var_send_to_ui( variable_t* var );
rc_t var_send_to_ui( proc_t* proc, unsigned vid, unsigned chIdx );
rc_t var_send_to_ui_enable( proc_t* proc, unsigned vid, unsigned chIdx, bool enable_fl );
rc_t var_send_to_ui_show( proc_t* proc, unsigned vid, unsigned chIdx, bool show_fl );
//-----------------
//

View File

@ -527,7 +527,7 @@ namespace cw
}
template< typename T >
rc_t _ui_callback_tpl( io_flow_ctl_t* p, const flow::ui_var_t* ui_var )
rc_t _ui_callback_tpl( io_flow_ctl_t* p, flow::ui_var_t* ui_var )
{
rc_t rc;
@ -549,7 +549,7 @@ namespace cw
}
// This function is called with messages for the UI from the flow proc instances
rc_t _ui_callback( void* arg, const flow::ui_var_t* ui_var )
rc_t _ui_callback( void* arg, flow::ui_var_t* ui_var )
{
rc_t rc = kOkRC;
@ -561,6 +561,28 @@ namespace cw
goto errLabel;
}
if( ui_var->new_disable_fl != ui_var->disable_fl )
{
if((rc = uiSetEnable( p->ioH, ui_var->user_id, !ui_var->new_disable_fl )) != kOkRC )
{
rc = cwLogError(rc,"UI enable/disable update failed.");
goto errLabel;
}
ui_var->disable_fl = ui_var->new_disable_fl;
}
if( ui_var->new_hide_fl != ui_var->hide_fl )
{
if((rc = uiSetVisible( p->ioH, ui_var->user_id, !ui_var->new_hide_fl )) != kOkRC )
{
rc = cwLogError(rc,"UI hide/show update failed.");
goto errLabel;
}
ui_var->hide_fl = ui_var->new_hide_fl;
}
switch( ui_var->value_tid & flow::kTypeMask )
{
case flow::kBoolTFl: