diff --git a/autogen/src/analysis.cpp b/autogen/src/analysis.cpp index 4d887a5..6a8d204 100644 --- a/autogen/src/analysis.cpp +++ b/autogen/src/analysis.cpp @@ -24,7 +24,8 @@ std::map parseAnnotationString(std::string src) { int i = 0; for (; i < src.length(); i++) { - if (src[i] == ' ' && (stage != 2 || !quoted)) continue; // Ignore spaces if not in stage 2 and quoted + if (src[i] == ' ' && (stage != 2 || !quoted)) continue; // Ignore spaces if not in stage 2 and quoted + if (src[i] == ',' && stage == 0) continue; // Let empty commas slip by if (stage < 2 && (src[i] >= 'a' && src[i] <= 'z' || src[i] >= 'A' && src[i] <= 'Z' || src[i] >= '0' && src[i] <= '9' || src[i] == '_')) { currentIdent += src[i]; stage = 1; @@ -228,6 +229,8 @@ void processClass(CXCursor cur, AnalysisState* state, std::string className, std if (result.count("hidden")) anly.flags = anly.flags | ClassFlag_Hidden; + anly.abstract = result.count("abstract") > 0; + anly.explorerIcon = result["explorer_icon"]; // Find annotated fields diff --git a/autogen/src/analysis.h b/autogen/src/analysis.h index 88e4319..2bc778c 100644 --- a/autogen/src/analysis.h +++ b/autogen/src/analysis.h @@ -46,6 +46,7 @@ struct ClassAnalysis { std::string name; std::string baseClass; std::string headerPath; + bool abstract = false; std::vector properties; ClassFlags flags = (ClassFlags)0; std::string explorerIcon; diff --git a/autogen/src/codegen.cpp b/autogen/src/codegen.cpp index bef3ea4..11d3af8 100644 --- a/autogen/src/codegen.cpp +++ b/autogen/src/codegen.cpp @@ -18,6 +18,7 @@ std::map MAPPED_TYPE = { { "float", "Data::Float" }, { "std::string", "Data::String" }, { "std::weak_ptr", "Data::InstanceRef" }, + { "std::weak_ptr", "Data::InstanceRef" }, { "glm::vec3", "Vector3" }, }; @@ -57,7 +58,7 @@ void writePropertySetHandler(std::ofstream& out, ClassAnalysis state) { out << (first ? "" : " else ") << "if (name == \"" << prop.name << "\") {"; if (prop.flags & PropertyFlag_Readonly) { - out << "\n return AssignToReadOnlyMember(\"" << state.name << "\", name)"; + out << "\n return AssignToReadOnlyMember(GetClass()->className, name)"; } else if (prop.cframeMember == CFrameMember_Position) { out << "\n this->" << prop.fieldName << " = this->" << prop.fieldName << ".Rotation() + value.get();"; } else if (prop.cframeMember == CFrameMember_Rotation) { @@ -72,7 +73,8 @@ void writePropertySetHandler(std::ofstream& out, ClassAnalysis state) { first = false; } - out << "\n return MemberNotFound(\"" << state.name << "\", name);"; + out << "\n return " << state.baseClass << "::InternalSetPropertyValue(name, value);"; + // out << "\n return MemberNotFound(\"" << state.name << "\", name);"; out << "\n};\n\n"; } @@ -97,11 +99,23 @@ void writePropertyGetHandler(std::ofstream& out, ClassAnalysis state) { first = false; } - out << "\n return MemberNotFound(\"" << state.name << "\", name);"; + out << "\n return " << state.baseClass << "::InternalGetPropertyValue(name);"; + // out << "\n return MemberNotFound(\"" << state.name << "\", name);"; out << "\n};\n\n"; } +void writePropertiesList(std::ofstream& out, ClassAnalysis state) { + out << "std::vector " << state.name << "::InternalGetProperties() {\n"; + out << " std::vector properties = " << state.baseClass << "::InternalGetProperties();\n"; + + for (auto& prop : state.properties) { + out << " properties.push_back(\"" << prop.name << "\")l\n"; + } + + out << "};\n\n"; +} + void writePropertyMetaHandler(std::ofstream& out, ClassAnalysis state) { out << "result " << state.name << "::InternalGetPropertyMeta(std::string name) {"; @@ -135,7 +149,8 @@ void writePropertyMetaHandler(std::ofstream& out, ClassAnalysis state) { first = false; } - out << "\n return MemberNotFound(\"" << state.name << "\", name);"; + out << "\n return " << state.baseClass << "::InternalGetPropertyMeta(name);"; + // out << "\n return MemberNotFound(\"" << state.name << "\", name);"; out << "\n};\n\n"; } @@ -143,7 +158,7 @@ void writePropertyMetaHandler(std::ofstream& out, ClassAnalysis state) { void writeCodeForClass(std::ofstream& out, ClassAnalysis& state) { std::string strFlags; if (state.flags & ClassFlag_NotCreatable) - strFlags += " | INSTANCE_NOT_CREATABLE"; + strFlags += " | INSTANCE_NOTCREATABLE"; if (state.flags & ClassFlag_Service) strFlags += " | INSTANCE_SERVICE"; if (state.flags & ClassFlag_Hidden) @@ -155,11 +170,15 @@ void writeCodeForClass(std::ofstream& out, ClassAnalysis& state) { out << "// This file was automatically generated by autogen, and should not be edited manually //\n"; out << "/////////////////////////////////////////////////////////////////////////////////////////\n\n"; + std::string constructorStr; + if (state.abstract) constructorStr = "nullptr"; + else constructorStr = "&" + state.name + "::Create"; + out << "#include \"" << state.headerPath << "\"\n\n"; out << "const InstanceType " << state.name << "::TYPE = {\n" << " .super = &" << state.baseClass << "::TYPE,\n" << " .className = \"" << state.name << "\",\n" - << " .constructor = &" << state.name << "::CreateGeneric,\n" + << " .constructor = " << constructorStr << ",\n" << " .explorerIcon = \"" << state.explorerIcon << "\",\n" << " .flags = " << strFlags << ",\n" << "};\n\n"; @@ -168,6 +187,9 @@ void writeCodeForClass(std::ofstream& out, ClassAnalysis& state) { << " return &TYPE;\n" << "};\n\n"; + // Special case for our Service class + if (state.baseClass == "Service") state.baseClass = "Instance"; + writePropertySetHandler(out, state); writePropertyGetHandler(out, state); writePropertyMetaHandler(out, state); diff --git a/autogen/src/main.cpp b/autogen/src/main.cpp index 6439db9..9bf0475 100644 --- a/autogen/src/main.cpp +++ b/autogen/src/main.cpp @@ -71,6 +71,7 @@ int main(int argc, char** argv) { } printf("[AUTOGEN] Generating cpp files...\n"); + fs::create_directories(argv[3]); // Make sure generated dir exists before we try writing to it for (auto& [_, clazz] : state.classes) { fs::path outPath = fs::path(argv[3]) / ("class_" + clazz.name + ".cpp"); std::ofstream outStream(outPath); @@ -79,6 +80,20 @@ int main(int argc, char** argv) { outStream.close(); } + // // Write __all__.cpp file + // fs::path outPath = fs::path(argv[3]) / "__all__.cpp"; + // std::ofstream outStream(outPath); + + // // TODO: replace these with just direct filenames that can be converted by + // // CMake itself + // for (auto& [_, clazz] : state.classes) { + // std::string includeName = "class_" + clazz.name + ".cpp"; + + // outStream << "#include \"" << includeName << "\"\n"; + // } + + // outStream.close(); + flushCaches(argv[3]); } \ No newline at end of file diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index 5e2f6b1..be55604 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -20,7 +20,7 @@ add_custom_target(build_autogen ALL COMMAND "${CMAKE_BINARY_DIR}/autogen/autogen" "${CMAKE_CURRENT_SOURCE_DIR}/src" "${CMAKE_CURRENT_SOURCE_DIR}/src/objects" "${CMAKE_BINARY_DIR}/generated" ) -file(GLOB_RECURSE SOURCES "src/*.cpp" "src/*.h" "${CMAKE_BINARY_DIR}/generated/*.cpp") +file(GLOB_RECURSE SOURCES "src/*.cpp" "src/*.h" "${CMAKE_BINARY_DIR}/generated/__all__.cpp") add_library(openblocks STATIC ${SOURCES}) set_target_properties(openblocks PROPERTIES OUTPUT_NAME "openblocks") target_link_libraries(openblocks ${GLEW_LIBRARIES} ${LUAJIT_LIBRARIES} OpenGL::GL ReactPhysics3D::ReactPhysics3D pugixml::pugixml) diff --git a/core/src/objects/annotation.h b/core/src/objects/annotation.h index be7e8b7..50e6f15 100644 --- a/core/src/objects/annotation.h +++ b/core/src/objects/annotation.h @@ -4,6 +4,9 @@ #ifdef __AUTOGEN__ #define def_inst(...) clang::annotate("OB::def_inst", #__VA_ARGS__) +#define INSTANCE [[ def_inst() ]] +#define INSTANCE_WITH(...) [[ def_inst(__VA_ARGS__) ]] +#define INSTANCE_SERVICE(...) [[ def_inst(__VA_ARGS__, service) ]] #define def_prop(...) clang::annotate("OB::def_prop", #__VA_ARGS__) @@ -11,14 +14,18 @@ #define cframe_rotation_prop(...) clang::annotate("OB::cframe_rotation_prop", #__VA_ARGS__) #else #define def_inst(...) +#define INSTANCE +#define INSTANCE_WITH(...) +#define INSTANCE_SERVICE(...) #define def_prop(...) #define cframe_position_prop(...) #define cframe_rotation_prop(...) #endif #define AUTOGEN_PREAMBLE \ -private: \ +protected: \ result InternalGetPropertyMeta(std::string name) override; \ fallible InternalSetPropertyValue(std::string name, Data::Variant value) override; \ result InternalGetPropertyValue(std::string name) override; \ +std::vector InternalGetProperties() override; \ private: diff --git a/core/src/objects/base/instance.cpp b/core/src/objects/base/instance.cpp index 34983f3..7fcf768 100644 --- a/core/src/objects/base/instance.cpp +++ b/core/src/objects/base/instance.cpp @@ -43,15 +43,6 @@ constexpr FieldCodec classNameCodec() { 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() } }, - { "Parent", { .backingField = &parent, .type = &Data::InstanceRef::TYPE, .codec = fieldCodecOf>() } }, - { "ClassName", { .backingField = const_cast(type), .type = &Data::String::TYPE, .codec = classNameCodec(), .flags = (PropertyFlags)(PROP_READONLY | PROP_NOSAVE) } }, - } - }); } Instance::~Instance () { @@ -195,83 +186,66 @@ void Instance::OnWorkspaceRemoved(std::shared_ptr oldWorkspace) { // Properties result Instance::GetPropertyValue(std::string name) { - auto meta_ = GetPropertyMeta(name); - if (!meta_) return MemberNotFound(GetClass()->className, name); - auto meta = meta_.expect(); - - return meta.codec.read(meta.backingField); + return InternalGetPropertyValue(name); } fallible Instance::SetPropertyValue(std::string name, Data::Variant value) { - // Handle special case: Parent - if (name == "Parent") { - Data::InstanceRef ref = value.get(); - std::weak_ptr inst = ref; - SetParent(inst.expired() ? std::nullopt : std::make_optional(inst.lock())); - return {}; - } - - if (InternalSetPropertyValue(name, value).isSuccess()) - return {}; - - auto meta_ = GetPropertyMeta(name); - if (!meta_) return MemberNotFound(GetClass()->className, name); - auto meta = meta_.expect(); - if (meta.flags & PROP_READONLY) AssignToReadOnlyMember(GetClass()->className, name); - - meta.codec.write(value, meta.backingField); - if (meta.updateCallback) meta.updateCallback.value()(name); - sendPropertyUpdatedSignal(shared_from_this(), name, value); - - return {}; + auto result = InternalSetPropertyValue(name, value); + if (result.isSuccess()) sendPropertyUpdatedSignal(shared_from_this(), name, value); + return result; } result Instance::GetPropertyMeta(std::string name) { - MemberMap* current = &*memberMap; - while (true) { - // We look for the property in current member map - auto it = current->members.find(name); - - // It is found, return it - if (it != current->members.end()) - return it->second; - - // It is not found, If there are no other maps to search, return null - if (!current->super.has_value()) - return MemberNotFound(GetClass()->className, name); - - // Search in the parent - current = current->super->get(); - } + return InternalGetPropertyMeta(name); } -result Instance::InternalGetPropertyValue(std::string name) { return MemberNotFound(GetClass()->className, name); } -fallible Instance::InternalSetPropertyValue(std::string name, Data::Variant value) { return MemberNotFound(GetClass()->className, name); } +result Instance::InternalGetPropertyValue(std::string name) { + if (name == "Name") { + return Data::Variant(Data::String(this->name)); + } else if (name == "Parent") { + return Data::Variant(Data::InstanceRef(this->parent)); + } else if (name == "ClassName") { + return Data::Variant(Data::String(GetClass()->className)); + } + return MemberNotFound(GetClass()->className, name); +} + +fallible Instance::InternalSetPropertyValue(std::string name, Data::Variant value) { + if (name == "Name") { + this->name = (std::string)value.get(); + } else if (name == "Parent") { + std::weak_ptr ref = value.get(); + SetParent(ref.expired() ? std::nullopt : std::make_optional(ref.lock())); + } else if (name == "ClassName") { + return AssignToReadOnlyMember(GetClass()->className, name); + } + return MemberNotFound(GetClass()->className, name); +} + +std::vector Instance::InternalGetProperties() { + std::vector members; + members.push_back("Name"); + members.push_back("Parent"); + members.push_back("ClassName"); + return members; +} + result Instance::InternalGetPropertyMeta(std::string name) { return MemberNotFound(GetClass()->className, name); } void Instance::UpdateProperty(std::string name) { - PropertyMeta meta = GetPropertyMeta(name).expect(); - if (!meta.updateCallback) return; // Nothing to update, exit. - meta.updateCallback.value()(name); + // TODO: temporary workaround because I'm too lazy to implement this in autogen + InternalSetPropertyValue(name, InternalGetPropertyValue(name).expect()).expect(); + + // PropertyMeta meta = GetPropertyMeta(name).expect(); + // if (!meta.updateCallback) return; // Nothing to update, exit. + // meta.updateCallback.value()(name); } std::vector Instance::GetProperties() { if (cachedMemberList.has_value()) return cachedMemberList.value(); - std::vector memberList; - - MemberMap* current = &*memberMap; - do { - for (auto const& [key, _] : current->members) { - // Don't add it if it's already in the list - if (std::find(memberList.begin(), memberList.end(), key) == memberList.end()) - memberList.push_back(key); - } - if (!current->super.has_value()) - break; - current = &*current->super.value(); - } while (true); + std::vector memberList = InternalGetProperties(); cachedMemberList = memberList; return memberList; diff --git a/core/src/objects/base/instance.h b/core/src/objects/base/instance.h index 0fcb997..254591a 100644 --- a/core/src/objects/base/instance.h +++ b/core/src/objects/base/instance.h @@ -65,7 +65,6 @@ private: friend JointInstance; // This isn't ideal, but oh well protected: bool parentLocked = false; - std::unique_ptr memberMap; Instance(const InstanceType*); virtual ~Instance(); @@ -73,6 +72,7 @@ protected: virtual result InternalGetPropertyValue(std::string name); virtual fallible InternalSetPropertyValue(std::string name, Data::Variant value); virtual result InternalGetPropertyMeta(std::string name); + virtual std::vector InternalGetProperties(); virtual void OnParentUpdated(std::optional> oldParent, std::optional> newParent); virtual void OnAncestryChanged(std::optional> child, std::optional> newParent); diff --git a/core/src/objects/base/member.h b/core/src/objects/base/member.h index 2f4dc97..0318165 100644 --- a/core/src/objects/base/member.h +++ b/core/src/objects/base/member.h @@ -66,9 +66,4 @@ struct PropertyMeta { PropertyCategory category = PROP_CATEGORY_DATA; }; -typedef std::variant MemberMeta; - -struct MemberMap { - std::optional> super; - std::map members; -}; \ No newline at end of file +typedef std::variant MemberMeta; \ No newline at end of file diff --git a/core/src/objects/datamodel.cpp b/core/src/objects/datamodel.cpp index 1469b6e..543810a 100644 --- a/core/src/objects/datamodel.cpp +++ b/core/src/objects/datamodel.cpp @@ -13,16 +13,6 @@ #include #include -const InstanceType DataModel::TYPE = { - .super = &Instance::TYPE, - .className = "DataModel", - .constructor = nullptr, -}; - -const InstanceType* DataModel::GetClass() { - return &TYPE; -} - DataModel::DataModel() : Instance(&TYPE) { this->name = "Place"; diff --git a/core/src/objects/datamodel.h b/core/src/objects/datamodel.h index 3ff6eac..c9719d0 100644 --- a/core/src/objects/datamodel.h +++ b/core/src/objects/datamodel.h @@ -2,6 +2,7 @@ #include "error/instance.h" #include "error/result.h" +#include "objects/annotation.h" #include "objects/base/instance.h" #include "objects/base/refstate.h" #include @@ -12,7 +13,8 @@ class DataModel; class Service; // The root instance to all objects in the hierarchy -class DataModel : public Instance { +class INSTANCE_WITH(abstract) DataModel : public Instance { + AUTOGEN_PREAMBLE private: void DeserializeService(pugi::xml_node node); static void cloneService(std::shared_ptr target, std::shared_ptr, RefState<_RefStatePropertyCell>); diff --git a/core/src/objects/handles.cpp b/core/src/objects/handles.cpp index 60e5333..c5a5151 100644 --- a/core/src/objects/handles.cpp +++ b/core/src/objects/handles.cpp @@ -23,17 +23,6 @@ static CFrame XYZToZXY(glm::vec3(0, 0, 0), -glm::vec3(1, 0, 0), glm::vec3(0, 0, static rp3d::PhysicsCommon common; static rp3d::PhysicsWorld* world = common.createPhysicsWorld(); -const InstanceType Handles::TYPE = { - .super = &Instance::TYPE, - .className = "Handles", - // .constructor = &Workspace::Create, - // .explorerIcon = "", -}; - -const InstanceType* Handles::GetClass() { - return &TYPE; -} - Handles::Handles(): Instance(&TYPE) { } diff --git a/core/src/objects/handles.h b/core/src/objects/handles.h index fbb532d..27f95a5 100644 --- a/core/src/objects/handles.h +++ b/core/src/objects/handles.h @@ -2,6 +2,7 @@ #include "base.h" #include "datatypes/cframe.h" +#include "objects/annotation.h" #include "objects/base/service.h" #include "objects/part.h" #include @@ -30,7 +31,8 @@ enum HandlesType { RotateHandles, }; -class Handles : public Instance { +class INSTANCE_WITH(abstract) Handles : public Instance { + AUTOGEN_PREAMBLE public: const static InstanceType TYPE; diff --git a/core/src/objects/joint/jointinstance.cpp b/core/src/objects/joint/jointinstance.cpp index c4c71e1..4980dad 100644 --- a/core/src/objects/joint/jointinstance.cpp +++ b/core/src/objects/joint/jointinstance.cpp @@ -11,42 +11,7 @@ #include #include "ptr_helpers.h" -const InstanceType JointInstance::TYPE = { - .super = &Instance::TYPE, - .className = "JointInstance", -}; - -const InstanceType* JointInstance::GetClass() { - return &TYPE; -} - JointInstance::JointInstance(const InstanceType* type): Instance(type) { - this->memberMap = std::make_unique(MemberMap { - .super = std::move(this->memberMap), - .members = { - { "Part0", { - .backingField = &part0, - .type = &Data::InstanceRef::TYPE, - .codec = fieldCodecOf>(), - .updateCallback = memberFunctionOf(&JointInstance::onUpdated, this), - }}, { "Part1", { - .backingField = &part1, - .type = &Data::InstanceRef::TYPE, - .codec = fieldCodecOf>(), - .updateCallback = memberFunctionOf(&JointInstance::onUpdated, this), - }}, { "C0", { - .backingField = &c0, - .type = &CFrame::TYPE, - .codec = fieldCodecOf(), - .updateCallback = memberFunctionOf(&JointInstance::onUpdated, this), - }}, { "C1", { - .backingField = &c1, - .type = &CFrame::TYPE, - .codec = fieldCodecOf(), - .updateCallback = memberFunctionOf(&JointInstance::onUpdated, this), - }}, - } - }); } JointInstance::~JointInstance() { diff --git a/core/src/objects/joint/jointinstance.h b/core/src/objects/joint/jointinstance.h index d987e97..970d29a 100644 --- a/core/src/objects/joint/jointinstance.h +++ b/core/src/objects/joint/jointinstance.h @@ -1,13 +1,16 @@ #pragma once #include "objects/base/instance.h" +#include "../annotation.h" #include #include class Part; class Workspace; -class JointInstance : public Instance { +class INSTANCE_SERVICE() JointInstance : public Instance { + AUTOGEN_PREAMBLE + std::weak_ptr oldPart0; std::weak_ptr oldPart1; protected: @@ -23,9 +26,13 @@ protected: public: const static InstanceType TYPE; + [[ def_prop(name="Part0", on_update=onUpdated) ]] std::weak_ptr part0; + [[ def_prop(name="Part1", on_update=onUpdated) ]] std::weak_ptr part1; + [[ def_prop(name="C0", on_update=onUpdated) ]] CFrame c0; + [[ def_prop(name="C1", on_update=onUpdated) ]] CFrame c1; JointInstance(const InstanceType*); diff --git a/core/src/objects/joint/snap.cpp b/core/src/objects/joint/snap.cpp index bdcb7b8..8ef4b12 100644 --- a/core/src/objects/joint/snap.cpp +++ b/core/src/objects/joint/snap.cpp @@ -10,16 +10,6 @@ #include #include -const InstanceType Snap::TYPE = { - .super = &JointInstance::TYPE, - .className = "Snap", - .constructor = &Snap::Create, -}; - -const InstanceType* Snap::GetClass() { - return &TYPE; -} - Snap::Snap(): JointInstance(&TYPE) { } diff --git a/core/src/objects/joint/snap.h b/core/src/objects/joint/snap.h index bac4262..ac33976 100644 --- a/core/src/objects/joint/snap.h +++ b/core/src/objects/joint/snap.h @@ -1,10 +1,13 @@ #pragma once +#include "objects/annotation.h" #include "objects/base/instance.h" #include "objects/joint/jointinstance.h" #include -class Snap : public JointInstance { +class INSTANCE Snap : public JointInstance { + AUTOGEN_PREAMBLE + rp::FixedJoint* joint = nullptr; virtual void buildJoint() override; diff --git a/core/src/objects/joint/weld.cpp b/core/src/objects/joint/weld.cpp index 8053aba..ca89c9d 100644 --- a/core/src/objects/joint/weld.cpp +++ b/core/src/objects/joint/weld.cpp @@ -10,16 +10,6 @@ #include #include -const InstanceType Weld::TYPE = { - .super = &JointInstance::TYPE, - .className = "Weld", - .constructor = &Weld::Create, -}; - -const InstanceType* Weld::GetClass() { - return &TYPE; -} - Weld::Weld(): JointInstance(&TYPE) { } diff --git a/core/src/objects/joint/weld.h b/core/src/objects/joint/weld.h index 318eef9..061f018 100644 --- a/core/src/objects/joint/weld.h +++ b/core/src/objects/joint/weld.h @@ -1,10 +1,13 @@ #pragma once +#include "objects/annotation.h" #include "objects/base/instance.h" #include "objects/joint/jointinstance.h" #include -class Weld : public JointInstance { +class INSTANCE Weld : public JointInstance { + AUTOGEN_PREAMBLE + rp::FixedJoint* joint = nullptr; virtual void buildJoint() override; diff --git a/core/src/objects/jointsservice.cpp b/core/src/objects/jointsservice.cpp index 226ca45..133832e 100644 --- a/core/src/objects/jointsservice.cpp +++ b/core/src/objects/jointsservice.cpp @@ -2,18 +2,6 @@ #include "workspace.h" #include -const InstanceType JointsService::TYPE = { - .super = &Instance::TYPE, - .className = "JointsService", - .constructor = &JointsService::Create, - .flags = INSTANCE_NOTCREATABLE | INSTANCE_SERVICE | INSTANCE_HIDDEN, -}; - -const InstanceType* JointsService::GetClass() { - return &TYPE; -} - - JointsService::JointsService(): Service(&TYPE) { } diff --git a/core/src/objects/jointsservice.h b/core/src/objects/jointsservice.h index b57e121..e08972f 100644 --- a/core/src/objects/jointsservice.h +++ b/core/src/objects/jointsservice.h @@ -1,8 +1,10 @@ #pragma once +#include "objects/annotation.h" #include "objects/base/service.h" -class JointsService : public Service { +class INSTANCE_SERVICE() JointsService : public Service { + AUTOGEN_PREAMBLE private: std::optional> jointWorkspace(); protected: diff --git a/core/src/objects/part.cpp b/core/src/objects/part.cpp index 644c864..2db21a8 100644 --- a/core/src/objects/part.cpp +++ b/core/src/objects/part.cpp @@ -55,102 +55,7 @@ Part::Part(): Part(PartConstructParams { .size = glm::vec3(2, 1.2, 4), .color = Part::Part(PartConstructParams params): Instance(&TYPE), cframe(CFrame::FromEulerAnglesXYZ((Vector3)params.rotation) + params.position), size(params.size), color(params.color), anchored(params.anchored), locked(params.locked) { - this->memberMap = std::make_unique(MemberMap { - .super = std::move(this->memberMap), - .members = { - { "Anchored", { - .backingField = &anchored, - .type = &Data::Bool::TYPE, - .codec = fieldCodecOf(), - .updateCallback = memberFunctionOf(&Part::onUpdated, this), - .category = PROP_CATEGORY_BEHAVIOR, - }}, { "Locked", { - .backingField = &locked, - .type = &Data::Bool::TYPE, - .codec = fieldCodecOf(), - .category = PROP_CATEGORY_BEHAVIOR, - }}, { "Position", { - .backingField = &cframe, - .type = &Vector3::TYPE, - .codec = cframePositionCodec(), - .updateCallback = memberFunctionOf(&Part::onUpdated, this), - .flags = PROP_NOSAVE - }}, { "Rotation", { - .backingField = &cframe, - .type = &Vector3::TYPE, - .codec = cframeRotationCodec(), - .updateCallback = memberFunctionOf(&Part::onUpdated, this), - .flags = PROP_NOSAVE - }}, { "Velocity", { - .backingField = &velocity, - .type = &Vector3::TYPE, - .codec = fieldCodecOf(), - .updateCallback = memberFunctionOf(&Part::onUpdated, this), - }}, { "CFrame", { - .backingField = &cframe, - .type = &CFrame::TYPE, - .codec = fieldCodecOf(), - .updateCallback = memberFunctionOf(&Part::onUpdated, this), - }}, { "Size", { - .backingField = &size, - .type = &Vector3::TYPE, - .codec = fieldCodecOf(), - .updateCallback = memberFunctionOf(&Part::onUpdated, this), - .category = PROP_CATEGORY_PART, - }}, { "Color", { - .backingField = &color, - .type = &Color3::TYPE, - .codec = fieldCodecOf(), - .category = PROP_CATEGORY_APPEARENCE, - }}, { "Transparency", { - .backingField = &transparency, - .type = &Data::Float::TYPE, - .codec = fieldCodecOf(), - .flags = PROP_UNIT_FLOAT, - .category = PROP_CATEGORY_APPEARENCE, - }}, - - // Surfaces - - { "TopSurface", { - .backingField = &topSurface, - .type = &Data::Int::TYPE, // Replace with enum - .codec = fieldCodecOf(), - .flags = PROP_HIDDEN, - .category = PROP_CATEGORY_SURFACE, - }}, { "BottomSurface", { - .backingField = &bottomSurface, - .type = &Data::Int::TYPE, // Replace with enum - .codec = fieldCodecOf(), - .flags = PROP_HIDDEN, - .category = PROP_CATEGORY_SURFACE, - }}, { "FrontSurface", { - .backingField = &frontSurface, - .type = &Data::Int::TYPE, // Replace with enum - .codec = fieldCodecOf(), - .flags = PROP_HIDDEN, - .category = PROP_CATEGORY_SURFACE, - }}, { "BackSurface", { - .backingField = &backSurface, - .type = &Data::Int::TYPE, // Replace with enum - .codec = fieldCodecOf(), - .flags = PROP_HIDDEN, - .category = PROP_CATEGORY_SURFACE, - }}, { "RightSurface", { - .backingField = &rightSurface, - .type = &Data::Int::TYPE, // Replace with enum - .codec = fieldCodecOf(), - .flags = PROP_HIDDEN, - .category = PROP_CATEGORY_SURFACE, - }}, { "LeftSurface", { - .backingField = &leftSurface, - .type = &Data::Int::TYPE, // Replace with enum - .codec = fieldCodecOf(), - .flags = PROP_HIDDEN, - .category = PROP_CATEGORY_SURFACE, - }}, - } - }); + } Part::~Part() { diff --git a/core/src/objects/part.h b/core/src/objects/part.h index dd061dc..0fb2e41 100644 --- a/core/src/objects/part.h +++ b/core/src/objects/part.h @@ -28,7 +28,7 @@ struct PartConstructParams { class Snap; -class [[ def_inst(explorer_icon="part") ]] Part : public Instance { +class INSTANCE_WITH(explorer_icon="part") Part : public Instance { AUTOGEN_PREAMBLE protected: // Joints where this part is Part0 @@ -51,10 +51,11 @@ protected: public: const static InstanceType TYPE; + [[ def_prop(name="Velocity", on_update=onUpdated) ]] Vector3 velocity; - [[ def_prop(name="CFrame"), cframe_position_prop(name="Position"), cframe_rotation_prop(name="Rotation") ]] + [[ def_prop(name="CFrame", on_update=onUpdated), cframe_position_prop(name="Position"), cframe_rotation_prop(name="Rotation") ]] CFrame cframe; - [[ def_prop(name="Size", category=PART) ]] + [[ def_prop(name="Size", category=PART, on_update=onUpdated) ]] glm::vec3 size; [[ def_prop(name="Color", category=APPEARANCE) ]] Color3 color; @@ -62,7 +63,7 @@ public: float transparency = 0.f; bool selected = false; - [[ def_prop(name="Anchored", category=BEHAVIOR) ]] + [[ def_prop(name="Anchored", category=BEHAVIOR, on_update=onUpdated) ]] bool anchored = false; [[ def_prop(name="Locked", category=BEHAVIOR) ]] bool locked = false; @@ -87,7 +88,7 @@ public: static inline std::shared_ptr New() { return std::make_shared(); }; static inline std::shared_ptr New(PartConstructParams params) { return std::make_shared(params); }; - static inline InstanceRef CreateGeneric() { return std::make_shared(); }; + static inline InstanceRef Create() { return std::make_shared(); }; virtual const InstanceType* GetClass() override; inline Vector3 position() { return cframe.Position(); } diff --git a/core/src/objects/script.cpp b/core/src/objects/script.cpp index 576d2fb..bff5895 100644 --- a/core/src/objects/script.cpp +++ b/core/src/objects/script.cpp @@ -6,30 +6,7 @@ #include "objects/workspace.h" #include "lua.h" -const InstanceType Script::TYPE = { - .super = &Instance::TYPE, - .className = "Script", - .constructor = &Script::Create, - .explorerIcon = "script", -}; - -const InstanceType* Script::GetClass() { - return &TYPE; -} - Script::Script(): Instance(&TYPE) { - this->memberMap = std::make_unique(MemberMap { - .super = std::move(this->memberMap), - .members = { - { "Source", { - .backingField = &source, - .type = &Data::String::TYPE, - .codec = fieldCodecOf(), - .flags = PROP_HIDDEN, - }}, - } - }); - source = "print \"Hello, world!\""; } diff --git a/core/src/objects/script.h b/core/src/objects/script.h index 9d941c9..bd821b1 100644 --- a/core/src/objects/script.h +++ b/core/src/objects/script.h @@ -1,15 +1,18 @@ #pragma once +#include "objects/annotation.h" #include "objects/base/instance.h" #include -class Script : public Instance { +class INSTANCE_WITH(explorer_icon="script") Script : public Instance { + AUTOGEN_PREAMBLE public: const static InstanceType TYPE; Script(); ~Script(); + [[ def_prop(name="Source", hidden) ]] std::string source; void Run(); void Stop(); diff --git a/core/src/objects/script/scriptcontext.cpp b/core/src/objects/script/scriptcontext.cpp index 4988508..b8e8e5d 100644 --- a/core/src/objects/script/scriptcontext.cpp +++ b/core/src/objects/script/scriptcontext.cpp @@ -16,17 +16,6 @@ std::string unsafe_globals[] = { "loadfile", "loadstring", "load", "dofile", "getfenv", "setfenv" }; -const InstanceType ScriptContext::TYPE = { - .super = &Instance::TYPE, - .className = "ScriptContext", - .constructor = &ScriptContext::Create, - .flags = INSTANCE_NOTCREATABLE | INSTANCE_SERVICE | INSTANCE_HIDDEN, -}; - -const InstanceType* ScriptContext::GetClass() { - return &TYPE; -} - ScriptContext::ScriptContext(): Service(&TYPE) { } diff --git a/core/src/objects/script/scriptcontext.h b/core/src/objects/script/scriptcontext.h index 3e04db3..c08a5cf 100644 --- a/core/src/objects/script/scriptcontext.h +++ b/core/src/objects/script/scriptcontext.h @@ -1,10 +1,11 @@ #pragma once +#include "objects/annotation.h" #include "objects/base/service.h" #include "lua.h" -class ScriptContext : public Service { -private: +class INSTANCE_SERVICE() ScriptContext : public Service { + AUTOGEN_PREAMBLE protected: void InitService() override; bool initialized = false; diff --git a/core/src/objects/script/serverscriptservice.cpp b/core/src/objects/script/serverscriptservice.cpp index fcea055..920b7ce 100644 --- a/core/src/objects/script/serverscriptservice.cpp +++ b/core/src/objects/script/serverscriptservice.cpp @@ -2,17 +2,6 @@ #include "objects/script.h" #include "objects/workspace.h" -const InstanceType ServerScriptService::TYPE = { - .super = &Instance::TYPE, - .className = "ServerScriptService", - .constructor = &ServerScriptService::Create, - .flags = INSTANCE_NOTCREATABLE | INSTANCE_SERVICE, -}; - -const InstanceType* ServerScriptService::GetClass() { - return &TYPE; -} - ServerScriptService::ServerScriptService(): Service(&TYPE) { } diff --git a/core/src/objects/script/serverscriptservice.h b/core/src/objects/script/serverscriptservice.h index 0c537a2..dc2e7bb 100644 --- a/core/src/objects/script/serverscriptservice.h +++ b/core/src/objects/script/serverscriptservice.h @@ -1,11 +1,12 @@ #pragma once +#include "objects/annotation.h" #include "objects/base/service.h" // Container class for server scripts // Also handles/manages running server scripts on run -class ServerScriptService : public Service { -private: +class INSTANCE_SERVICE() ServerScriptService : public Service { + AUTOGEN_PREAMBLE protected: void InitService() override; void OnRun() override; diff --git a/core/src/objects/workspace.cpp b/core/src/objects/workspace.cpp index e550feb..7c8b47d 100644 --- a/core/src/objects/workspace.cpp +++ b/core/src/objects/workspace.cpp @@ -5,18 +5,6 @@ #include "physics/util.h" #include -const InstanceType Workspace::TYPE = { - .super = &Instance::TYPE, - .className = "Workspace", - .constructor = &Workspace::Create, - .explorerIcon = "workspace", - .flags = INSTANCE_NOTCREATABLE | INSTANCE_SERVICE, -}; - -const InstanceType* Workspace::GetClass() { - return &TYPE; -} - rp::PhysicsCommon* Workspace::physicsCommon = new rp::PhysicsCommon; Workspace::Workspace(): Service(&TYPE) { diff --git a/core/src/objects/workspace.h b/core/src/objects/workspace.h index d5859e8..6680005 100644 --- a/core/src/objects/workspace.h +++ b/core/src/objects/workspace.h @@ -1,5 +1,6 @@ #pragma once +#include "objects/annotation.h" #include "objects/base/service.h" #include #include @@ -29,7 +30,9 @@ class Weld; typedef std::function)> RaycastFilter; -class Workspace : public Service { +class INSTANCE_SERVICE(explorer_icon="workspace") Workspace : public Service { + AUTOGEN_PREAMBLE + rp::PhysicsWorld* physicsWorld = nullptr; static rp::PhysicsCommon* physicsCommon;