Compare commits

..

No commits in common. "49066db8fbf62922fca599518fd5b21656ba9fac" and "9968266839936ee91e8a572ea05db1f3d66fbf27" have entirely different histories.

17 changed files with 51 additions and 343 deletions

View file

@ -7,10 +7,6 @@ set( CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin )
set( CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib ) set( CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib )
set( CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/lib ) set( CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/lib )
SET(BASEPATH "${CMAKE_SOURCE_DIR}")
include_directories("${BASEPATH}")
include_directories("src")
find_package(OpenGL REQUIRED COMPONENTS OpenGL) find_package(OpenGL REQUIRED COMPONENTS OpenGL)
find_package(SDL2 REQUIRED) find_package(SDL2 REQUIRED)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 354 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 294 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 688 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 774 B

View file

@ -88,159 +88,6 @@
</layout> </layout>
</widget> </widget>
</widget> </widget>
<widget class="QToolBar" name="toolBar">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>toolBar</string>
</property>
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
<addaction name="actionNew"/>
<addaction name="actionOpen"/>
<addaction name="actionSave"/>
<addaction name="separator"/>
<addaction name="actionAddPart"/>
<addaction name="separator"/>
<addaction name="actionToolSelect"/>
<addaction name="actionToolMove"/>
<addaction name="actionToolScale"/>
<addaction name="actionToolRotate"/>
</widget>
<action name="actionAddPart">
<property name="icon">
<iconset>
<normaloff>assets/icons/part.png</normaloff>assets/icons/part.png</iconset>
</property>
<property name="text">
<string>Add Part</string>
</property>
<property name="toolTip">
<string>Add a part to the workspace</string>
</property>
</action>
<action name="actionNew">
<property name="icon">
<iconset>
<normaloff>assets/icons/editor/new.png</normaloff>assets/icons/editor/new.png</iconset>
</property>
<property name="text">
<string>New</string>
</property>
<property name="toolTip">
<string>New document</string>
</property>
<property name="shortcut">
<string>Ctrl+N</string>
</property>
</action>
<action name="actionOpen">
<property name="icon">
<iconset>
<normaloff>assets/icons/editor/open.png</normaloff>assets/icons/editor/open.png</iconset>
</property>
<property name="text">
<string>Open</string>
</property>
<property name="toolTip">
<string>Open document</string>
</property>
<property name="shortcut">
<string>Ctrl+O</string>
</property>
</action>
<action name="actionSave">
<property name="icon">
<iconset>
<normaloff>assets/icons/editor/save.png</normaloff>assets/icons/editor/save.png</iconset>
</property>
<property name="text">
<string>Save</string>
</property>
<property name="toolTip">
<string>Save document</string>
</property>
<property name="shortcut">
<string>Ctrl+S</string>
</property>
</action>
<action name="actionToolSelect">
<property name="checkable">
<bool>true</bool>
</property>
<property name="icon">
<iconset theme="edit-select">
<normaloff>assets/icons/editor/drag.png</normaloff>assets/icons/editor/drag.png</iconset>
</property>
<property name="text">
<string>Select Objects</string>
</property>
<property name="toolTip">
<string>Select objects in the workspace</string>
</property>
<property name="shortcut">
<string>1</string>
</property>
</action>
<action name="actionToolMove">
<property name="checkable">
<bool>true</bool>
</property>
<property name="icon">
<iconset theme="transform-move"/>
</property>
<property name="text">
<string>Move Objects</string>
</property>
<property name="toolTip">
<string>Move objects in the workspace</string>
</property>
<property name="shortcut">
<string>2</string>
</property>
</action>
<action name="actionToolScale">
<property name="checkable">
<bool>true</bool>
</property>
<property name="icon">
<iconset theme="transform-scale"/>
</property>
<property name="text">
<string>Scale Objects</string>
</property>
<property name="toolTip">
<string>Scale objects in the workspace</string>
</property>
<property name="shortcut">
<string>3</string>
</property>
</action>
<action name="actionToolRotate">
<property name="checkable">
<bool>true</bool>
</property>
<property name="icon">
<iconset theme="transform-rotate"/>
</property>
<property name="text">
<string>Rotate Objects</string>
</property>
<property name="toolTip">
<string>Rotate objects in the workspace</string>
</property>
<property name="shortcut">
<string>4</string>
</property>
</action>
</widget> </widget>
<customwidgets> <customwidgets>
<customwidget> <customwidget>

View file

@ -22,7 +22,7 @@ QVariant PropertiesModel::data(const QModelIndex &index, int role) const {
if (index.column() == 0) if (index.column() == 0)
return QString::fromStdString(propertyName); return QString::fromStdString(propertyName);
else if (index.column() == 1) else if (index.column() == 1)
return QString::fromStdString(selectedItem->GetPropertyValue(propertyName).value().ToString()); return QString::fromStdString(selectedItem->GetPropertyValue(propertyName).value());
// case Qt::DecorationRole: // case Qt::DecorationRole:
// return iconOf(item->GetClass()); // return iconOf(item->GetClass());
} }

View file

@ -1,41 +0,0 @@
#include "base.h"
#define IMPL_WRAPPER_CLASS(CLASS_NAME, WRAPPED_TYPE, TYPE_NAME) Data::CLASS_NAME::CLASS_NAME(WRAPPED_TYPE in) : value(in) {} \
Data::CLASS_NAME::~CLASS_NAME() = default; \
Data::CLASS_NAME::operator WRAPPED_TYPE() { return value; } \
const Data::TypeInfo Data::CLASS_NAME::TYPE = { .name = TYPE_NAME, }; \
const Data::TypeInfo& Data::CLASS_NAME::GetType() const { return Data::CLASS_NAME::TYPE; };
Data::Base::~Base() {};
Data::Null::Null() {};
Data::Null::~Null() = default;
const Data::TypeInfo Data::Null::TYPE = {
.name = "null",
};
const Data::TypeInfo& Data::Null::GetType() const { return Data::Null::TYPE; };
IMPL_WRAPPER_CLASS(Bool, bool, "bool")
IMPL_WRAPPER_CLASS(Int, int, "int")
IMPL_WRAPPER_CLASS(Float, float, "float")
IMPL_WRAPPER_CLASS(String, std::string, "string")
const Data::String Data::Null::ToString() const {
return Data::String("null");
}
const Data::String Data::Bool::ToString() const {
return Data::String(value ? "true" : "false");
}
const Data::String Data::Int::ToString() const {
return Data::String(std::to_string(value));
}
const Data::String Data::Float::ToString() const {
return Data::String(std::to_string(value));
}
const Data::String Data::String::ToString() const {
return *this;
}

View file

@ -1,48 +0,0 @@
#pragma once
#include <string>
#define DEF_WRAPPER_CLASS(CLASS_NAME, WRAPPED_TYPE) class CLASS_NAME : public Data::Base { \
public: \
const WRAPPED_TYPE value; \
CLASS_NAME(WRAPPED_TYPE); \
~CLASS_NAME(); \
operator WRAPPED_TYPE(); \
virtual const TypeInfo& GetType() const override; \
static const TypeInfo TYPE; \
\
virtual const Data::String ToString() const override; \
};
namespace Data {
struct TypeInfo {
std::string name;
};
class String;
class Base {
public:
virtual ~Base();
virtual const TypeInfo& GetType() const = 0;
virtual const Data::String ToString() const = 0;
};
class Null : Base {
public:
Null();
~Null();
virtual const TypeInfo& GetType() const override;
static const TypeInfo TYPE;
virtual const Data::String ToString() const override;
};
DEF_WRAPPER_CLASS(Bool, bool)
DEF_WRAPPER_CLASS(Int, int)
DEF_WRAPPER_CLASS(Float, float)
DEF_WRAPPER_CLASS(String, std::string)
};
#undef DEF_WRAPPER_CLASS

View file

@ -1,8 +0,0 @@
#include "meta.h"
#include <variant>
Data::String Data::Variant::ToString() const {
return std::visit([](auto&& it) {
return it.ToString();
}, this->wrapped);
}

View file

@ -1,30 +0,0 @@
#pragma once
#include "base.h"
#include <variant>
// #define __VARIANT_TYPE std::variant< \
// Null, \
// Bool, \
// Int, \
// Float, \
// String \
// >
namespace Data {
typedef std::variant<
Null,
Bool,
Int,
Float,
String
> __VARIANT_TYPE;
class Variant {
__VARIANT_TYPE wrapped;
public:
template <typename T> Variant(T obj) : wrapped(obj) {}
template <typename T> T get() { return std::get<T>(wrapped); }
Data::String ToString() const;
};
}

View file

@ -0,0 +1,11 @@
#include "primitives.h"
#define IMPL_WRAPPER_CLASS(CLASS_NAME, WRAPPED_TYPE) Data::CLASS_NAME::CLASS_NAME(WRAPPED_TYPE in) : wrapped(in) {}\
Data::CLASS_NAME::operator WRAPPED_TYPE() { return wrapped; }
Data::Void::Void() {};
IMPL_WRAPPER_CLASS(Bool, bool)
IMPL_WRAPPER_CLASS(Int, int)
IMPL_WRAPPER_CLASS(Float, float)
IMPL_WRAPPER_CLASS(String, std::string)

View file

@ -0,0 +1,25 @@
#pragma once
#include <string>
#define DEF_WRAPPER_CLASS(CLASS_NAME, WRAPPED_TYPE) class CLASS_NAME {\
WRAPPED_TYPE wrapped;\
public:\
CLASS_NAME(WRAPPED_TYPE); \
operator WRAPPED_TYPE(); \
};
namespace Data {
class Void {
public:
Void();
};
DEF_WRAPPER_CLASS(Bool, bool)
DEF_WRAPPER_CLASS(Int, int)
DEF_WRAPPER_CLASS(Float, float)
DEF_WRAPPER_CLASS(String, std::string)
};
#undef DEF_WRAPPER_CLASS

View file

@ -1,8 +1,5 @@
#include "instance.h" #include "instance.h"
#include "../../common.h" #include "../../common.h"
#include "../../datatypes/meta.h"
#include "datatypes/base.h"
#include "objects/base/member.h"
#include <algorithm> #include <algorithm>
#include <cstddef> #include <cstddef>
#include <cstdio> #include <cstdio>
@ -27,12 +24,12 @@ InstanceType* Instance::TYPE = &TYPE_;
Instance::Instance(InstanceType* type) { Instance::Instance(InstanceType* type) {
this->name = type->className; this->name = type->className;
this->memberMap = std::make_unique<MemberMap>( MemberMap { this->memberMap = {
.super = std::nullopt, .super = std::nullopt,
.members = { .members = {
{ "Name", { .backingField = &name, .codec = fieldCodecOf<Data::String, std::string>() } } { "Name", { .backingField = &name } }
} }
}); };
} }
Instance::~Instance () { Instance::~Instance () {
@ -71,24 +68,24 @@ void Instance::OnParentUpdated(std::optional<std::shared_ptr<Instance>> oldParen
// Properties // Properties
tl::expected<Data::Variant, MemberNotFound> Instance::GetPropertyValue(std::string name) { tl::expected<std::string, MemberNotFound> Instance::GetPropertyValue(std::string name) {
auto meta = GetPropertyMeta(name); auto meta = GetPropertyMeta(name);
if (!meta) return tl::make_unexpected(MemberNotFound()); if (!meta) return tl::make_unexpected(MemberNotFound());
return meta->codec.read(meta->backingField); return *(std::string*)meta->backingField;
} }
tl::expected<void, MemberNotFound> Instance::SetPropertyValue(std::string name, Data::Variant value) { tl::expected<void, MemberNotFound> Instance::SetPropertyValue(std::string name, std::string value) {
auto meta = GetPropertyMeta(name); auto meta = GetPropertyMeta(name);
if (!meta) return tl::make_unexpected(MemberNotFound()); if (!meta) return tl::make_unexpected(MemberNotFound());
meta->codec.write(value, meta->backingField); *(std::string*)meta->backingField = value;
return {}; return {};
} }
tl::expected<PropertyMeta, MemberNotFound> Instance::GetPropertyMeta(std::string name) { tl::expected<PropertyMeta, MemberNotFound> Instance::GetPropertyMeta(std::string name) {
MemberMap* current = &*memberMap; MemberMap* current = &memberMap;
while (true) { while (true) {
// We look for the property in current member map // We look for the property in current member map
auto it = current->members.find(name); auto it = current->members.find(name);
@ -111,17 +108,14 @@ std::vector<std::string> Instance::GetProperties() {
std::vector<std::string> memberList; std::vector<std::string> memberList;
MemberMap* current = &*memberMap; MemberMap* current = &memberMap;
do { do {
for (auto const& [key, _] : current->members) { for (auto const& [key, _] : current->members) {
// Don't add it if it's already in the list // Don't add it if it's already in the list
if (std::find(memberList.begin(), memberList.end(), key) == memberList.end()) if (std::find(memberList.begin(), memberList.end(), key) == memberList.end())
memberList.push_back(key); memberList.push_back(key);
} }
if (!current->super.has_value()) } while (current->super.has_value());
break;
current = &*current->super.value();
} while (true);
cachedMemberList = memberList; cachedMemberList = memberList;
return memberList; return memberList;

View file

@ -36,7 +36,7 @@ private:
std::optional<std::vector<std::string>> cachedMemberList; std::optional<std::vector<std::string>> cachedMemberList;
protected: protected:
std::unique_ptr<MemberMap> memberMap; MemberMap memberMap;
Instance(InstanceType*); Instance(InstanceType*);
virtual ~Instance(); virtual ~Instance();
@ -57,8 +57,8 @@ public:
// Properties // Properties
// Do I like using expected? // Do I like using expected?
tl::expected<Data::Variant, MemberNotFound> GetPropertyValue(std::string name); tl::expected<std::string, MemberNotFound> GetPropertyValue(std::string name);
tl::expected<void, MemberNotFound> SetPropertyValue(std::string name, Data::Variant value); tl::expected<void, MemberNotFound> SetPropertyValue(std::string name, std::string value);
tl::expected<PropertyMeta, MemberNotFound> GetPropertyMeta(std::string name); tl::expected<PropertyMeta, MemberNotFound> GetPropertyMeta(std::string name);
// Returning a list of property names feels kinda janky. Is this really the way to go? // Returning a list of property names feels kinda janky. Is this really the way to go?
std::vector<std::string> GetProperties(); std::vector<std::string> GetProperties();

View file

@ -1,7 +1,5 @@
#pragma once #pragma once
#include "../../datatypes/base.h"
#include "datatypes/meta.h"
#include <map> #include <map>
#include <memory> #include <memory>
#include <optional> #include <optional>
@ -9,33 +7,8 @@
class Instance; class Instance;
struct FieldCodec {
void (*write)(Data::Variant source, void* destination);
Data::Variant (*read)(void* source);
};
template <typename T, typename U>
void _writeCodec(Data::Variant source, void* destination) {
*(U*)destination = source.get<T>().value;
}
template <typename T, typename U>
Data::Variant _readCodec(void* source) {
return T(*(U*)source);
}
template <typename T, typename U>
constexpr FieldCodec fieldCodecOf() {
return FieldCodec {
.write = &_writeCodec<T, U>,
.read = &_readCodec<T, U>,
};
}
struct PropertyMeta { struct PropertyMeta {
void* backingField; void* backingField;
Data::TypeInfo type;
FieldCodec codec;
}; };
typedef std::variant<PropertyMeta> MemberMeta; typedef std::variant<PropertyMeta> MemberMeta;

View file

@ -1,9 +1,5 @@
#include "part.h" #include "part.h"
#include "base/instance.h" #include "base/instance.h"
#include "datatypes/base.h"
#include "objects/base/member.h"
#include <memory>
#include <optional>
static InstanceType TYPE_ { static InstanceType TYPE_ {
.super = Instance::TYPE, .super = Instance::TYPE,
@ -18,18 +14,11 @@ InstanceType* Part::GetClass() {
return &TYPE_; return &TYPE_;
} }
Part::Part(): Part(PartConstructParams {}) { Part::Part(): Instance(&TYPE_) {
} }
Part::Part(PartConstructParams params): Instance(&TYPE_), position(params.position), rotation(params.rotation), Part::Part(PartConstructParams params): Instance(&TYPE_), position(params.position), rotation(params.rotation),
scale(params.scale), material(params.material), anchored(params.anchored) { scale(params.scale), material(params.material), anchored(params.anchored) {
this->memberMap = std::make_unique<MemberMap>(MemberMap {
.super = std::move(this->memberMap),
.members = {
{ "Anchored", { .backingField = &anchored, .codec = fieldCodecOf<Data::Bool, bool>() } }
}
});
} }
// This feels wrong. Get access to PhysicsWorld somehow else? Part will need access to this often though, most likely... // This feels wrong. Get access to PhysicsWorld somehow else? Part will need access to this often though, most likely...