Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
5271c1a
Updated iteration to for loop style from while iteration
alien588 Dec 24, 2025
44da1ba
Added a utility method for retrieval of sample rate from domain data …
alien588 Dec 24, 2025
d4b9472
2.0 example draft
alien588 Jan 6, 2026
1e67a95
tree_traversal example update
alien588 Jan 7, 2026
6b346c1
Updated Tree traversal example
alien588 Jan 7, 2026
eb83099
Added first iteration of tree traversal
alien588 Jan 9, 2026
0fafd54
Updated framework of the example
alien588 Jan 12, 2026
b5a15c3
Updated numenclatire and creted a simple version of the display sctript
alien588 Jan 12, 2026
33b3752
Addressed code review
alien588 Dec 9, 2025
cca8ea5
Missing changes required by the code review
alien588 Dec 9, 2025
ed39e4f
Removed use of block reader
alien588 Jan 6, 2026
ad407d5
Mssing dots
alien588 Jan 6, 2026
f4b2a53
Updated comment
alien588 Jan 6, 2026
a5f03dc
Updated calculation of sampleRate
alien588 Jan 6, 2026
ec07eb5
Fixed sampleRate calculation function in daq_utils
alien588 Jan 6, 2026
d02ccae
Addressing a code review
alien588 Jan 7, 2026
d27e326
Added a new utility method for checking if the data rule is linear
alien588 Jan 7, 2026
cd757d5
Refactored sample rate calculation method
alien588 Jan 7, 2026
a0d2f18
Fixed a typo
alien588 Jan 7, 2026
b4ed30e
Renaming functions and misc printout format fix
alien588 Jan 8, 2026
2d836d1
Added basic information display for nodes when traversing the tree
alien588 Jan 12, 2026
7f63be8
Updated structure
alien588 Jan 13, 2026
d2b0566
Added sceleton for globalID search
alien588 Jan 13, 2026
1a84ccd
Removed hanging TODO comments and misc.
alien588 Jan 14, 2026
c9cbf11
Removed unnecesary comments
alien588 Jan 14, 2026
2591238
Missed it
alien588 Jan 14, 2026
36bcb0e
Updated exaple to a working state
alien588 Jan 15, 2026
39204d3
Remowed access new line
alien588 Jan 15, 2026
568f656
Updated example and removed dangling comments
alien588 Jan 16, 2026
b00df6e
Merge branch 'main' into feature/examples-v0.6
alien588 Jan 20, 2026
481bbdb
Updated the example
alien588 Jan 20, 2026
72c0eb7
Renamed example
alien588 Jan 20, 2026
27b7ded
Renamed variable for greater clarity
alien588 Jan 20, 2026
0c8b358
Updated example description
alien588 Jan 21, 2026
4033bfe
Set required openDAQ CMake flags
JakaMohorko Jan 21, 2026
e5d530f
Disable logging, use instance builder and module path
JakaMohorko Jan 21, 2026
ef7e4af
Added a utility method for retrieval of sample rate from domain data …
alien588 Dec 24, 2025
9a1c2a7
2.0 example draft
alien588 Jan 6, 2026
e645142
Addressed code review
alien588 Dec 9, 2025
8d033ba
Missing changes required by the code review
alien588 Dec 9, 2025
034ddbb
Updated exaple to a working state
alien588 Jan 15, 2026
72765da
Updated example and removed dangling comments
alien588 Jan 16, 2026
a0ed3af
Renamed example
alien588 Jan 20, 2026
bf54bf4
Merge branch 'main' into feature/examples-v0.6
alien588 Jan 21, 2026
a5fd85e
Removing merging artifacts
alien588 Jan 21, 2026
ced9806
Removing artifacts 2.0
alien588 Jan 21, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions examples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ set(EXAMPLE_SOURCES
stream_reader_read_in_loop.c
read_with_formatted_timestamps.c
print_data_descriptor_and_calculater_sample_rate.c
create_and_read_sample_rate_buffers.c)

create_and_read_sample_rate_buffers.c
tree_traversal.c)

foreach(src ${EXAMPLE_SOURCES})
get_filename_component(exec_name ${src} NAME_WLE)
Expand Down
384 changes: 384 additions & 0 deletions examples/tree_traversal.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,384 @@
/*
* In openDAQ devices are represented by a tree structure. Example demonstrates how to fully explore that tree and displays
* the type of the object alongside its name. After saving every object into an dictionary, example displays all of saved objects
* globalIds.
*/

#include <daq_utils.h>

enum ComponentType
{
Unk = 0,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should use full words where abbreviations are redundant.

Suggested change
Unk = 0,
Unknown = 0,

Device,
FunctionBlock,
IOFolder,
Channel,
Server,
Signal,
Folder,
Component,
SyncComponent,
InputPort
};

void componentTreePrintOut(daqDevice* headDevice, daqDict** listOfAvailableDevices, daqBool printout);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

printComponentTree to be consistent.


void printDaqSignal(daqSignal* signal, daqDict* listOfAvailableDevices, daqBool printout);
void printInputPort(daqInputPort* inputPort, daqDict* listOfAvailableDevices, daqBool printout);
void printDaqSyncComponent(daqSyncComponent* syncComp, daqDict* listOfAvailableDevices, daqBool printout);
Comment on lines +26 to +28
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are duplicates.

void printDaqServer(daqServer* server, daqDict* listOfAvailableDevices, daqBool printout);
void printDaqFolder(daqFolder* folder, daqDict* listOfAvailableDevices, daqBool printout);
void printDaqFunctionBlock(daqFunctionBlock* functionBlock, daqDict* listOfAvailableDevices, daqBool printout);
void printDaqDevice(daqDevice* device, daqDict* listOfAvailableDevices, daqBool printout);

void addDaqComponentToDict(daqDict* listOfAvailableDevices, daqComponent* component);


void addDaqComponentToDict(daqDict* listOfAvailableDevices, daqComponent* component)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The last declaration is implemented first. The order of implementations should follow the declaration order.

{
daqString* globalId = NULL;
daqString* description = NULL;
daqComponent_getGlobalId(component, &globalId);
daqComponent_getDescription(component, &description);

daqDict_set(listOfAvailableDevices, globalId, description);
Comment on lines +41 to +44
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The description is never used.


daqReleaseRef(globalId);
daqReleaseRef(description);
}

void componentTreePrintOut(daqDevice* headDevice, daqDict** listOfAvailableDevices, daqBool printout)
{
daqDict_createDict(listOfAvailableDevices);
printDaqDevice(headDevice, *listOfAvailableDevices, printout);
}
Comment on lines +50 to +54
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does not need to be its own function.


void printObjectList(daqList* list, daqDict* listOfAvailableDevices, daqBool printout)
{
daqBaseObject* listMember = NULL;
daqSizeT count = 0;
daqList_getCount(list, &count);
if (count <= 0)
return;
daqList_getItemAt(list, 0, &listMember);
enum ComponentType componentType = Unk;

if (DAQ_SUPPORTS_INTERFACE(listMember, DAQ_DEVICE_INTF_ID) && (componentType == Unk))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These calls are redundant. Whenever the function is called, given the current structure, the type of objects in the list are already known. The component type should be passed as argument.

componentType = Device;

if (DAQ_SUPPORTS_INTERFACE(listMember, DAQ_SERVER_INTF_ID) && (componentType == Unk))
componentType = Server;

if (DAQ_SUPPORTS_INTERFACE(listMember, DAQ_SYNC_COMPONENT_INTF_ID) && (componentType == Unk))
componentType = SyncComponent;

if (DAQ_SUPPORTS_INTERFACE(listMember, DAQ_FUNCTION_BLOCK_INTF_ID) && (componentType == Unk))
componentType = FunctionBlock;

if (DAQ_SUPPORTS_INTERFACE(listMember, DAQ_FOLDER_INTF_ID) && (componentType == Unk))
componentType = Folder;

if (DAQ_SUPPORTS_INTERFACE(listMember, DAQ_INPUT_PORT_INTF_ID) && (componentType == Unk))
componentType = InputPort;

if (DAQ_SUPPORTS_INTERFACE(listMember, DAQ_SIGNAL_INTF_ID) && (componentType == Unk))
componentType = Signal;
Comment on lines +66 to +85
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be in its own function getComponentType.


daqSizeT numberOfObjects = 0;
daqList_getCount(list, &numberOfObjects);

for (daqSizeT i = 0; i < numberOfObjects; i++)
{
daqList_getItemAt(list, i, &listMember);

switch (componentType)
{
case Device:
{
daqDevice* device = NULL;
daqQueryInterface(listMember, DAQ_DEVICE_INTF_ID, &device);
printDaqDevice(device, listOfAvailableDevices, printout);
daqReleaseRef(device);
daqReleaseRef(listMember);
Comment on lines +98 to +102
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move the query interfaces inside the print functions. It'll be more legible.

break;
}
case Server:
{
daqServer* server = NULL;
daqQueryInterface(listMember, DAQ_SERVER_INTF_ID, &server);
printDaqServer(server, listOfAvailableDevices, printout);
daqReleaseRef(server);
daqReleaseRef(listMember);
break;
}
case SyncComponent:
{
daqSyncComponent* syncComponent = NULL;
daqQueryInterface(listMember, DAQ_SYNC_COMPONENT_INTF_ID, &syncComponent);
printDaqSyncComponent(syncComponent, listOfAvailableDevices, printout);
daqReleaseRef(syncComponent);
daqReleaseRef(listMember);
break;
}
case FunctionBlock:
{
daqFunctionBlock* functionBlock = NULL;
daqQueryInterface(listMember, DAQ_FUNCTION_BLOCK_INTF_ID, &functionBlock);
printDaqFunctionBlock(functionBlock, listOfAvailableDevices, printout);
daqReleaseRef(functionBlock);
daqReleaseRef(listMember);
break;
}
case Folder:
{
daqFolder* folder = NULL;
daqQueryInterface(listMember, DAQ_FOLDER_INTF_ID, &folder);
printDaqFolder(folder, listOfAvailableDevices, printout);
daqReleaseRef(folder);
daqReleaseRef(listMember);
break;
}
case InputPort:
{
daqInputPort* inputPort = NULL;
daqQueryInterface(listMember, DAQ_INPUT_PORT_INTF_ID, &inputPort);
printInputPort(inputPort, listOfAvailableDevices, printout);
daqReleaseRef(inputPort);
daqReleaseRef(listMember);
break;
}
case Signal:
{
daqSignal* signal = NULL;
daqQueryInterface(listMember, DAQ_SIGNAL_INTF_ID, &signal);
printDaqSignal(signal, listOfAvailableDevices, printout);
daqReleaseRef(signal);
daqReleaseRef(listMember);
break;
}
default:
{
daqReleaseRef(listMember);
break;
}
}
}
}

void printDaqDevice(daqDevice* device, daqDict* listOfAvailableDevices, daqBool printout)
{
daqString* name = NULL;
daqComponent_getName((daqComponent*)device, &name);

if (printout && name != NULL)
printDaqFormattedString("Device: %s\n", name);

daqReleaseRef(name);

addDaqComponentToDict(listOfAvailableDevices, (daqComponent*) device);

daqFolder* ioFolder = NULL;
daqDevice_getInputsOutputsFolder(device, &ioFolder);
if (ioFolder != NULL)
{
printDaqFolder(ioFolder, listOfAvailableDevices, printout);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just have a method called printIOComponent.

daqReleaseRef(ioFolder);
}

daqSyncComponent* syncComponent = NULL;
daqDevice_getSyncComponent(device, &syncComponent);
if (syncComponent != NULL)
{
printDaqSyncComponent(syncComponent, listOfAvailableDevices, printout);
daqReleaseRef(syncComponent);
}

daqList* devices = NULL;
daqDevice_getDevices(device, &devices, NULL);
if (devices != NULL)
{
printObjectList(devices, listOfAvailableDevices, printout);
daqReleaseRef(devices);
}

daqList* functionBlocks = NULL;
daqDevice_getFunctionBlocks(device, &functionBlocks, NULL);
if (functionBlocks != NULL)
{
printObjectList(functionBlocks, listOfAvailableDevices, printout);
daqReleaseRef(functionBlocks);
}

daqList* servers = NULL;
daqDevice_getServers(device, &servers);
if (servers != NULL)
{
printObjectList(servers, listOfAvailableDevices, printout);
daqReleaseRef(servers);
}
}

void printDaqFunctionBlock(daqFunctionBlock* functionBlock, daqDict* listOfAvailableDevices, daqBool printout)
{
daqString* name = NULL;
daqComponent_getName((daqComponent*)functionBlock, &name);

if (printout && name != NULL)
printDaqFormattedString("Function block: %s\n", name);

daqReleaseRef(name);

addDaqComponentToDict(listOfAvailableDevices, (daqComponent*) functionBlock);

daqList* functionBlocks = NULL;
daqFunctionBlock_getFunctionBlocks(functionBlock, &functionBlocks, NULL);
if (functionBlocks != NULL)
{
printObjectList(functionBlocks, listOfAvailableDevices, printout);
daqReleaseRef(functionBlocks);
}

daqList* inputPorts = NULL;
daqFunctionBlock_getInputPorts(functionBlock, &inputPorts, NULL);
if (inputPorts != NULL)
{
printObjectList(inputPorts, listOfAvailableDevices, printout);
daqReleaseRef(inputPorts);
}

daqList* listOfSignals = NULL;
daqFunctionBlock_getSignals(functionBlock, &listOfSignals, NULL);
if (listOfSignals != NULL)
{
printObjectList(listOfSignals, listOfAvailableDevices, printout);
daqReleaseRef(listOfSignals);
}
}

void printDaqFolder(daqFolder* folder, daqDict* listOfAllDevices, daqBool printout)
{
daqString* name = NULL;
daqComponent_getName((daqComponent*)folder, &name);


if (printout&& name!=NULL)
printDaqFormattedString("Folder: %s\n", name);

daqReleaseRef(name);

addDaqComponentToDict(listOfAllDevices, (daqComponent*) folder);

daqList* listOfItems = NULL;
daqFolder_getItems(folder, &listOfItems, NULL);
if (listOfItems != NULL)
{
printObjectList(listOfItems, listOfAllDevices, printout);
daqReleaseRef(listOfItems);
}
}

void printDaqServer(daqServer* server, daqDict* listOfAllAvailableDevices, daqBool printout)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The argument name being listOfAvailableDevices does not make sense.

{
daqString* name = NULL;
daqComponent_getName((daqComponent*)server, &name);

if(printout && name != NULL)
printDaqFormattedString("Server: %s\n", name);

daqReleaseRef(name);

addDaqComponentToDict(listOfAllAvailableDevices, (daqComponent*) server);

daqList* listOfSignals = NULL;
daqServer_getSignals(server, &listOfSignals, NULL);
if (listOfSignals != NULL)
{
printObjectList(listOfSignals, listOfAllAvailableDevices, printout);
daqReleaseRef(listOfSignals);
}
}

void printDaqSyncComponent(daqSyncComponent* syncComp, daqDict* listOfAvailableDevices, daqBool printout)
{
daqString* name = NULL;
daqComponent_getName((daqComponent*)syncComp, &name);

if(printout && name != NULL)
printDaqFormattedString("Sync component: %s\n", name);

daqReleaseRef(name);

addDaqComponentToDict(listOfAvailableDevices, (daqComponent*) syncComp);
}

void printInputPort(daqInputPort* inputPort, daqDict* listOfAvailableDevices, daqBool printout)
{
daqString* name = NULL;
daqComponent_getName((daqComponent*)inputPort, &name);

if (printout && name != NULL)
printDaqFormattedString("Input port: %s\n", name);

daqReleaseRef(name);

addDaqComponentToDict(listOfAvailableDevices, (daqComponent*) inputPort);
}

void printDaqSignal(daqSignal* signal, daqDict* listOfAvailableDevices, daqBool printout)
{
daqString* name = NULL;
daqComponent_getName((daqComponent*)signal, &name);

if (printout && name != NULL)
printDaqFormattedString("Signal: %s\n", name);

daqReleaseRef(name);

addDaqComponentToDict(listOfAvailableDevices, (daqComponent*) signal);
}

int main()
{
daqInstance* simulatorInstance = NULL;
setupSimulator(&simulatorInstance);

daqInstance* instance = NULL;
daqDevice* simulator = NULL;
addSimulator(&simulator, &instance);

daqDict* listOfComponents = NULL;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see the need why we would want to collect all components here. The goal is to do a DFS tree traversal and print out all component IDs and potentially names/other metadata.

Caching all global IDs only to later just print them out seems redundant.


componentTreePrintOut((daqDevice*)instance, &listOfComponents, True);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does this not just call printDaqDevice?


daqSizeT count = 0;
daqDict_getCount(listOfComponents, &count);
printf("\nNumber of components in the openDAQ tree: %llu\n\n", count);

daqList* keys = NULL;
daqDict_getKeyList(listOfComponents, &keys);
daqIterator* iterator = NULL;
daqList_createStartIterator(keys, &iterator);
Comment on lines +357 to +360
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this a dictionary if all that's being printed out are the global IDs?


while(daqIterator_moveNext(iterator) == DAQ_SUCCESS)
{
daqBaseObject* current = NULL;
daqIterator_getCurrent(iterator, &current);
daqString* comp = NULL;
if(DAQ_SUPPORTS_INTERFACE(current, DAQ_STRING_INTF_ID))
{
daqQueryInterface(current, DAQ_STRING_INTF_ID, &comp);
daqConstCharPtr constChar = NULL;
daqString_getCharPtr(comp, &constChar);
printf("%s\n", constChar);
}
daqReleaseRef(current);
}

daqReleaseRef(iterator);
daqReleaseRef(keys);
daqReleaseRef(listOfComponents);
daqReleaseRef(simulator);
daqReleaseRef(instance);
daqReleaseRef(simulatorInstance);
return 0;
}