/* * DeviceModule.cc * * Created on: Jun 27, 2016 * Author: Martin Hierholzer */ #include <ChimeraTK/DeviceBackend.h> #include <ChimeraTK/Device.h> #include "Application.h" #include "DeviceModule.h" namespace ChimeraTK { DeviceModule::DeviceModule(const std::string& _deviceAliasOrURI, const std::string& _registerNamePrefix) : Module(&(Application::getInstance()), "Device:"+_deviceAliasOrURI+":"+_registerNamePrefix, ""), deviceAliasOrURI(_deviceAliasOrURI), registerNamePrefix(_registerNamePrefix) {} /*********************************************************************************************************************/ VariableNetworkNode DeviceModule::operator()(const std::string& registerName, UpdateMode mode, const std::type_info &valueType, size_t nElements) const { return {registerName, deviceAliasOrURI, registerNamePrefix/registerName, mode, VariableDirection::invalid, valueType, nElements}; } /*********************************************************************************************************************/ Module& DeviceModule::operator[](const std::string& moduleName) const { if(subModules.count(moduleName) == 0) { subModules[moduleName] = {deviceAliasOrURI, registerNamePrefix/moduleName}; } return subModules[moduleName]; } /*********************************************************************************************************************/ const Module& DeviceModule::virtualise() const { return *this; } /*********************************************************************************************************************/ void DeviceModule::connectTo(const Module &target, VariableNetworkNode trigger) const { auto &cat = virtualiseFromCatalog(); cat.connectTo(target, trigger); } /*********************************************************************************************************************/ VirtualModule& DeviceModule::virtualiseFromCatalog() const { if(virtualisedModuleFromCatalog_isValid) return virtualisedModuleFromCatalog; virtualisedModuleFromCatalog = VirtualModule(deviceAliasOrURI, "Device module", ModuleType::Device); // obtain register catalogue Device d; d.open(deviceAliasOrURI); /// @todo: do not actually open the device (needs extension of DeviceAccess)! auto catalog = d.getRegisterCatalogue(); // iterate catalogue, create VariableNetworkNode for all registers starting with the registerNamePrefix size_t prefixLength = registerNamePrefix.length(); for(auto ® : catalog) { if(std::string(reg.getRegisterName()).substr(0,prefixLength) != std::string(registerNamePrefix)) continue; // ignore 2D registers if(reg.getNumberOfDimensions() > 1) continue; // guess direction and determine update mode VariableDirection direction; UpdateMode updateMode; if(reg.isWriteable()) { direction = VariableDirection::consuming; updateMode = UpdateMode::push; } else { direction = VariableDirection::feeding; if(reg.getSupportedAccessModes().has(AccessMode::wait_for_new_data)) { updateMode = UpdateMode::push; } else { updateMode = UpdateMode::poll; } } // guess type const std::type_info *valTyp{&typeid(AnyType)}; auto &dd = reg.getDataDescriptor(); //numeric, string, boolean, nodata, undefined if(dd.fundamentalType() == RegisterInfo::FundamentalType::numeric) { if(dd.isIntegral()) { if(dd.isSigned()) { if(dd.nDigits() > 11) { valTyp = &typeid(int64_t); } else if(dd.nDigits() > 6) { valTyp = &typeid(int32_t); } else if(dd.nDigits() > 4) { valTyp = &typeid(int16_t); } else { valTyp = &typeid(int8_t); } } else { if(dd.nDigits() > 10) { valTyp = &typeid(uint64_t); } else if(dd.nDigits() > 5) { valTyp = &typeid(uint32_t); } else if(dd.nDigits() > 3) { valTyp = &typeid(uint16_t); } else { valTyp = &typeid(uint8_t); } } } else { // fractional valTyp = &typeid(double); } } else if(dd.fundamentalType() == RegisterInfo::FundamentalType::boolean) { valTyp = &typeid(int32_t); } else if(dd.fundamentalType() == RegisterInfo::FundamentalType::string) { valTyp = &typeid(std::string); } auto name = std::string(reg.getRegisterName()).substr(prefixLength); VariableNetworkNode node(name, deviceAliasOrURI, reg.getRegisterName(), updateMode, direction, *valTyp, reg.getNumberOfElements()); virtualisedModuleFromCatalog.getAccessorList().push_back(node); } virtualisedModuleFromCatalog_isValid = true; return virtualisedModuleFromCatalog; } }