Open mejohnnaylor opened 4 weeks ago
each type definition needs to have some bolt-on static methods to assist with serialization and deserialization thus:
struct FieldSpec {
std::string name;
std::ptr_diff_max_t offset
};
using FieldInfo = std::vector<FieldSpec>;
// this code is generated by cppgen
//
struct MyType {
int a_number;
float another_number;
using Fieldtypes = catena::Typelist<int, float>;
static FieldInfo field_info = {
"a_number", std::offsetof (MyType, a_number),
"another_number, std::offsetof (MyType, another_number)
},
static fromClient (void* dst, const catena::Value& v) {
char* base = static_cast<char*>(dst); // so our pointer math works
uint_t idx = 0;
for (f : field_info) {
if (v.has_field(f.name)) { // can't remember the actual call to make but you get the idea
*reinterpret_cast<Fieldtypes<idx>*>(base + f.offset) = v.field_value(f.name); //
}
idx++;
}
}
static toClient (catena::Value& dst, const void* src) {
const char* base = static_cast<const char*>(src); // so our pointer math works
uint32_t idx = 0;
for (f : field_info) {
v.field_value(f.name) = *reinterpret_cast<const Fieldtypes<idx>*>(dst + f.offset);
idx++;
}
}
};
correction usage of Fieldtypes<idx>
should be...
catena::meta::Typelist Types<int, float>;
*reinterpret_cast<catena::meta::NthElement<Types, idx>*>(base + f.offset) = v.field_value(f.name);
we could also put this as a handy operator
template <typename T>
T& operator[](const std::string& fieldname) {
return *(base + fieldinfo[fieldname]);
}
client code in business logic...
Location& loc = device_model.getRef("/location");
loc = {0,1};
float& lat = device_model.getRef("/location/latitude");
// above first calls device_model's getRef method, then the Location type's getRef method.
lat = 45.0;
obviously this presents thread safety issues so we still need setValue, getValue for the biz logic to use that asserts a lock.
idea: process the JSON definition of a device model to create C++ data structure that matches the state of the model.
let's start with some simple examples
say we're authoring our device in a folder called
example
this would produce a C++ header
example_state.h
thus:business logic would then have trivial access to the state
but what about constraints, names etc?
One way to tackle this would be to have a
ParamAccessor
class (not too fussy about the name, there could be better ones)More complex scenario
This introduces the need for a user defined type in the C++ code...
example.h
againSome rules
Conversion mappings