250 lines
6.3 KiB
C
250 lines
6.3 KiB
C
/**
|
|
* @file GoOutput.c
|
|
*
|
|
* @internal
|
|
* Copyright (C) 2016-2021 by LMI Technologies Inc.
|
|
* Licensed under the MIT License.
|
|
* Redistributed files must retain the above copyright notice.
|
|
*/
|
|
#include <GoSdk/Outputs/GoOutput.h>
|
|
#include <GoSdk/GoUtils.h>
|
|
|
|
kBeginClassEx(Go, GoOutput)
|
|
kAddVMethod(GoOutput, kObject, VRelease)
|
|
kEndClassEx()
|
|
|
|
GoFx(kStatus) GoOutput_Construct(GoOutput* output, kObject sensor, kAlloc allocator)
|
|
{
|
|
kAlloc alloc = kAlloc_Fallback(allocator);
|
|
kStatus status;
|
|
|
|
kCheck(kAlloc_GetObject(alloc, kTypeOf(GoOutput), output));
|
|
|
|
if (!kSuccess(status = GoOutput_Init(*output, kTypeOf(GoOutput), sensor, alloc)))
|
|
{
|
|
kAlloc_FreeRef(alloc, output);
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
GoFx(kStatus) GoOutput_Init(GoOutput output, kType type, kObject sensor, kAlloc alloc)
|
|
{
|
|
kObjR(GoOutput, output);
|
|
k32u i;
|
|
kStatus exception;
|
|
|
|
kCheck(kObject_Init(output, type, alloc));
|
|
|
|
obj->sensor = sensor;
|
|
obj->xml = obj->xmlItem = obj->ethernet = obj->serial = obj->analog = kNULL;
|
|
for (i = 0; i < kCountOf(obj->digital); ++i) obj->digital[i] = kNULL;
|
|
|
|
kTry
|
|
{
|
|
kTest(GoEthernet_Construct(&obj->ethernet, sensor, alloc));
|
|
kTest(GoSerial_Construct(&obj->serial, sensor, alloc));
|
|
kTest(GoAnalog_Construct(&obj->analog, sensor, alloc));
|
|
|
|
for (i = 0; i < kCountOf(obj->digital); ++i)
|
|
{
|
|
kTest(GoDigital_Construct(&obj->digital[i], sensor, alloc));
|
|
}
|
|
}
|
|
kCatch(&exception)
|
|
{
|
|
GoOutput_VRelease(output);
|
|
kEndCatch(exception);
|
|
}
|
|
|
|
return kOK;
|
|
}
|
|
|
|
GoFx(kStatus) GoOutput_VRelease(GoOutput output)
|
|
{
|
|
kObjR(GoOutput, output);
|
|
k32u i;
|
|
|
|
kCheck(kDestroyRef(&obj->ethernet));
|
|
kCheck(kDestroyRef(&obj->serial));
|
|
kCheck(kDestroyRef(&obj->analog));
|
|
|
|
for (i = 0; i < kCountOf(obj->digital); ++i)
|
|
{
|
|
kCheck(kDestroyRef(&obj->digital[i]));
|
|
}
|
|
|
|
kCheck(kObject_VRelease(output));
|
|
|
|
return kOK;
|
|
}
|
|
|
|
GoFx(kStatus) GoOutput_Read(GoOutput output, kXml xml, kXmlItem item)
|
|
{
|
|
kObjR(GoOutput, output);
|
|
kXmlItem ethernetItem = kNULL;
|
|
kXmlItem serialItem = kNULL;
|
|
kXmlItem digitalItem = kNULL;
|
|
kXmlItem analogItem = kNULL;
|
|
k32u i;
|
|
kString digitalString = kNULL;
|
|
|
|
obj->xml = xml;
|
|
obj->xmlItem = item;
|
|
|
|
kCheck(!kIsNull(ethernetItem = kXml_Child(xml, item, "Ethernet")));
|
|
kCheck(GoEthernet_Read(obj->ethernet, xml, ethernetItem));
|
|
|
|
kCheck(!kIsNull(serialItem = kXml_Child(xml, item, "Serial")));
|
|
kCheck(GoSerial_Read(obj->serial, xml, serialItem));
|
|
|
|
kCheck(!kIsNull(analogItem = kXml_Child(xml, item, "Analog")));
|
|
kCheck(GoAnalog_Read(obj->analog, xml, analogItem));
|
|
|
|
kTry
|
|
{
|
|
kTest(kString_Construct(&digitalString, "", kObject_Alloc(output)));
|
|
|
|
for (i = 0; i < kCountOf(obj->digital); ++i)
|
|
{
|
|
kTest(kString_Setf(digitalString, "Digital%u", i));
|
|
digitalItem = kXml_Child(xml, item, kString_Chars(digitalString));
|
|
kTest(!kIsNull(digitalItem));
|
|
kTest(GoDigital_Read(obj->digital[i], xml, digitalItem));
|
|
}
|
|
}
|
|
kFinally
|
|
{
|
|
kDestroyRef(&digitalString);
|
|
kEndFinally();
|
|
}
|
|
|
|
return kOK;
|
|
}
|
|
|
|
GoFx(kStatus) GoOutput_Write(GoOutput output, kXml xml, kXmlItem item)
|
|
{
|
|
kObjR(GoOutput, output);
|
|
kXmlItem ethernetItem = kNULL;
|
|
kXmlItem serialItem = kNULL;
|
|
kXmlItem digitalItem = kNULL;
|
|
kXmlItem analogItem = kNULL;
|
|
k32u i;
|
|
kString digitalString = kNULL;
|
|
|
|
if (kIsNull(obj->xml) || kIsNull(obj->xmlItem)) return kERROR_STATE;
|
|
|
|
kCheck(kXml_AddItem(xml, item, "Ethernet", ðernetItem));
|
|
kCheck(GoEthernet_Write(obj->ethernet, xml, ethernetItem));
|
|
|
|
kCheck(kXml_AddItem(xml, item, "Serial", &serialItem));
|
|
kCheck(GoSerial_Write(obj->serial, xml, serialItem));
|
|
|
|
kCheck(kXml_AddItem(xml, item, "Analog", &analogItem));
|
|
kCheck(GoAnalog_Write(obj->analog, xml, analogItem));
|
|
|
|
kTry
|
|
{
|
|
kTest(kString_Construct(&digitalString, "", kObject_Alloc(output)));
|
|
|
|
for (i = 0; i < kCountOf(obj->digital); ++i)
|
|
{
|
|
kTest(kString_Setf(digitalString, "Digital%u", i));
|
|
kTest(kXml_AddItem(xml, item, kString_Chars(digitalString), &digitalItem));
|
|
kTest(GoDigital_Write(obj->digital[i], xml, digitalItem));
|
|
}
|
|
}
|
|
kFinally
|
|
{
|
|
kDestroyRef(&digitalString);
|
|
kEndFinally();
|
|
}
|
|
|
|
//Forwards Compatibility
|
|
kCheck(GoUtils_XmlMerge(obj->xml, obj->xmlItem, xml, item));
|
|
|
|
return kOK;
|
|
}
|
|
|
|
GoFx(GoEthernet) GoOutput_Ethernet(GoOutput output)
|
|
{
|
|
kObjR(GoOutput, output);
|
|
return obj->ethernet;
|
|
}
|
|
|
|
GoFx(k32u) GoOutput_EthernetCount(GoOutput output)
|
|
{
|
|
kObjR(GoOutput, output);
|
|
kObjNR(GoEthernet, ethernet, obj->ethernet);
|
|
return (k32u) ethernet->outputUsed;
|
|
}
|
|
|
|
GoFx(GoEthernet) GoOutput_EthernetAt(GoOutput output, kSize index)
|
|
{
|
|
kObjR(GoOutput, output);
|
|
kAssert(index < GoOutput_EthernetCount(output));
|
|
return obj->ethernet;
|
|
}
|
|
|
|
GoFx(GoSerial) GoOutput_Serial(GoOutput output)
|
|
{
|
|
kObjR(GoOutput, output);
|
|
return obj->serial;
|
|
}
|
|
|
|
GoFx(k32u) GoOutput_SerialCount(GoOutput output)
|
|
{
|
|
kObjR(GoOutput, output);
|
|
kObjNR(GoSerial, serial, obj->serial);
|
|
return (k32u) serial->outputUsed;
|
|
}
|
|
|
|
GoFx(GoSerial) GoOutput_SerialAt(GoOutput output, kSize index)
|
|
{
|
|
kObjR(GoOutput, output);
|
|
kAssert(index < GoOutput_SerialCount(output));
|
|
return obj->serial;
|
|
}
|
|
|
|
GoFx(k32u) GoOutput_DigitalCount(GoOutput output)
|
|
{
|
|
kObjR(GoOutput, output);
|
|
kObjNR(GoDigital, digital, kNULL);
|
|
k32u i, numEnabled = 0;
|
|
|
|
for (i = 0; i < kCountOf(obj->digital); i++){
|
|
digital = obj->digital[i];
|
|
if (digital->outputUsed){
|
|
numEnabled++;
|
|
}
|
|
}
|
|
return numEnabled;
|
|
}
|
|
|
|
GoFx(GoDigital) GoOutput_DigitalAt(GoOutput output, kSize index)
|
|
{
|
|
kObjR(GoOutput, output);
|
|
kAssert(index < GoOutput_DigitalCount(output));
|
|
return obj->digital[index];
|
|
}
|
|
|
|
GoFx(GoAnalog) GoOutput_Analog(GoOutput output)
|
|
{
|
|
kObjR(GoOutput, output);
|
|
return obj->analog;
|
|
}
|
|
|
|
GoFx(k32u) GoOutput_AnalogCount(GoOutput output)
|
|
{
|
|
kObjR(GoOutput, output);
|
|
kObjNR(GoAnalog, analog, obj->analog);
|
|
return (k32u) analog->outputUsed;
|
|
}
|
|
|
|
GoFx(GoAnalog) GoOutput_AnalogAt(GoOutput output, kSize index)
|
|
{
|
|
kObjR(GoOutput, output);
|
|
kAssert(index < GoOutput_AnalogCount(output));
|
|
return obj->analog;
|
|
}
|