6#include "dawn/prog/switch.hxx"
11#include "dawn/debug.hxx"
12#include "dawn/io/common.hxx"
13#include "dawn/io/ddata.hxx"
14#include "dawn/io/sdata.hxx"
18static const size_t INPUT_WORDS = 2;
33CProgSwitch::~CProgSwitch()
48 inputs.push_back(inp);
53int CProgSwitch::configureDesc(
const CDescObject &desc)
63 for (ii = 0; ii < desc.
getSize(); ii++)
67 if (item->
cfgid.
s.
cls != CProgCommon::PROG_CLASS_SWITCH)
69 DAWNERR(
"switch: unsupported cfg class 0x%" PRIx32
"\n", item->
cfgid.
v);
75 case PROG_SWITCH_CFG_INPUTS:
78 if (n == 0 || n % INPUT_WORDS != 0)
80 DAWNERR(
"switch: invalid INPUTS size %zu\n", n);
84 vals =
reinterpret_cast<const uint32_t *
>(item->
data);
85 for (
size_t j = 0; j < n; j += INPUT_WORDS)
88 int ret = allocInput(ids[0].v, vals[j + 1]);
97 case PROG_SWITCH_CFG_TARGET:
102 DAWNERR(
"switch: invalid TARGET size %zu\n", n);
107 vals =
reinterpret_cast<const uint32_t *
>(item->
data);
109 onCmd =
static_cast<uint8_t
>(vals[1]);
110 offCmd =
static_cast<uint8_t
>(vals[2]);
117 DAWNERR(
"switch: unsupported cfg id %u\n", item->
cfgid.
s.
id);
125 DAWNERR(
"switch: at least one input required\n");
131 DAWNERR(
"switch: target IO not configured\n");
140 return configureDesc(
getDesc());
149 for (i = 0; i < inputs.size(); i++)
151 io =
getIO(inputs[i].ioId);
154 DAWNERR(
"switch: input IO 0x%" PRIx32
" not found\n", inputs[i].ioId);
160 DAWNERR(
"switch: input 0x%" PRIx32
" is not readable\n", inputs[i].ioId);
166 DAWNERR(
"switch: input 0x%" PRIx32
" must be scalar uint32, got dtype=%u dim=%zu\n",
176 target =
getIO(targetId);
179 DAWNERR(
"switch: target 0x%" PRIx32
" not found\n", targetId);
183 ret = prepareWritableTarget(target, 1,
true);
186 DAWNERR(
"switch: target prepare failed %d\n", ret);
191 if (!iodata || !iodata->isAllocated())
195 DAWNERR(
"switch: iodata allocation failed\n");
212int CProgSwitch::ioNotifierCb(
void *priv,
io_ddata_t *data)
214 SSwitchInput *inp =
static_cast<SSwitchInput *
>(priv);
218 std::memcpy(&inp->current, data->
getDataPtr(),
sizeof(inp->current));
221 if (inp->owner && inp->owner->active)
223 inp->owner->evaluate();
238 for (i = 0; i < inputs.size(); i++)
242 ret = inputs[i].io->getData(inputData, 1);
245 DAWNERR(
"switch: getData failed on input %zu: %d\n", i, ret);
248 inputs[i].current = inputData(0);
251 lastAndState = !allInputsMatch();
258 for (i = 0; i < inputs.size(); i++)
260 if (!inputs[i].io->isNotify())
265 ret = inputs[i].io->setNotifier(ioNotifierCb, 0, &inputs[i]);
268 DAWNERR(
"switch: setNotifier failed on input %zu: %d\n", i, ret);
276 for (i = 0; i < inputs.size(); i++)
280 ret = inputs[i].io->getData(inputData, 1);
283 DAWNERR(
"switch: getData failed on input %zu: %d\n", i, ret);
286 inputs[i].current = inputData(0);
288 lastAndState = !allInputsMatch();
298 for (
size_t i = 0; i < inputs.size(); i++)
300 if (inputs[i].io && inputs[i].io->isNotify())
302 inputs[i].io->setNotifier(
nullptr, 0,
nullptr);
318bool CProgSwitch::allInputsMatch()
const
320 for (
size_t i = 0; i < inputs.size(); i++)
322 if (inputs[i].current != inputs[i].match)
331void CProgSwitch::evaluate()
337 for (
size_t i = 0; i < inputs.size(); i++)
341 if (inputs[i].io ==
nullptr)
346 ret = inputs[i].io->getData(inputData, 1);
349 DAWNERR(
"switch: getData failed on input %zu: %d\n", i, ret);
353 inputs[i].current = inputData(0);
356 allMatch = allInputsMatch();
358 if (allMatch == lastAndState)
363 lastAndState = allMatch;
364 cmd = allMatch ? onCmd : offCmd;
366 if (!iodata || !target)
372 std::memcpy(iodata->
getDataPtr(), &cmd,
sizeof(cmd));
374 ret = target->
setData(*iodata);
377 DAWNERR(
"switch: setData to target failed %d\n", ret);
CIOCommon * getIO(SObjectId::ObjectId id)
Get an I/O object by ID.
void setObjectMapItem(SObjectId::ObjectId id, CObject *obj)
Set an item in the object map.
Descriptor wrapper for individual object configuration.
size_t getSize() const
Get number of configuration items for this object.
SObjectCfg::SObjectCfgItem * objectCfgItemNext(size_t &offset) const
Get config item at current offset and advance past it.
Base class for all I/O objects.
int setData(IODataCmn &data, size_t offset=0)
Set data for I/O (public interface with stats tracking).
virtual size_t getDataDim() const =0
Get data vector dimension.
virtual size_t getDataSize() const =0
Get data size in bytes.
virtual bool isRead() const =0
Check if IO supports read operations.
CDescObject & getDesc()
Get descriptor object for this object.
uint8_t getDtype() const
Get data type field.
Base class for all PROG (processing) objects.
int deinit()
De-initialize object.
bool hasThread() const
Check if a background thread is active.
int init()
One-time initialize object after bindings are resolved.
int doStart()
Start implementation hook.
int doStop()
Stop implementation hook.
int configure()
Configure object from descriptor data.
Out-of-tree user-extension hooks for Dawn.
Single configuration item within object.
ObjectCfgData_t data[]
Configuration data array (flexible, size from cfgid.s.size).
UObjectCfgId cfgid
Configuration ID header (type, class, id, size, rw, dtype).
@ DTYPE_UINT32
Unsigned 32-bit integer (0 to 4294967295).
uint32_t ObjectId
ObjectID type - single 32-bit value.
Heap-allocated dynamic I/O data buffer.
size_t getDataSize()
Get data size in bytes.
void * getDataPtr(size_t batch=0)
Get pointer to data only (skips timestamp if present).
size_t getItems()
Get number of items per batch.
Static (compile-time) I/O data buffer (no timestamp).
ObjectCfgId v
Raw 32-bit ConfigID value (for storage, comparison).
uint32_t cls
Object class (bits 21-29, max 511).
uint32_t id
Configuration identifier (bits 0-4, max 31).
uint32_t size
Configuration data size in 32-bit words (bits 5-14, max 1023).
struct dawn::SObjectCfg::UObjectCfgId::@10 s
Bit-field structure for named member access.
32-bit encoded object identifier (union with bit field).
ObjectId v
Raw 32-bit ObjectID value (for comparison, hashing, storage).