// // MultiConfigurable.cpp // Clock Signal // // Created by Thomas Harte on 09/02/2018. // Copyright 2018 Thomas Harte. All rights reserved. // #include "MultiConfigurable.hpp" #include using namespace Analyser::Dynamic; namespace { class MultiStruct: public Reflection::Struct { public: MultiStruct(const std::vector &devices) : devices_(devices) { for(auto device: devices) { options_.emplace_back(device->get_options()); } } void apply() { auto options = options_.begin(); for(auto device: devices_) { device->set_options(*options); ++options; } } std::vector all_keys() const final { std::set keys; for(auto &options: options_) { const auto new_keys = options->all_keys(); keys.insert(new_keys.begin(), new_keys.end()); } return std::vector(keys.begin(), keys.end()); } std::vector values_for(const std::string &name) const final { std::set values; for(auto &options: options_) { const auto new_values = options->values_for(name); values.insert(new_values.begin(), new_values.end()); } return std::vector(values.begin(), values.end()); } const std::type_info *type_of(const std::string &name) const final { for(auto &options: options_) { auto info = options->type_of(name); if(info) return info; } return nullptr; } size_t count_of(const std::string &name) const final { for(auto &options: options_) { auto info = options->type_of(name); if(info) return options->count_of(name); } return 0; } const void *get(const std::string &name) const final { for(auto &options: options_) { auto value = options->get(name); if(value) return value; } return nullptr; } void *get(const std::string &name) final { for(auto &options: options_) { auto value = options->get(name); if(value) return value; } return nullptr; } void set(const std::string &name, const void *value, size_t offset) final { const auto safe_type = type_of(name); if(!safe_type) return; // Set this property only where the child's type is the same as that // which was returned from here for type_of. for(auto &options: options_) { const auto type = options->type_of(name); if(!type) continue; if(*type == *safe_type) { options->set(name, value, offset); } } } private: const std::vector &devices_; std::vector> options_; }; } MultiConfigurable::MultiConfigurable(const std::vector> &machines) { for(const auto &machine: machines) { Configurable::Device *device = machine->configurable_device(); if(device) devices_.push_back(device); } } void MultiConfigurable::set_options(const std::unique_ptr &str) { const auto options = dynamic_cast(str.get()); options->apply(); } std::unique_ptr MultiConfigurable::get_options() { return std::make_unique(devices_); }