diff --git a/core/src/objects/base/instance.cpp b/core/src/objects/base/instance.cpp index 1cd287d..9f6e5d5 100644 --- a/core/src/objects/base/instance.cpp +++ b/core/src/objects/base/instance.cpp @@ -25,13 +25,23 @@ const InstanceType Instance::TYPE = { // return &TYPE_; // } +constexpr FieldCodec classNameCodec() { + return FieldCodec { + .write = nullptr, + .read = [](void* source) -> Data::Variant { + return Data::String(((const InstanceType*)source)->className); + }, + }; +} + Instance::Instance(const InstanceType* type) { this->name = type->className; this->memberMap = std::make_unique( MemberMap { .super = std::nullopt, .members = { - { "Name", { .backingField = &name, .type = &Data::String::TYPE, .codec = fieldCodecOf() } } + { "Name", { .backingField = &name, .type = &Data::String::TYPE, .codec = fieldCodecOf() } }, + { "ClassName", { .backingField = const_cast(type), .type = &Data::String::TYPE, .codec = classNameCodec(), .flags = PROP_READONLY } }, } }); } @@ -156,7 +166,7 @@ auto meta = GetPropertyMeta(name); tl::expected Instance::SetPropertyValue(std::string name, Data::Variant value) { auto meta = GetPropertyMeta(name); - if (!meta) return tl::make_unexpected(MemberNotFound()); + if (!meta || meta->flags & PROP_READONLY) return tl::make_unexpected(MemberNotFound()); meta->codec.write(value, meta->backingField); if (meta->updateCallback) meta->updateCallback.value()(name); diff --git a/core/src/objects/base/member.h b/core/src/objects/base/member.h index 5306eab..b0a1ecf 100644 --- a/core/src/objects/base/member.h +++ b/core/src/objects/base/member.h @@ -48,11 +48,12 @@ enum PropertyFlags { PROP_HIDDEN = 1 << 0, // Hidden from the editor PROP_NOSAVE = 1 << 1, // Do not serialize PROP_UNIT_FLOAT = 1 << 2, // Float between 0 and 1 + PROP_READONLY = 1 << 3, // Read only property, do not write }; enum PropertyCategory { - PROP_CATEGORY_DATA, PROP_CATEGORY_APPEARENCE, + PROP_CATEGORY_DATA, PROP_CATEGORY_BEHAVIOR, PROP_CATEGORY_PART, PROP_CATEGORY_SURFACE,