InstanceFactory, make PropertyViewer better, DataModel

This commit is contained in:
floralrainfall 2023-07-18 18:46:04 -04:00
parent d976800f38
commit a1cea61ce2
13 changed files with 170 additions and 22 deletions

View File

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -11,6 +11,6 @@ private:
QLabel* prop_label; QLabel* prop_label;
public: public:
PropertyViewer(); PropertyViewer();
void view(RNR::Instance* instance); void view(RNR::Instance* instance);
}; };

View File

@ -82,6 +82,7 @@ void MainWindow::recurseTreeAddInstance(QTreeWidgetItem* parent, RNR::Instance*
void MainWindow::updateTree(RNR::Instance* root_instance) void MainWindow::updateTree(RNR::Instance* root_instance)
{ {
explorer->clear();
for(auto& child : *root_instance->getChildren()) for(auto& child : *root_instance->getChildren())
{ {
QTreeWidgetItem* parent = new QTreeWidgetItem(); QTreeWidgetItem* parent = new QTreeWidgetItem();

View File

@ -1,6 +1,7 @@
#include <PropertyViewer.hpp> #include <PropertyViewer.hpp>
#include <QVBoxLayout> #include <QVBoxLayout>
#include <QHeaderView> #include <QHeaderView>
#include <QFile>
PropertyViewer::PropertyViewer() : QWidget() PropertyViewer::PropertyViewer() : QWidget()
{ {
@ -9,6 +10,8 @@ PropertyViewer::PropertyViewer() : QWidget()
prop_table->horizontalHeader()->setVisible(false); prop_table->horizontalHeader()->setVisible(false);
prop_table->horizontalHeader()->setStretchLastSection(true); prop_table->horizontalHeader()->setStretchLastSection(true);
prop_table->setColumnCount(2); prop_table->setColumnCount(2);
prop_table->setMouseTracking(true);
prop_table->viewport()->setMouseTracking(true);
prop_label = new QLabel(); prop_label = new QLabel();
QVBoxLayout* layout = new QVBoxLayout(this); QVBoxLayout* layout = new QVBoxLayout(this);
@ -33,12 +36,55 @@ void PropertyViewer::view(RNR::Instance* instance)
for(auto& property : properties) for(auto& property : properties)
{ {
QTableWidgetItem* new_property_item = new QTableWidgetItem(tr("%1").arg(property.name().c_str())); QTableWidgetItem* new_property_item = new QTableWidgetItem(tr("%1").arg(property.name().c_str()));
QTableWidgetItem* new_property_itemval = new QTableWidgetItem(tr("%1").arg(property.toString().c_str()));
new_property_item->setStatusTip(property.description().c_str()); Qt::ItemFlags cell_flags = new_property_item->flags();
cell_flags.setFlag(Qt::ItemFlag::ItemIsEditable, false);
new_property_item->setFlags(cell_flags);
new_property_item->setToolTip(QString(property.description().c_str()));
QTableWidgetItem* new_property_itemval = new QTableWidgetItem(tr("%1").arg(property.toString().c_str()));
new_property_itemval->setToolTip(QString(property.description().c_str()));
switch(property.type())
{
case RNR::PROPERTY_BOOL:
{
bool check_state = *(bool*)property.rawGetter();
new_property_itemval->setCheckState(check_state ? Qt::Checked : Qt::Unchecked);
new_property_itemval->setText("");
cell_flags = new_property_itemval->flags();
cell_flags.setFlag(Qt::ItemFlag::ItemIsEditable, false);
new_property_itemval->setFlags(cell_flags);
}
break;
case RNR::PROPERTY_INSTANCE:
{
cell_flags = new_property_itemval->flags();
cell_flags.setFlag(Qt::ItemFlag::ItemIsEditable, false);
new_property_itemval->setFlags(cell_flags);
RNR::Instance* instance_ref = (RNR::Instance*)property.rawGetter();
if(!instance_ref)
break;
QImage image;
QString icon_path;
icon_path = "content/textures/studio/icons/";
icon_path += instance_ref->getClassName();
icon_path += ".png";
if(QFile::exists(icon_path))
image = QImage(icon_path);
else
image = QImage("content/textures/studio/icons/Instance.png");
new_property_itemval->setData(Qt::DecorationRole, QPixmap::fromImage(image));
}
break;
}
prop_table->setItem(property_count, 0, new_property_item); prop_table->setItem(property_count, 0, new_property_item);
prop_table->setItem(property_count, 1, new_property_itemval); prop_table->setItem(property_count, 1, new_property_itemval);
property_count++; property_count++;
} }
prop_table->resizeRowsToContents();
} }

View File

@ -10,11 +10,13 @@ add_library(Engine STATIC
Header/App/GUI/TopMenuBar.hpp Header/App/GUI/TopMenuBar.hpp
Header/App/Humanoid/Humanoid.hpp Header/App/Humanoid/Humanoid.hpp
Header/App/V8/DataModel/Camera.hpp Header/App/V8/DataModel/Camera.hpp
Header/App/V8/DataModel/DataModel.hpp
Header/App/V8/DataModel/ForceField.hpp Header/App/V8/DataModel/ForceField.hpp
Header/App/V8/DataModel/PartInstance.hpp Header/App/V8/DataModel/PartInstance.hpp
Header/App/V8/DataModel/FaceInstance.hpp Header/App/V8/DataModel/FaceInstance.hpp
Header/App/V8/DataModel/Workspace.hpp Header/App/V8/DataModel/Workspace.hpp
Header/App/V8/Tree/Instance.hpp Header/App/V8/Tree/Instance.hpp
Header/App/V8/Tree/InstanceFactory.hpp
Header/App/V8/Tree/PVInstance.hpp Header/App/V8/Tree/PVInstance.hpp
Header/App/V8/Tree/ModelInstance.hpp Header/App/V8/Tree/ModelInstance.hpp
Header/App/V8/World/World.hpp Header/App/V8/World/World.hpp
@ -34,11 +36,13 @@ add_library(Engine STATIC
Source/App/GUI/TopMenuBar.cpp Source/App/GUI/TopMenuBar.cpp
Source/App/Humanoid/Humanoid.cpp Source/App/Humanoid/Humanoid.cpp
Source/App/V8/DataModel/Camera.cpp Source/App/V8/DataModel/Camera.cpp
Source/App/V8/DataModel/DataModel.cpp
Source/App/V8/DataModel/ForceField.cpp Source/App/V8/DataModel/ForceField.cpp
Source/App/V8/DataModel/PartInstance.cpp Source/App/V8/DataModel/PartInstance.cpp
Source/App/V8/DataModel/FaceInstance.cpp Source/App/V8/DataModel/FaceInstance.cpp
Source/App/V8/DataModel/Workspace.cpp Source/App/V8/DataModel/Workspace.cpp
Source/App/V8/Tree/Instance.cpp Source/App/V8/Tree/Instance.cpp
Source/App/V8/Tree/InstanceFactory.cpp
Source/App/V8/Tree/PVInstance.cpp Source/App/V8/Tree/PVInstance.cpp
Source/App/V8/Tree/ModelInstance.cpp Source/App/V8/Tree/ModelInstance.cpp
Source/App/CoordinateFrame.cpp Source/App/CoordinateFrame.cpp

View File

@ -70,6 +70,10 @@ namespace RNR
bool access(ReflectionPropertyAccess accessor) { return this->m_access <= accessor; } bool access(ReflectionPropertyAccess accessor) { return this->m_access <= accessor; }
std::string name() { return m_name; } std::string name() { return m_name; }
std::string description() { return m_description; } std::string description() { return m_description; }
ReflectionPropertyType type() { return m_type; }
const void* rawGetter() { return m_getter(m_object); }
void rawSetter(const void* value) { return m_setter((void*)m_object, value); }
std::string toString(); std::string toString();
}; };

View File

@ -0,0 +1,14 @@
#pragma once
#include <App/V8/Tree/Instance.hpp>
namespace RNR
{
class DataModel : public Instance
{
public:
DataModel();
private:
};
}

View File

@ -23,7 +23,7 @@ namespace RNR
void updateMatrix(); void updateMatrix();
virtual std::string getClassName() { return "PartInstance"; } virtual std::string getClassName() { return "Part"; }
void setSize(Ogre::Vector3 size) { m_size = size; } void setSize(Ogre::Vector3 size) { m_size = size; }
Ogre::Vector3 getSize() { return m_size; } Ogre::Vector3 getSize() { return m_size; }
Ogre::Vector4 getColor() { return m_color; } Ogre::Vector4 getColor() { return m_color; }

View File

@ -0,0 +1,26 @@
#pragma once
#include <functional>
#include <App/V8/Tree/Instance.hpp>
namespace RNR
{
class InstanceFactory
{
public:
typedef std::function<Instance*()> InstanceBuilder;
InstanceFactory();
bool registerInstance(std::string key, InstanceBuilder builder);
Instance* build(std::string key);
static InstanceFactory* singleton() { return m_singleton; };
// default builder
template <typename Derived>
static Instance* instanceBuilder() { return new Derived(); }
private:
static InstanceFactory* m_singleton;
std::map<std::string, InstanceBuilder> m_builders;
};
}

View File

@ -0,0 +1,9 @@
#include <App/V8/DataModel/DataModel.hpp>
namespace RNR
{
DataModel::DataModel()
{
}
}

View File

@ -20,17 +20,17 @@ namespace RNR
std::vector<ReflectionProperty> Instance::getProperties() std::vector<ReflectionProperty> Instance::getProperties()
{ {
ReflectionProperty properties[] = { ReflectionProperty properties[] = {
{ this, std::string("Name"), std::string(""), { this, std::string("Name"), std::string("This is the name of this Instance."),
ACCESS_NONE, OPERATION_READWRITE, PROPERTY_STD_STRING, ACCESS_NONE, OPERATION_READWRITE, PROPERTY_STD_STRING,
REFLECTION_GETTER(Instance* instance = (Instance*)object; return &instance->m_name; ), REFLECTION_GETTER(Instance* instance = (Instance*)object; return &instance->m_name; ),
REFLECTION_SETTER(Instance* instance = (Instance*)object; instance->setName(*(std::string*)value); ) }, REFLECTION_SETTER(Instance* instance = (Instance*)object; instance->setName(*(std::string*)value); ) },
{ this, std::string("Parent"), std::string(""), { this, std::string("Parent"), std::string("This is the parent of this Instance."),
ACCESS_NONE, OPERATION_READ, PROPERTY_INSTANCE, ACCESS_NONE, OPERATION_READ, PROPERTY_INSTANCE,
REFLECTION_GETTER(Instance* instance = (Instance*)object; return instance->m_parent; ), REFLECTION_GETTER(Instance* instance = (Instance*)object; return instance->m_parent; ),
REFLECTION_NO_SETTER() }, REFLECTION_NO_SETTER() },
{ this, std::string("Archivable"), std::string(""), { this, std::string("Archivable"), std::string("This determines whether this Instance may be saved or replicated."),
ACCESS_NONE, OPERATION_READWRITE, PROPERTY_BOOL, ACCESS_NONE, OPERATION_READWRITE, PROPERTY_BOOL,
REFLECTION_GETTER(Instance* instance = (Instance*)object; return &instance->m_archivable; ), REFLECTION_GETTER(Instance* instance = (Instance*)object; return &instance->m_archivable; ),
REFLECTION_SETTER(Instance* instance = (Instance*)object; instance->m_archivable = *(bool*)value; ) }, REFLECTION_SETTER(Instance* instance = (Instance*)object; instance->m_archivable = *(bool*)value; ) },

View File

@ -0,0 +1,28 @@
#include <App/V8/Tree/InstanceFactory.hpp>
namespace RNR
{
InstanceFactory* InstanceFactory::m_singleton = 0;
InstanceFactory::InstanceFactory() : m_builders()
{
m_singleton = this;
}
bool InstanceFactory::registerInstance(std::string key, InstanceFactory::InstanceBuilder builder)
{
printf("InstanceFactory::registerInstance: registering %s\n", key.c_str());
bool ok = m_builders.insert(std::make_pair(key, builder)).second;
if(!ok)
printf("InstanceFactory::registerInstance: could not register\n");
return ok;
}
Instance* InstanceFactory::build(std::string key)
{
auto it = m_builders.find(key);
if(it == m_builders.end())
throw std::runtime_error("Invalid instance " + key);
return it->second();
}
}

View File

@ -1,7 +1,9 @@
#include <App/V8/World/World.hpp> #include <App/V8/World/World.hpp>
#include <App/V8/Tree/InstanceFactory.hpp>
#include <App/V8/DataModel/PartInstance.hpp> #include <App/V8/DataModel/PartInstance.hpp>
#include <App/GUI/SelectionBox.hpp> #include <App/GUI/SelectionBox.hpp>
#include <App/Humanoid/Humanoid.hpp> #include <App/Humanoid/Humanoid.hpp>
#include <stdexcept>
#include <pugixml.hpp> #include <pugixml.hpp>
namespace RNR namespace RNR
@ -17,6 +19,15 @@ namespace RNR
m_workspace = new Workspace(); m_workspace = new Workspace();
m_workspace->setParent(m_datamodel); m_workspace->setParent(m_datamodel);
InstanceFactory();
InstanceFactory::singleton()->registerInstance("Camera", InstanceFactory::instanceBuilder<Camera>);
InstanceFactory::singleton()->registerInstance("Model", InstanceFactory::instanceBuilder<ModelInstance>);
InstanceFactory::singleton()->registerInstance("SelectionBox", InstanceFactory::instanceBuilder<SelectionBox>);
InstanceFactory::singleton()->registerInstance("Part", InstanceFactory::instanceBuilder<PartInstance>);
InstanceFactory::singleton()->registerInstance("Workspace", InstanceFactory::instanceBuilder<Workspace>);
InstanceFactory::singleton()->registerInstance("Humanoid", InstanceFactory::instanceBuilder<Humanoid>);
m_tmb = new TopMenuBar(); m_tmb = new TopMenuBar();
} }
@ -27,10 +38,20 @@ namespace RNR
void World::xmlAddItem(pugi::xml_node node, Instance* parent) void World::xmlAddItem(pugi::xml_node node, Instance* parent)
{ {
bool skip = false;
Instance* instance;
pugi::xml_attribute class_attr = node.attribute("class"); pugi::xml_attribute class_attr = node.attribute("class");
Instance* instance;
/*
try{
instance = InstanceFactory::singleton()->build(class_attr.as_string());
}
catch(std::runtime_error e)
{
printf("World::xmlAddItem: InstanceFactory::build failed '%s'\n", e.what());
return;
}*/
if(class_attr.as_string() == std::string("Part")) if(class_attr.as_string() == std::string("Part"))
{ {
instance = new PartInstance(); instance = new PartInstance();
@ -56,22 +77,17 @@ namespace RNR
instance = new Instance(); instance = new Instance();
} }
if(!skip) pugi::xml_attribute referent = node.attribute("referent");
{ if(!referent.empty())
pugi::xml_attribute referent = node.attribute("referent"); m_refs[referent.as_string()] = instance;
if(!referent.empty()) WorldUndeserialized s;
m_refs[referent.as_string()] = instance; s.instance = instance;
WorldUndeserialized s; s.node = node;
s.instance = instance; m_undeserialized.push(s);
s.node = node; instance->setParent(parent);
m_undeserialized.push(s);
instance->setParent(parent);
}
for(pugi::xml_node item = node.child("Item"); item; item = item.next_sibling("Item")) for(pugi::xml_node item = node.child("Item"); item; item = item.next_sibling("Item"))
{
xmlAddItem(item, instance); xmlAddItem(item, instance);
}
} }
void World::load(char* path) void World::load(char* path)