feat(autogen): convert classes to new autogen annotations
This commit is contained in:
parent
b8ee828d29
commit
a2e2210998
31 changed files with 148 additions and 343 deletions
|
@ -24,7 +24,8 @@ std::map<std::string, std::string> 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
|
||||
|
|
|
@ -46,6 +46,7 @@ struct ClassAnalysis {
|
|||
std::string name;
|
||||
std::string baseClass;
|
||||
std::string headerPath;
|
||||
bool abstract = false;
|
||||
std::vector<PropertyAnalysis> properties;
|
||||
ClassFlags flags = (ClassFlags)0;
|
||||
std::string explorerIcon;
|
||||
|
|
|
@ -18,6 +18,7 @@ std::map<std::string, std::string> MAPPED_TYPE = {
|
|||
{ "float", "Data::Float" },
|
||||
{ "std::string", "Data::String" },
|
||||
{ "std::weak_ptr<Instance>", "Data::InstanceRef" },
|
||||
{ "std::weak_ptr<Part>", "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<Vector3>();";
|
||||
} 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<string> " << state.name << "::InternalGetProperties() {\n";
|
||||
out << " std::vector<string> 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<PropertyMeta, MemberNotFound> " << 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);
|
||||
|
|
|
@ -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]);
|
||||
}
|
|
@ -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)
|
||||
|
|
|
@ -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<PropertyMeta, MemberNotFound> InternalGetPropertyMeta(std::string name) override; \
|
||||
fallible<MemberNotFound, AssignToReadOnlyMember> InternalSetPropertyValue(std::string name, Data::Variant value) override; \
|
||||
result<Data::Variant, MemberNotFound> InternalGetPropertyValue(std::string name) override; \
|
||||
std::vector<std::string> InternalGetProperties() override; \
|
||||
private:
|
||||
|
|
|
@ -43,15 +43,6 @@ constexpr FieldCodec classNameCodec() {
|
|||
|
||||
Instance::Instance(const InstanceType* type) {
|
||||
this->name = type->className;
|
||||
|
||||
this->memberMap = std::make_unique<MemberMap>( MemberMap {
|
||||
.super = std::nullopt,
|
||||
.members = {
|
||||
{ "Name", { .backingField = &name, .type = &Data::String::TYPE, .codec = fieldCodecOf<Data::String, std::string>() } },
|
||||
{ "Parent", { .backingField = &parent, .type = &Data::InstanceRef::TYPE, .codec = fieldCodecOf<Data::InstanceRef, std::weak_ptr<Instance>>() } },
|
||||
{ "ClassName", { .backingField = const_cast<InstanceType*>(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<Workspace> oldWorkspace) {
|
|||
// Properties
|
||||
|
||||
result<Data::Variant, MemberNotFound> 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<MemberNotFound, AssignToReadOnlyMember> Instance::SetPropertyValue(std::string name, Data::Variant value) {
|
||||
// Handle special case: Parent
|
||||
if (name == "Parent") {
|
||||
Data::InstanceRef ref = value.get<Data::InstanceRef>();
|
||||
std::weak_ptr<Instance> 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<PropertyMeta, MemberNotFound> 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<Data::Variant, MemberNotFound> Instance::InternalGetPropertyValue(std::string name) { return MemberNotFound(GetClass()->className, name); }
|
||||
fallible<MemberNotFound, AssignToReadOnlyMember> Instance::InternalSetPropertyValue(std::string name, Data::Variant value) { return MemberNotFound(GetClass()->className, name); }
|
||||
result<Data::Variant, MemberNotFound> 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<MemberNotFound, AssignToReadOnlyMember> Instance::InternalSetPropertyValue(std::string name, Data::Variant value) {
|
||||
if (name == "Name") {
|
||||
this->name = (std::string)value.get<Data::String>();
|
||||
} else if (name == "Parent") {
|
||||
std::weak_ptr<Instance> ref = value.get<Data::InstanceRef>();
|
||||
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<std::string> Instance::InternalGetProperties() {
|
||||
std::vector<std::string> members;
|
||||
members.push_back("Name");
|
||||
members.push_back("Parent");
|
||||
members.push_back("ClassName");
|
||||
return members;
|
||||
}
|
||||
|
||||
result<PropertyMeta, MemberNotFound> 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<std::string> Instance::GetProperties() {
|
||||
if (cachedMemberList.has_value()) return cachedMemberList.value();
|
||||
|
||||
std::vector<std::string> 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<std::string> memberList = InternalGetProperties();
|
||||
|
||||
cachedMemberList = memberList;
|
||||
return memberList;
|
||||
|
|
|
@ -65,7 +65,6 @@ private:
|
|||
friend JointInstance; // This isn't ideal, but oh well
|
||||
protected:
|
||||
bool parentLocked = false;
|
||||
std::unique_ptr<MemberMap> memberMap;
|
||||
|
||||
Instance(const InstanceType*);
|
||||
virtual ~Instance();
|
||||
|
@ -73,6 +72,7 @@ protected:
|
|||
virtual result<Data::Variant, MemberNotFound> InternalGetPropertyValue(std::string name);
|
||||
virtual fallible<MemberNotFound, AssignToReadOnlyMember> InternalSetPropertyValue(std::string name, Data::Variant value);
|
||||
virtual result<PropertyMeta, MemberNotFound> InternalGetPropertyMeta(std::string name);
|
||||
virtual std::vector<std::string> InternalGetProperties();
|
||||
|
||||
virtual void OnParentUpdated(std::optional<std::shared_ptr<Instance>> oldParent, std::optional<std::shared_ptr<Instance>> newParent);
|
||||
virtual void OnAncestryChanged(std::optional<std::shared_ptr<Instance>> child, std::optional<std::shared_ptr<Instance>> newParent);
|
||||
|
|
|
@ -66,9 +66,4 @@ struct PropertyMeta {
|
|||
PropertyCategory category = PROP_CATEGORY_DATA;
|
||||
};
|
||||
|
||||
typedef std::variant<PropertyMeta> MemberMeta;
|
||||
|
||||
struct MemberMap {
|
||||
std::optional<std::unique_ptr<MemberMap>> super;
|
||||
std::map<std::string, PropertyMeta> members;
|
||||
};
|
||||
typedef std::variant<PropertyMeta> MemberMeta;
|
|
@ -13,16 +13,6 @@
|
|||
#include <memory>
|
||||
#include <optional>
|
||||
|
||||
const InstanceType DataModel::TYPE = {
|
||||
.super = &Instance::TYPE,
|
||||
.className = "DataModel",
|
||||
.constructor = nullptr,
|
||||
};
|
||||
|
||||
const InstanceType* DataModel::GetClass() {
|
||||
return &TYPE;
|
||||
}
|
||||
|
||||
DataModel::DataModel()
|
||||
: Instance(&TYPE) {
|
||||
this->name = "Place";
|
||||
|
|
|
@ -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 <memory>
|
||||
|
@ -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<DataModel> target, std::shared_ptr<Service>, RefState<_RefStatePropertyCell>);
|
||||
|
|
|
@ -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) {
|
||||
}
|
||||
|
||||
|
|
|
@ -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 <array>
|
||||
|
@ -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;
|
||||
|
||||
|
|
|
@ -11,42 +11,7 @@
|
|||
#include <reactphysics3d/engine/PhysicsWorld.h>
|
||||
#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>(MemberMap {
|
||||
.super = std::move(this->memberMap),
|
||||
.members = {
|
||||
{ "Part0", {
|
||||
.backingField = &part0,
|
||||
.type = &Data::InstanceRef::TYPE,
|
||||
.codec = fieldCodecOf<Data::InstanceRef, std::weak_ptr<Instance>>(),
|
||||
.updateCallback = memberFunctionOf(&JointInstance::onUpdated, this),
|
||||
}}, { "Part1", {
|
||||
.backingField = &part1,
|
||||
.type = &Data::InstanceRef::TYPE,
|
||||
.codec = fieldCodecOf<Data::InstanceRef, std::weak_ptr<Instance>>(),
|
||||
.updateCallback = memberFunctionOf(&JointInstance::onUpdated, this),
|
||||
}}, { "C0", {
|
||||
.backingField = &c0,
|
||||
.type = &CFrame::TYPE,
|
||||
.codec = fieldCodecOf<CFrame>(),
|
||||
.updateCallback = memberFunctionOf(&JointInstance::onUpdated, this),
|
||||
}}, { "C1", {
|
||||
.backingField = &c1,
|
||||
.type = &CFrame::TYPE,
|
||||
.codec = fieldCodecOf<CFrame>(),
|
||||
.updateCallback = memberFunctionOf(&JointInstance::onUpdated, this),
|
||||
}},
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
JointInstance::~JointInstance() {
|
||||
|
|
|
@ -1,13 +1,16 @@
|
|||
#pragma once
|
||||
|
||||
#include "objects/base/instance.h"
|
||||
#include "../annotation.h"
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
|
||||
class Part;
|
||||
class Workspace;
|
||||
|
||||
class JointInstance : public Instance {
|
||||
class INSTANCE_SERVICE() JointInstance : public Instance {
|
||||
AUTOGEN_PREAMBLE
|
||||
|
||||
std::weak_ptr<Part> oldPart0;
|
||||
std::weak_ptr<Part> oldPart1;
|
||||
protected:
|
||||
|
@ -23,9 +26,13 @@ protected:
|
|||
public:
|
||||
const static InstanceType TYPE;
|
||||
|
||||
[[ def_prop(name="Part0", on_update=onUpdated) ]]
|
||||
std::weak_ptr<Part> part0;
|
||||
[[ def_prop(name="Part1", on_update=onUpdated) ]]
|
||||
std::weak_ptr<Part> part1;
|
||||
[[ def_prop(name="C0", on_update=onUpdated) ]]
|
||||
CFrame c0;
|
||||
[[ def_prop(name="C1", on_update=onUpdated) ]]
|
||||
CFrame c1;
|
||||
|
||||
JointInstance(const InstanceType*);
|
||||
|
|
|
@ -10,16 +10,6 @@
|
|||
#include <reactphysics3d/constraint/FixedJoint.h>
|
||||
#include <reactphysics3d/engine/PhysicsWorld.h>
|
||||
|
||||
const InstanceType Snap::TYPE = {
|
||||
.super = &JointInstance::TYPE,
|
||||
.className = "Snap",
|
||||
.constructor = &Snap::Create,
|
||||
};
|
||||
|
||||
const InstanceType* Snap::GetClass() {
|
||||
return &TYPE;
|
||||
}
|
||||
|
||||
Snap::Snap(): JointInstance(&TYPE) {
|
||||
}
|
||||
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
#pragma once
|
||||
|
||||
#include "objects/annotation.h"
|
||||
#include "objects/base/instance.h"
|
||||
#include "objects/joint/jointinstance.h"
|
||||
#include <memory>
|
||||
|
||||
class Snap : public JointInstance {
|
||||
class INSTANCE Snap : public JointInstance {
|
||||
AUTOGEN_PREAMBLE
|
||||
|
||||
rp::FixedJoint* joint = nullptr;
|
||||
|
||||
virtual void buildJoint() override;
|
||||
|
|
|
@ -10,16 +10,6 @@
|
|||
#include <reactphysics3d/constraint/FixedJoint.h>
|
||||
#include <reactphysics3d/engine/PhysicsWorld.h>
|
||||
|
||||
const InstanceType Weld::TYPE = {
|
||||
.super = &JointInstance::TYPE,
|
||||
.className = "Weld",
|
||||
.constructor = &Weld::Create,
|
||||
};
|
||||
|
||||
const InstanceType* Weld::GetClass() {
|
||||
return &TYPE;
|
||||
}
|
||||
|
||||
Weld::Weld(): JointInstance(&TYPE) {
|
||||
}
|
||||
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
#pragma once
|
||||
|
||||
#include "objects/annotation.h"
|
||||
#include "objects/base/instance.h"
|
||||
#include "objects/joint/jointinstance.h"
|
||||
#include <memory>
|
||||
|
||||
class Weld : public JointInstance {
|
||||
class INSTANCE Weld : public JointInstance {
|
||||
AUTOGEN_PREAMBLE
|
||||
|
||||
rp::FixedJoint* joint = nullptr;
|
||||
|
||||
virtual void buildJoint() override;
|
||||
|
|
|
@ -2,18 +2,6 @@
|
|||
#include "workspace.h"
|
||||
#include <memory>
|
||||
|
||||
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) {
|
||||
}
|
||||
|
||||
|
|
|
@ -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<std::shared_ptr<Workspace>> jointWorkspace();
|
||||
protected:
|
||||
|
|
|
@ -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>(MemberMap {
|
||||
.super = std::move(this->memberMap),
|
||||
.members = {
|
||||
{ "Anchored", {
|
||||
.backingField = &anchored,
|
||||
.type = &Data::Bool::TYPE,
|
||||
.codec = fieldCodecOf<Data::Bool, bool>(),
|
||||
.updateCallback = memberFunctionOf(&Part::onUpdated, this),
|
||||
.category = PROP_CATEGORY_BEHAVIOR,
|
||||
}}, { "Locked", {
|
||||
.backingField = &locked,
|
||||
.type = &Data::Bool::TYPE,
|
||||
.codec = fieldCodecOf<Data::Bool, bool>(),
|
||||
.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<Vector3>(),
|
||||
.updateCallback = memberFunctionOf(&Part::onUpdated, this),
|
||||
}}, { "CFrame", {
|
||||
.backingField = &cframe,
|
||||
.type = &CFrame::TYPE,
|
||||
.codec = fieldCodecOf<CFrame>(),
|
||||
.updateCallback = memberFunctionOf(&Part::onUpdated, this),
|
||||
}}, { "Size", {
|
||||
.backingField = &size,
|
||||
.type = &Vector3::TYPE,
|
||||
.codec = fieldCodecOf<Vector3, glm::vec3>(),
|
||||
.updateCallback = memberFunctionOf(&Part::onUpdated, this),
|
||||
.category = PROP_CATEGORY_PART,
|
||||
}}, { "Color", {
|
||||
.backingField = &color,
|
||||
.type = &Color3::TYPE,
|
||||
.codec = fieldCodecOf<Color3>(),
|
||||
.category = PROP_CATEGORY_APPEARENCE,
|
||||
}}, { "Transparency", {
|
||||
.backingField = &transparency,
|
||||
.type = &Data::Float::TYPE,
|
||||
.codec = fieldCodecOf<Data::Float, float>(),
|
||||
.flags = PROP_UNIT_FLOAT,
|
||||
.category = PROP_CATEGORY_APPEARENCE,
|
||||
}},
|
||||
|
||||
// Surfaces
|
||||
|
||||
{ "TopSurface", {
|
||||
.backingField = &topSurface,
|
||||
.type = &Data::Int::TYPE, // Replace with enum
|
||||
.codec = fieldCodecOf<Data::Int, int>(),
|
||||
.flags = PROP_HIDDEN,
|
||||
.category = PROP_CATEGORY_SURFACE,
|
||||
}}, { "BottomSurface", {
|
||||
.backingField = &bottomSurface,
|
||||
.type = &Data::Int::TYPE, // Replace with enum
|
||||
.codec = fieldCodecOf<Data::Int, int>(),
|
||||
.flags = PROP_HIDDEN,
|
||||
.category = PROP_CATEGORY_SURFACE,
|
||||
}}, { "FrontSurface", {
|
||||
.backingField = &frontSurface,
|
||||
.type = &Data::Int::TYPE, // Replace with enum
|
||||
.codec = fieldCodecOf<Data::Int, int>(),
|
||||
.flags = PROP_HIDDEN,
|
||||
.category = PROP_CATEGORY_SURFACE,
|
||||
}}, { "BackSurface", {
|
||||
.backingField = &backSurface,
|
||||
.type = &Data::Int::TYPE, // Replace with enum
|
||||
.codec = fieldCodecOf<Data::Int, int>(),
|
||||
.flags = PROP_HIDDEN,
|
||||
.category = PROP_CATEGORY_SURFACE,
|
||||
}}, { "RightSurface", {
|
||||
.backingField = &rightSurface,
|
||||
.type = &Data::Int::TYPE, // Replace with enum
|
||||
.codec = fieldCodecOf<Data::Int, int>(),
|
||||
.flags = PROP_HIDDEN,
|
||||
.category = PROP_CATEGORY_SURFACE,
|
||||
}}, { "LeftSurface", {
|
||||
.backingField = &leftSurface,
|
||||
.type = &Data::Int::TYPE, // Replace with enum
|
||||
.codec = fieldCodecOf<Data::Int, int>(),
|
||||
.flags = PROP_HIDDEN,
|
||||
.category = PROP_CATEGORY_SURFACE,
|
||||
}},
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
Part::~Part() {
|
||||
|
|
|
@ -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<Part> New() { return std::make_shared<Part>(); };
|
||||
static inline std::shared_ptr<Part> New(PartConstructParams params) { return std::make_shared<Part>(params); };
|
||||
static inline InstanceRef CreateGeneric() { return std::make_shared<Part>(); };
|
||||
static inline InstanceRef Create() { return std::make_shared<Part>(); };
|
||||
virtual const InstanceType* GetClass() override;
|
||||
|
||||
inline Vector3 position() { return cframe.Position(); }
|
||||
|
|
|
@ -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>(MemberMap {
|
||||
.super = std::move(this->memberMap),
|
||||
.members = {
|
||||
{ "Source", {
|
||||
.backingField = &source,
|
||||
.type = &Data::String::TYPE,
|
||||
.codec = fieldCodecOf<Data::String, std::string>(),
|
||||
.flags = PROP_HIDDEN,
|
||||
}},
|
||||
}
|
||||
});
|
||||
|
||||
source = "print \"Hello, world!\"";
|
||||
}
|
||||
|
||||
|
|
|
@ -1,15 +1,18 @@
|
|||
#pragma once
|
||||
|
||||
#include "objects/annotation.h"
|
||||
#include "objects/base/instance.h"
|
||||
#include <memory>
|
||||
|
||||
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();
|
||||
|
|
|
@ -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) {
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -5,18 +5,6 @@
|
|||
#include "physics/util.h"
|
||||
#include <reactphysics3d/engine/PhysicsCommon.h>
|
||||
|
||||
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) {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include "objects/annotation.h"
|
||||
#include "objects/base/service.h"
|
||||
#include <memory>
|
||||
#include <reactphysics3d/body/RigidBody.h>
|
||||
|
@ -29,7 +30,9 @@ class Weld;
|
|||
|
||||
typedef std::function<FilterResult(std::shared_ptr<Part>)> RaycastFilter;
|
||||
|
||||
class Workspace : public Service {
|
||||
class INSTANCE_SERVICE(explorer_icon="workspace") Workspace : public Service {
|
||||
AUTOGEN_PREAMBLE
|
||||
|
||||
rp::PhysicsWorld* physicsWorld = nullptr;
|
||||
static rp::PhysicsCommon* physicsCommon;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue