/** * @file GoExtTool.c * * @internal * Copyright (C) 2016-2021 by LMI Technologies Inc. * Licensed under the MIT License. * Redistributed files must retain the above copyright notice. */ #include #include #include kBeginClassEx(Go, GoExtTool) kAddVMethod(GoExtTool, kObject, VRelease) kAddVMethod(GoExtTool, GoTool, VInit) kAddVMethod(GoExtTool, GoTool, VRead) kAddVMethod(GoExtTool, GoTool, VWrite) kEndClassEx() GoFx(kStatus) GoExtTool_Construct(GoExtTool* tool, kObject sensor, kAlloc allocator) { return kERROR_UNIMPLEMENTED; } GoFx(kStatus) GoExtTool_Init(GoTool tool, kType type, GoToolType typeId, kObject sensor, kAlloc alloc) { kObjR(GoExtTool, tool); kCheck(GoTool_Init(tool, type, typeId, sensor, alloc)); obj->version[0] = 0; obj->toolType[0] = 0; kZero(obj->streamOptions); kZero(obj->stream); kZero(obj->sourceOptions); kZero(obj->anchoring); obj->params = kNULL; kZero(obj->toolDataOutputs); obj->source = GO_DATA_SOURCE_TOP; obj->anchoring.x.anchor = GO_MEASUREMENT_ID_NONE; obj->anchoring.y.anchor = GO_MEASUREMENT_ID_NONE; obj->anchoring.z.anchor = GO_MEASUREMENT_ID_NONE; obj->anchoring.zAngle.anchor = GO_MEASUREMENT_ID_NONE; obj->anchoring.x.used = kFALSE; obj->anchoring.y.used = kFALSE; obj->anchoring.z.used = kFALSE; obj->anchoring.zAngle.used = kFALSE; kCheck(kArrayList_Construct(&obj->anchoring.x.options, kTypeOf(k32u), 0, alloc)); kCheck(kArrayList_Construct(&obj->anchoring.y.options, kTypeOf(k32u), 0, alloc)); kCheck(kArrayList_Construct(&obj->anchoring.z.options, kTypeOf(k32u), 0, alloc)); kCheck(kArrayList_Construct(&obj->anchoring.zAngle.options, kTypeOf(k32u), 0, alloc)); //obj->stream.step = GO_DATA_STEP_SURFACE; //obj->stream.id = 0; kCheck(kArrayList_Construct(&obj->streamOptions, kTypeOf(GoDataStream), 0, alloc)); kCheck(kArrayList_Construct(&obj->sourceOptions, kTypeOf(GoDataSource), 0, alloc)); kCheck(GoExtParams_Construct(&obj->params, sensor, alloc)); kCheck(kArrayList_Construct(&obj->toolDataOutputs, kTypeOf(GoExtToolDataOutput), 0, alloc)); return kOK; } GoFx(kStatus) GoExtTool_VInit(GoExtTool tool, kType type, kObject sensor, kAlloc alloc) { return GoExtTool_Init(tool, type, GO_TOOL_EXTENSIBLE, sensor, alloc); } GoFx(kStatus) GoExtTool_VRelease(GoExtTool tool) { kObj(GoExtTool, tool); kCheck(kDisposeRef(&obj->streamOptions)); kCheck(kDisposeRef(&obj->sourceOptions)); kCheck(kDisposeRef(&obj->anchoring.x.options)); kCheck(kDisposeRef(&obj->anchoring.y.options)); kCheck(kDisposeRef(&obj->anchoring.z.options)); kCheck(kDisposeRef(&obj->anchoring.zAngle.options)); kCheck(kDisposeRef(&obj->params)); kCheck(kDisposeRef(&obj->toolDataOutputs)); return GoTool_VRelease(tool); } GoFx(kStatus) GoExtTool_VRead(GoExtTool tool, kXml xml, kXmlItem item) { kObj(GoExtTool, tool); kString tempText = kNULL; kXmlItem childItem; kCheck(GoTool_VRead(tool, xml, item)); kCheck(GoToolUtil_ParseStreamOptions(tool, xml, item, obj->streamOptions)); kTry { kTest(kString_Construct(&tempText, kNULL, kObject_Alloc(tool))); if (kXml_AttrExists(xml, item, GO_XML_TAG_NAME_ATTR_VERSION)) { kTest(kXml_AttrText(xml, item, GO_XML_TAG_NAME_ATTR_VERSION, obj->version, kCountOf(obj->version))); } if (kXml_AttrExists(xml, item, GO_XML_TAG_NAME_ATTR_TYPE)) { kTest(kXml_AttrText(xml, item, GO_XML_TAG_NAME_ATTR_TYPE, obj->toolType, kCountOf(obj->toolType))); } childItem = kXml_Child(xml, item, GO_XML_TAG_NAME_STREAM); if (!kIsNull(childItem)) { kTest(kXml_Child32s(xml, childItem, GO_XML_TAG_NAME_STREAM_STEP, &obj->stream.step)); kTest(kXml_Child32s(xml, childItem, GO_XML_TAG_NAME_STREAM_ID, &obj->stream.id)); } kTest(!kIsNull(childItem = kXml_Child(xml, item, GO_XML_TAG_NAME_ANCHOR))); kTest(GoExtTool_ParseAnchor(xml, childItem, &obj->anchoring)); kTest(kXml_Child32s(xml, item, GO_XML_TAG_NAME_SOURCE, &obj->source)); kTest(!kIsNull(childItem = kXml_Child(xml, item, GO_XML_TAG_NAME_SOURCE))); kTest(kXml_AttrString(xml, childItem, GO_XML_TAG_NAME_ATTR_OPTIONS, tempText)); kTest(GoOptionList_ParseList32u(kString_Chars(tempText), obj->sourceOptions)); // May not exist in non GDK internal tools childItem = kXml_Child(xml, item, GO_XML_TAG_NAME_PARAMETERS); if (!kIsNull(childItem)) { kTest(GoExtParams_Read(obj->params, xml, childItem)); } // Only extensible tools have tool data outputs section. kTest(GoExtTool_ReadToolDataOutputs(tool, xml, item)); } kFinally { kObject_Dispose(tempText); kEndFinally(); } return kOK; } GoFx(kStatus) GoExtTool_VWrite(GoExtTool tool, kXml xml, kXmlItem item) { kObj(GoExtTool, tool); kXmlItem tempItem; kXmlItem streamItem = kNULL; // Custom configuration nodes. kCheck(kXml_SetAttrText(xml, item, GO_XML_TAG_NAME_ATTR_TYPE, obj->toolType)); kCheck(kXml_SetAttrText(xml, item, GO_XML_TAG_NAME_ATTR_VERSION, obj->version)); kCheck(kXml_SetChild32s(xml, item, GO_XML_TAG_NAME_SOURCE, obj->source)); kCheck(kXml_AddItem(xml, item, GO_XML_TAG_NAME_ANCHOR, &tempItem)); if (obj->anchoring.x.used) { kCheck(kXml_SetChild32s(xml, tempItem, GO_XML_TAG_NAME_ANCHOR_X, obj->anchoring.x.anchor)); } if (obj->anchoring.y.used) { kCheck(kXml_SetChild32s(xml, tempItem, GO_XML_TAG_NAME_ANCHOR_Y, obj->anchoring.y.anchor)); } if (obj->anchoring.z.used) { kCheck(kXml_SetChild32s(xml, tempItem, GO_XML_TAG_NAME_ANCHOR_Z, obj->anchoring.z.anchor)); } if (obj->anchoring.zAngle.used) { kCheck(kXml_SetChild32s(xml, tempItem, GO_XML_TAG_NAME_ANCHOR_ZANGLE, obj->anchoring.zAngle.anchor)); } kCheck(kXml_AddItem(xml, item, GO_XML_TAG_NAME_PARAMETERS, &tempItem)); kCheck(GoExtParams_Write(obj->params, xml, tempItem)); kCheck(kXml_AddItem(xml, item, GO_XML_TAG_NAME_STREAM, &streamItem)); kCheck(kXml_SetChild32s(xml, streamItem, GO_XML_TAG_NAME_STREAM_STEP, obj->stream.step)); kCheck(kXml_SetChild32s(xml, streamItem, GO_XML_TAG_NAME_STREAM_ID, obj->stream.id)); kCheck(GoExtTool_WriteToolDataOutputs(tool, xml, item)); return GoTool_VWrite(tool, xml, item); } GoFx(kStatus) GoExtTool_ReadToolDataOutputs(GoExtTool tool, kXml xml, kXmlItem item) { kObj(GoExtTool, tool); kXmlItem toolDataListItem; kXmlItem toolDataItem; kSize itemCount = 0; kSize i; GoExtToolDataOutput toolDataOutput; kBool insertOutput; kStatus exception; toolDataListItem = kXml_Child(xml, item, GO_XML_TAG_NAME_TOOL_DATA_OUTPUTS); if (!kIsNull(toolDataListItem)) { itemCount = kXml_ChildCount(xml, toolDataListItem); for (i = 0; i < itemCount; i++) { insertOutput = kFALSE; toolDataItem = kXml_ChildAt(xml, toolDataListItem, i); kTry { if ((i >= kArrayList_Count(obj->toolDataOutputs)) || (kIsNull(toolDataOutput = kArrayList_AsT(obj->toolDataOutputs, i, GoExtToolDataOutput)))) { // No existing entry to overwrite, so allocate new entry. kTest(GoExtToolDataOutput_Construct(&toolDataOutput, kTypeOf(GoExtToolDataOutput), obj->base.sensor, kObject_Alloc(tool))); insertOutput = kTRUE; } kTest(GoExtToolDataOutput_Read(toolDataOutput, xml, toolDataItem, obj->base.format == GO_TOOL_FORMAT_GDK_USER)); if (insertOutput) { if (i >= kArrayList_Count(obj->toolDataOutputs)) { kTest(kArrayList_AddT(obj->toolDataOutputs, &toolDataOutput)); } else { kTest(kArrayList_InsertT(obj->toolDataOutputs, i, &toolDataOutput)); } } } kCatch(&exception) { if (insertOutput) { // An object was allocated kDisposeRef(&toolDataOutput); } kEndCatch(exception); } } } // If no exceptions raised, remove extraneous entries from the list // so that correct information is sent back to the sensor. // If exception occurs, leave the list as-is. while (itemCount < kArrayList_Count(obj->toolDataOutputs)) { kCheck(kArrayList_RemoveT(obj->toolDataOutputs, kArrayList_Count(obj->toolDataOutputs) - 1, &toolDataOutput)); kDisposeRef(&toolDataOutput); } return kOK; } GoFx(kStatus) GoExtTool_WriteToolDataOutputs(GoExtTool tool, kXml xml, kXmlItem item) { kObj(GoExtTool, tool); kXmlItem toolDataListItem; kXmlItem toolDataItem; kSize i; GoExtToolDataOutput toolDataOutput; kCheck(kXml_AddItem(xml, item, GO_XML_TAG_NAME_TOOL_DATA_OUTPUTS, &toolDataListItem)); for (i = 0; i < kArrayList_Count(obj->toolDataOutputs); i++) { toolDataOutput = *kArrayList_AtT(obj->toolDataOutputs, i, GoExtToolDataOutput); // Add a place holder for child node, and give it a dummy name so that // the node can be added to the XML structure. // The real name will be filled in by the class code implementation. kCheck(kXml_AddItem(xml, toolDataListItem, GO_XML_TAG_NAME_TOOL_DATA_OUTPUTS, &toolDataItem)); kCheck(GoExtToolDataOutput_Write(toolDataOutput, xml, toolDataItem, obj->base.format == GO_TOOL_FORMAT_GDK_USER)); } return kOK; } GoFx(kSize) GoExtTool_StreamOptionCount(GoExtTool tool) { kObj(GoExtTool, tool); GoSensor_SyncConfig(obj->base.sensor); return kArrayList_Count(obj->streamOptions); } GoFx(GoDataStream) GoExtTool_StreamOptionAt(GoExtTool tool, kSize index) { kObj(GoExtTool, tool); GoSensor_SyncConfig(obj->base.sensor); kAssert(index < kArrayList_Count(obj->streamOptions)); return kArrayList_AsT(obj->streamOptions, index, GoDataStream); } GoFx(kStatus) GoExtTool_SetStream(GoExtTool tool, GoDataStream stream) { kObj(GoExtTool, tool); kCheckState(GoSensor_IsConfigurable(GoTool_Sensor(tool))); kCheck(GoSensor_CacheConfig(GoTool_Sensor(tool))); kCheck(GoSensor_SyncConfig(GoTool_Sensor(tool))); if (GoTools_IsToolInOptionsList(GoSensor_Tools(GoTool_Sensor(tool)), kObject_Type(tool))) { kCheck(GoOptionList_CheckDataStream(kArrayList_DataT(obj->streamOptions, GoDataStream), kArrayList_Count(obj->streamOptions), stream)); } obj->stream = stream; kCheck(GoSensor_SetConfigModified(GoTool_Sensor(tool))); return kOK; } GoFx(GoDataStream) GoExtTool_Stream(GoExtTool tool) { kObj(GoExtTool, tool); GoSensor_SyncConfig(obj->base.sensor); return obj->stream; } GoFx(kStatus) GoExtTool_SetDisplayName(GoExtTool tool, const kChar* value) { kObj(GoExtTool, tool); return GoTool_SetName(tool, value); } GoFx(const kChar*) GoExtTool_DisplayName(GoExtTool tool) { kObj(GoExtTool, tool); GoSensor_SyncConfig(obj->base.sensor); return obj->base.name; } GoFx(const kChar*) GoExtTool_Type(GoExtTool tool) { kObj(GoExtTool, tool); GoSensor_SyncConfig(obj->base.sensor); return obj->toolType; } GoFx(kBool) GoExtTool_XAnchorSupportEnabled(GoExtTool tool) { kObj(GoExtTool, tool); GoSensor_SyncConfig(obj->base.sensor); return obj->anchoring.x.used; } GoFx(kBool) GoExtTool_YAnchorSupportEnabled(GoExtTool tool) { kObj(GoExtTool, tool); GoSensor_SyncConfig(obj->base.sensor); return obj->anchoring.y.used; } GoFx(kBool) GoExtTool_ZAnchorSupportEnabled(GoExtTool tool) { kObj(GoExtTool, tool); GoSensor_SyncConfig(obj->base.sensor); return obj->anchoring.z.used; } GoFx(kBool) GoExtTool_ZAngleAnchorSupportEnabled(GoExtTool tool) { kObj(GoExtTool, tool); GoSensor_SyncConfig(obj->base.sensor); return obj->anchoring.zAngle.used; } GoFx(kSize) GoExtTool_MeasurementCount(GoExtTool tool) { kObj(GoExtTool, tool); GoSensor_SyncConfig(obj->base.sensor); return kArrayList_Count(obj->base.measurements); } GoFx(GoMeasurement) GoExtTool_MeasurementAt(GoExtTool tool, kSize index) { kObj(GoExtTool, tool); GoSensor_SyncConfig(obj->base.sensor); if (index > kArrayList_Count(obj->base.measurements)) { return kNULL; } return *kArrayList_AtT(obj->base.measurements, index, GoMeasurement); } GoFx(GoMeasurement) GoExtTool_FindMeasurementByName(GoExtTool tool, const kChar* name) { kObj(GoExtTool, tool); kSize i; GoSensor_SyncConfig(obj->base.sensor); for (i = 0; i < kArrayList_Count(obj->base.measurements); i++) { GoMeasurement extMeasurement = *kArrayList_AtT(obj->base.measurements, i, GoMeasurement); const kChar* name2 = GoMeasurement_Name(extMeasurement); //not quite right - this checks the measurement name, but not the extensible tool's measurement type name identifier if (strcmp(name,name2) == 0) { return extMeasurement; } } return kNULL; } GoFx(kStatus) GoExtTool_SetSource(GoExtTool tool, GoDataSource source) { kObj(GoExtTool, tool); kCheckState(GoSensor_IsConfigurable(GoTool_Sensor(tool))); kCheck(GoSensor_CacheConfig(GoTool_Sensor(tool))); kCheck(GoSensor_SyncConfig(GoTool_Sensor(tool))); kCheck(GoOptionList_Check32u((k32u*)kArrayList_DataT(obj->sourceOptions, GoDataSource), kArrayList_Count(obj->sourceOptions), source)); obj->source = source; kCheck(GoSensor_SetConfigModified(GoTool_Sensor(tool))); return kOK; } GoFx(kSize) GoExtTool_SourceOptionCount(GoExtTool tool) { kObj(GoExtTool, tool); GoSensor_SyncConfig(obj->base.sensor); return kArrayList_Count(obj->sourceOptions); } GoFx(k32u) GoExtTool_SourceOptionAt(GoExtTool tool, kSize index) { kObj(GoExtTool, tool); GoSensor_SyncConfig(obj->base.sensor); kAssert(index < kArrayList_Count(obj->sourceOptions)); return kArrayList_AsT(obj->sourceOptions, index, k32u); } GoFx(GoDataSource) GoExtTool_Source(GoExtTool tool) { kObj(GoExtTool, tool); GoSensor_SyncConfig(obj->base.sensor); return obj->source; } GoFx(kSize) GoExtTool_XAnchorOptionCount(GoExtTool tool) { kObj(GoExtTool, tool); GoSensor_SyncConfig(obj->base.sensor); return kArrayList_Count(obj->anchoring.x.options); } GoFx(k32u) GoExtTool_XAnchorOptionAt(GoExtTool tool, kSize index) { kObj(GoExtTool, tool); GoSensor_SyncConfig(obj->base.sensor); kAssert(index < kArrayList_Count(obj->anchoring.x.options)); return kArrayList_AsT(obj->anchoring.x.options, index, k32u); } GoFx(k32s) GoExtTool_XAnchor(GoExtTool tool) { kObj(GoExtTool, tool); GoSensor_SyncConfig(obj->base.sensor); return obj->anchoring.x.anchor; } GoFx(kStatus) GoExtTool_SetXAnchor(GoExtTool tool, k32s id) { kObj(GoExtTool, tool); kCheckState(GoSensor_IsConfigurable(GoTool_Sensor(tool))); kCheck(GoSensor_CacheConfig(GoTool_Sensor(tool))); kCheck(GoSensor_SyncConfig(GoTool_Sensor(tool))); if (id != GO_MEASUREMENT_ID_NONE) { obj->anchoring.x.used = kTRUE; kCheck(GoOptionList_Check32u(kArrayList_DataT(obj->anchoring.x.options, k32u), kArrayList_Count(obj->anchoring.x.options), id)); } obj->anchoring.x.anchor = id; kCheck(GoSensor_SetConfigModified(GoTool_Sensor(tool))); return kOK; } GoFx(kBool) GoExtTool_XAnchorEnabled(GoExtTool tool) { kObj(GoExtTool, tool); GoSensor_SyncConfig(obj->base.sensor); if (obj->anchoring.x.anchor != GO_MEASUREMENT_ID_NONE) { return kTRUE; } return kFALSE; } GoFx(kSize) GoExtTool_YAnchorOptionCount(GoExtTool tool) { kObj(GoExtTool, tool); GoSensor_SyncConfig(obj->base.sensor); return kArrayList_Count(obj->anchoring.y.options); } GoFx(k32u) GoExtTool_YAnchorOptionAt(GoExtTool tool, kSize index) { kObj(GoExtTool, tool); GoSensor_SyncConfig(obj->base.sensor); kAssert(index < kArrayList_Count(obj->anchoring.y.options)); return kArrayList_AsT(obj->anchoring.y.options, index, k32u); } GoFx(k32s) GoExtTool_YAnchor(GoExtTool tool) { kObj(GoExtTool, tool); GoSensor_SyncConfig(obj->base.sensor); return obj->anchoring.y.anchor; } GoFx(kStatus) GoExtTool_SetYAnchor(GoExtTool tool, k32s id) { kObj(GoExtTool, tool); kCheckState(GoSensor_IsConfigurable(GoTool_Sensor(tool))); kCheck(GoSensor_CacheConfig(GoTool_Sensor(tool))); kCheck(GoSensor_SyncConfig(GoTool_Sensor(tool))); if (id != GO_MEASUREMENT_ID_NONE) { obj->anchoring.y.used = kTRUE; kCheck(GoOptionList_Check32u(kArrayList_DataT(obj->anchoring.y.options, k32u), kArrayList_Count(obj->anchoring.y.options), id)); } obj->anchoring.y.anchor = id; kCheck(GoSensor_SetConfigModified(GoTool_Sensor(tool))); return kOK; } GoFx(kBool) GoExtTool_YAnchorEnabled(GoExtTool tool) { kObj(GoExtTool, tool); GoSensor_SyncConfig(obj->base.sensor); if (obj->anchoring.y.anchor != GO_MEASUREMENT_ID_NONE) { return kTRUE; } return kFALSE; } GoFx(kSize) GoExtTool_ZAnchorOptionCount(GoExtTool tool) { kObj(GoExtTool, tool); GoSensor_SyncConfig(obj->base.sensor); return kArrayList_Count(obj->anchoring.z.options); } GoFx(k32u) GoExtTool_ZAnchorOptionAt(GoExtTool tool, kSize index) { kObj(GoExtTool, tool); GoSensor_SyncConfig(obj->base.sensor); kAssert(index < kArrayList_Count(obj->anchoring.z.options)); return kArrayList_AsT(obj->anchoring.z.options, index, k32u); } GoFx(kStatus) GoExtTool_SetZAnchor(GoExtTool tool, k32s id) { kObj(GoExtTool, tool); kCheckState(GoSensor_IsConfigurable(GoTool_Sensor(tool))); kCheck(GoSensor_CacheConfig(GoTool_Sensor(tool))); kCheck(GoSensor_SyncConfig(GoTool_Sensor(tool))); if (id != GO_MEASUREMENT_ID_NONE) { obj->anchoring.z.used = kTRUE; kCheck(GoOptionList_Check32u(kArrayList_DataT(obj->anchoring.z.options, k32u), kArrayList_Count(obj->anchoring.z.options), id)); } obj->anchoring.z.anchor = id; kCheck(GoSensor_SetConfigModified(GoTool_Sensor(tool))); return kOK; } GoFx(kBool) GoExtTool_ZAnchorEnabled(GoExtTool tool) { kObj(GoExtTool, tool); GoSensor_SyncConfig(obj->base.sensor); if (obj->anchoring.z.anchor != GO_MEASUREMENT_ID_NONE) { return kTRUE; } return kFALSE; } GoFx(k32s) GoExtTool_ZAnchor(GoExtTool tool) { kObj(GoExtTool, tool); GoSensor_SyncConfig(obj->base.sensor); return obj->anchoring.z.anchor; } GoFx(kSize) GoExtTool_ZAngleAnchorOptionCount(GoExtTool tool) { kObj(GoExtTool, tool); GoSensor_SyncConfig(obj->base.sensor); return kArrayList_Count(obj->anchoring.zAngle.options); } GoFx(k32u) GoExtTool_ZAngleAnchorOptionAt(GoExtTool tool, kSize index) { kObj(GoExtTool, tool); GoSensor_SyncConfig(obj->base.sensor); kAssert(index < kArrayList_Count(obj->anchoring.zAngle.options)); return kArrayList_AsT(obj->anchoring.zAngle.options, index, k32u); } GoFx(kStatus) GoExtTool_SetZAngleAnchor(GoExtTool tool, k32s id) { kObj(GoExtTool, tool); kCheckState(GoSensor_IsConfigurable(GoTool_Sensor(tool))); kCheck(GoSensor_CacheConfig(GoTool_Sensor(tool))); kCheck(GoSensor_SyncConfig(GoTool_Sensor(tool))); if (id != GO_MEASUREMENT_ID_NONE) { obj->anchoring.zAngle.used = kTRUE; kCheck(GoOptionList_Check32u(kArrayList_DataT(obj->anchoring.zAngle.options, k32u), kArrayList_Count(obj->anchoring.zAngle.options), id)); } obj->anchoring.zAngle.anchor = id; kCheck(GoSensor_SetConfigModified(GoTool_Sensor(tool))); return kOK; } GoFx(kBool) GoExtTool_ZAngleAnchorEnabled(GoExtTool tool) { kObj(GoExtTool, tool); GoSensor_SyncConfig(obj->base.sensor); if (obj->anchoring.zAngle.anchor != GO_MEASUREMENT_ID_NONE) { return kTRUE; } return kFALSE; } GoFx(k32s) GoExtTool_ZAngleAnchor(GoExtTool tool) { kObj(GoExtTool, tool); GoSensor_SyncConfig(obj->base.sensor); return obj->anchoring.zAngle.anchor; } GoFx(kSize) GoExtTool_ParameterCount(GoExtTool tool) { kObj(GoExtTool, tool); GoSensor_SyncConfig(obj->base.sensor); return GoExtParams_ParameterCount(obj->params); } GoFx(GoExtParam) GoExtTool_ParameterAt(GoExtTool tool, kSize index) { kObj(GoExtTool, tool); GoSensor_SyncConfig(obj->base.sensor); return GoExtParams_ParameterAt(obj->params, index); } GoFx(GoExtParam) GoExtTool_FindParameterById(GoExtTool tool, const kChar* id) { kObj(GoExtTool, tool); GoSensor_SyncConfig(obj->base.sensor); return GoExtParams_FindParameterById(obj->params, id); } GoFx(const kChar*) GoExtTool_Version(GoExtTool tool) { kObj(GoExtTool, tool); GoSensor_SyncConfig(obj->base.sensor); return obj->version; } GoFx(kStatus) GoExtTool_ParseAnchor(kXml xml, kXmlItem anchorItem, GoExtToolAnchoringCfg* anchoring) { kXmlItem tempItem = kNULL; kString tempText = kNULL; kTry { kTest(kString_Construct(&tempText, kNULL, kObject_Alloc(anchoring->x.options))); if (kXml_ChildExists(xml, anchorItem, GO_XML_TAG_NAME_ANCHOR_X)) { kTestArgs(!kIsNull(tempItem = kXml_Child(xml, anchorItem, GO_XML_TAG_NAME_ANCHOR_X))); kTest(kXml_Item32s(xml, tempItem, &anchoring->x.anchor)); if (kXml_AttrExists(xml, tempItem, GO_XML_TAG_NAME_ATTR_USED)) { kTest(kXml_AttrBool(xml, tempItem, GO_XML_TAG_NAME_ATTR_USED, &anchoring->x.used)); } else { anchoring->x.used = kTRUE; } kTest(kXml_AttrString(xml, tempItem, GO_XML_TAG_NAME_ATTR_OPTIONS, tempText)); kTest(GoOptionList_ParseList32u(kString_Chars(tempText), anchoring->x.options)); } else { anchoring->x.used = kFALSE; } if (kXml_ChildExists(xml, anchorItem, GO_XML_TAG_NAME_ANCHOR_Y)) { kTestArgs(!kIsNull(tempItem = kXml_Child(xml, anchorItem, GO_XML_TAG_NAME_ANCHOR_Y))); kTest(kXml_Item32s(xml, tempItem, &anchoring->y.anchor)); if (kXml_AttrExists(xml, tempItem, GO_XML_TAG_NAME_ATTR_USED)) { kTest(kXml_AttrBool(xml, tempItem, GO_XML_TAG_NAME_ATTR_USED, &anchoring->y.used)); } else { anchoring->y.used = kTRUE; } kTest(kXml_AttrString(xml, tempItem, GO_XML_TAG_NAME_ATTR_OPTIONS, tempText)); kTest(GoOptionList_ParseList32u(kString_Chars(tempText), anchoring->y.options)); } else { anchoring->y.used = kFALSE; } if (kXml_ChildExists(xml, anchorItem, GO_XML_TAG_NAME_ANCHOR_Z)) { kTestArgs(!kIsNull(tempItem = kXml_Child(xml, anchorItem, GO_XML_TAG_NAME_ANCHOR_Z))); kTest(kXml_Item32s(xml, tempItem, &anchoring->z.anchor)); if (kXml_AttrExists(xml, tempItem, GO_XML_TAG_NAME_ATTR_USED)) { kTest(kXml_AttrBool(xml, tempItem, GO_XML_TAG_NAME_ATTR_USED, &anchoring->z.used)); } else { anchoring->z.used = kTRUE; } kTest(kXml_AttrString(xml, tempItem, GO_XML_TAG_NAME_ATTR_OPTIONS, tempText)); kTest(GoOptionList_ParseList32u(kString_Chars(tempText), anchoring->z.options)); } else { anchoring->z.used = kFALSE; } if (kXml_ChildExists(xml, anchorItem, GO_XML_TAG_NAME_ANCHOR_ZANGLE)) { kTestArgs(!kIsNull(tempItem = kXml_Child(xml, anchorItem, GO_XML_TAG_NAME_ANCHOR_ZANGLE))); kTest(kXml_Item32s(xml, tempItem, &anchoring->zAngle.anchor)); if (kXml_AttrExists(xml, tempItem, GO_XML_TAG_NAME_ATTR_USED)) { kTest(kXml_AttrBool(xml, tempItem, GO_XML_TAG_NAME_ATTR_USED, &anchoring->zAngle.used)); } else { anchoring->zAngle.used = kTRUE; } kTest(kXml_AttrString(xml, tempItem, GO_XML_TAG_NAME_ATTR_OPTIONS, tempText)); kTest(GoOptionList_ParseList32u(kString_Chars(tempText), anchoring->zAngle.options)); } else { anchoring->zAngle.used = kFALSE; } } kFinally { kObject_Dispose(tempText); kEndFinally(); } return kOK; } GoFx(kSize) GoExtTool_ToolDataOutputCount(GoExtTool tool) { kObj(GoExtTool, tool); GoSensor_SyncConfig(obj->base.sensor); return kArrayList_Count(obj->toolDataOutputs); } GoFx(GoExtToolDataOutput) GoExtTool_ToolDataOutputAt(GoExtTool tool, kSize index) { kObj(GoExtTool, tool); GoSensor_SyncConfig(obj->base.sensor); kAssert(index < kArrayList_Count(obj->toolDataOutputs)); if (index >= kArrayList_Count(obj->toolDataOutputs)) { return kNULL; } return *kArrayList_AtT(obj->toolDataOutputs, index, GoExtToolDataOutput); } GoFx(kBool) GoExtTool_Equals(GoExtTool tool, kString toolType) { kObj(GoExtTool, tool); if (kIsNull(toolType) || 0 >= kString_Length(toolType)) { return kFALSE; } else if (0 < kStrLength(obj->toolType)) { return kString_Equals(toolType, obj->toolType); } return kString_Equals(toolType, kType_Name(kObject_Type(tool))); }