mirror of
https://github.com/TomHarte/CLK.git
synced 2025-02-06 13:31:55 +00:00
Starts to build an easy set
interface.
This commit is contained in:
parent
f27e0a141d
commit
1a2872c815
@ -51,9 +51,6 @@ namespace {
|
||||
|
||||
constexpr int CLOCK_RATE = 7833600;
|
||||
|
||||
|
||||
Analyser::Static::Macintosh::Target nothing;
|
||||
|
||||
}
|
||||
|
||||
namespace Apple {
|
||||
|
@ -39,6 +39,9 @@
|
||||
|
||||
namespace {
|
||||
|
||||
/// Takes an enum-style camel-case string (e.g. Mac128k) and
|
||||
//std::string
|
||||
|
||||
struct MachineRunner {
|
||||
MachineRunner() {
|
||||
frame_lock_.clear();
|
||||
|
@ -15,6 +15,8 @@
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include "Enum.h"
|
||||
|
||||
namespace Reflection {
|
||||
|
||||
#define DeclareField(Name) declare(&Name, #Name)
|
||||
@ -22,9 +24,75 @@ namespace Reflection {
|
||||
struct Struct {
|
||||
virtual std::vector<std::string> all_keys() = 0;
|
||||
virtual const std::type_info *type_of(const std::string &name) = 0;
|
||||
virtual void set(const std::string &name, const void *value) = 0;
|
||||
virtual const void *get(const std::string &name) = 0;
|
||||
virtual void set_raw(const std::string &name, const void *value) = 0;
|
||||
virtual const void *get_raw(const std::string &name) = 0;
|
||||
virtual ~Struct() {}
|
||||
|
||||
/*!
|
||||
Attempts to set the property @c name to @c value ; will perform limited type conversions.
|
||||
|
||||
@returns @c true if t
|
||||
*/
|
||||
template <typename Type> bool set(const std::string &name, Type value) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/*!
|
||||
Setting an int:
|
||||
|
||||
* to an int copies the int;
|
||||
* to an int64_t promotes the int; and
|
||||
* to a registered enum, copies the int.
|
||||
*/
|
||||
template <> bool set(const std::string &name, int value) {
|
||||
const auto target_type = type_of(name);
|
||||
if(!target_type) return false;
|
||||
|
||||
// No need to convert an int or a registered enum.
|
||||
if(*target_type == typeid(int) || !Reflection::Enum::name(*target_type).empty()) {
|
||||
set_raw(name, &value);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Promote to an int64_t.
|
||||
if(*target_type == typeid(int64_t)) {
|
||||
const auto int64 = int64_t(value);
|
||||
set_raw(name, &int64);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*!
|
||||
Setting a string:
|
||||
|
||||
* to an enum, if the string names a member of the enum, sets the value.
|
||||
*/
|
||||
template <> bool set(const std::string &name, const std::string &value) {
|
||||
const auto target_type = type_of(name);
|
||||
if(!target_type) return false;
|
||||
|
||||
if(Reflection::Enum::name(*target_type).empty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto enum_value = Reflection::Enum::from_string(*target_type, value);
|
||||
if(enum_value == std::string::npos) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int int_value = int(enum_value);
|
||||
set_raw(name, &int_value);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <> bool set(const std::string &name, const char *value) {
|
||||
const std::string string(value);
|
||||
return set<const std::string &>(name, string);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
struct Serialisable {
|
||||
@ -35,13 +103,13 @@ struct Serialisable {
|
||||
virtual bool deserialise(const std::vector<uint8_t> &source) = 0;
|
||||
};
|
||||
|
||||
template <typename Owner> class StructImpl: public Struct, public Serialisable {
|
||||
template <typename Owner> class StructImpl: public Struct {
|
||||
public:
|
||||
/*!
|
||||
@returns the value of type @c Type that is loaded from the offset registered for the field @c name.
|
||||
It is the caller's responsibility to provide an appropriate type of data.
|
||||
*/
|
||||
const void *get(const std::string &name) final {
|
||||
const void *get_raw(const std::string &name) final {
|
||||
const auto iterator = contents_.find(name);
|
||||
if(iterator == contents_.end()) return nullptr;
|
||||
return reinterpret_cast<uint8_t *>(this) + iterator->second.offset;
|
||||
@ -52,7 +120,7 @@ template <typename Owner> class StructImpl: public Struct, public Serialisable {
|
||||
|
||||
It is the caller's responsibility to provide an appropriate type of data.
|
||||
*/
|
||||
void set(const std::string &name, const void *value) final {
|
||||
void set_raw(const std::string &name, const void *value) final {
|
||||
const auto iterator = contents_.find(name);
|
||||
if(iterator == contents_.end()) return;
|
||||
memcpy(reinterpret_cast<uint8_t *>(this) + iterator->second.offset, value, iterator->second.size);
|
||||
|
Loading…
x
Reference in New Issue
Block a user