#include #include #include using namespace structive; struct Device : Property_Object { double temperature{25.0}; double pressure{101.3}; double min_speed{10.0}; double max_speed{100.0}; std::string name{"device-1"}; }; template <> struct structive::Type_Descriptor { static auto get() { return object( defaults(external_access, persistence_access), synchronization(sync_all_independent, sync_group<&Device::min_speed, &Device::max_speed>("speed_range")), field<&Device::temperature>(key<"temperature">, unit<"C">, min_value<-50.0>, max_value<200.0>), field<&Device::pressure>(key<"pressure">, unit<"kPa">), field<&Device::min_speed>(key<"min_speed">), field<&Device::max_speed>(key<"max_speed">), field<&Device::name>(key<"name">) ); } }; static bool update_speed_range(Device& device, double min_speed, double max_speed) { auto guard = device.lock_unique<&Device::min_speed, &Device::max_speed>(); auto old_min = guard.get<&Device::min_speed>(); auto old_max = guard.get<&Device::max_speed>(); guard.set < &Device::min_speed > (min_speed); guard.set < &Device::max_speed > (max_speed); if (min_speed <= max_speed) { return true; } guard.set < &Device::min_speed > (old_min); guard.set < &Device::max_speed > (old_max); return false; } int main() { Device device; device.external().write < &Device::temperature > (30.0); std::cout << "temperature=" << device.external().read<&Device::temperature>() << '\n'; std::cout << "temperature lock slot=" << device.lock_slot<&Device::temperature>() << '\n'; std::cout << "min/max shared slot=" << device.lock_slot<&Device::min_speed>() << '\n'; std::cout << "max_speed key=" << device.schema().property<&Device::max_speed>().key() << '\n'; if (!update_speed_range(device, 120.0, 80.0)) { std::cout << "invalid range rolled back by business logic\n"; } device.temperature = 31.0; std::cout << "raw temperature=" << device.temperature << '\n'; }