implement saving of procedure nodes
This commit is contained in:
@@ -13,6 +13,7 @@
|
||||
#include <functional>
|
||||
#include <limits>
|
||||
#include <cstdint>
|
||||
#include <array>
|
||||
|
||||
#include <QSpinBox>
|
||||
#include <QDoubleSpinBox>
|
||||
@@ -72,7 +73,11 @@ public:
|
||||
data_ptr.reset();
|
||||
return data_ptr;
|
||||
}
|
||||
return std::make_shared<GenericData<Ty, type_id, type_name, C, D>>(value);
|
||||
else
|
||||
{
|
||||
return std::make_shared<GenericData<Ty, type_id, type_name, C, D>>(value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void to_json(QWidget* widget, QJsonObject& json_obj, const std::string& name) override
|
||||
@@ -219,14 +224,38 @@ struct NoDefaultWidget
|
||||
|
||||
};
|
||||
|
||||
struct TypeFactory
|
||||
{
|
||||
static NodeData* create(const std::string& id)
|
||||
{
|
||||
const Creators_t::const_iterator iter = static_creators().find(id);
|
||||
return iter == static_creators().end() ? 0 : (*iter->second)();
|
||||
}
|
||||
|
||||
private:
|
||||
typedef NodeData* Creator_t();
|
||||
typedef std::map<std::string, Creator_t*> Creators_t;
|
||||
static Creators_t& static_creators() { static Creators_t s_creators; return s_creators; }
|
||||
|
||||
template<typename T> struct Register
|
||||
{
|
||||
static NodeData* create() { return new T(); };
|
||||
static Creator_t* init_creator(const std::string& id) { return static_creators()[id] = create; }
|
||||
static Creator_t* creator;
|
||||
};
|
||||
};
|
||||
|
||||
#define DECLARE_NODE_DATA_TYPE(TYPE_ID, TYPE_NAME, UNDERLYING_TYPE, DEFAULT_WIDGET_GEN) \
|
||||
constexpr char TYPE_ID##_typeid[] = #TYPE_ID; \
|
||||
constexpr char TYPE_ID##_typename[] = #TYPE_NAME; \
|
||||
using TYPE_NAME##Data = GenericData<UNDERLYING_TYPE, \
|
||||
TYPE_ID##_typeid, TYPE_ID##_typename, toQStringGeneric<UNDERLYING_TYPE>, DEFAULT_WIDGET_GEN>;
|
||||
TYPE_ID##_typeid, TYPE_ID##_typename, toQStringGeneric<UNDERLYING_TYPE>, DEFAULT_WIDGET_GEN>; \
|
||||
template<> TypeFactory::Creator_t* TypeFactory::Register<GenericData<UNDERLYING_TYPE, \
|
||||
TYPE_ID##_typeid, TYPE_ID##_typename, toQStringGeneric<UNDERLYING_TYPE>, DEFAULT_WIDGET_GEN>>::creator = TypeFactory::Register<GenericData<UNDERLYING_TYPE, \
|
||||
TYPE_ID##_typeid, TYPE_ID##_typename, toQStringGeneric<UNDERLYING_TYPE>, DEFAULT_WIDGET_GEN>>::init_creator(#TYPE_ID);
|
||||
|
||||
DECLARE_NODE_DATA_TYPE(int, Integer, int, DefaultIntWidget)
|
||||
|
||||
DECLARE_NODE_DATA_TYPE(double, Decimal, double, DefaultDecimalWidget)
|
||||
DECLARE_NODE_DATA_TYPE(bool, Boolean, bool, DefaultBooleanWidget)
|
||||
DECLARE_NODE_DATA_TYPE(string, String, std::string, DefaultStringWidget)
|
||||
@@ -238,11 +267,10 @@ DECLARE_NODE_DATA_TYPE(vec3, Vector3D, glm::vec3, NoDefaultWidget)
|
||||
DECLARE_NODE_DATA_TYPE(vec4, Vector4D, glm::vec4, NoDefaultWidget)
|
||||
DECLARE_NODE_DATA_TYPE(mat4, Matrix4x4, glm::mat4, NoDefaultWidget)
|
||||
DECLARE_NODE_DATA_TYPE(mat3, Matrix3x3, glm::mat3, NoDefaultWidget)
|
||||
DECLARE_NODE_DATA_TYPE(quat, Quaternion, glm::quat, NoDefaultWidget)
|
||||
//DECLARE_NODE_DATA_TYPE(quat, Quaternion, glm::quat, NoDefaultWidget)
|
||||
|
||||
DECLARE_NODE_DATA_TYPE(any, Any, std::nullptr_t, NoDefaultWidget);
|
||||
DECLARE_NODE_DATA_TYPE(procedure, Procedure, std::string, DefaultProcedureWidget);
|
||||
|
||||
|
||||
|
||||
#endif //NOGGIT_GENERICDATA_HPP
|
||||
|
||||
@@ -34,66 +34,7 @@ LogicProcedureNode::LogicProcedureNode()
|
||||
connect(static_cast<ProcedureSelector*>(_procedure_default), &ProcedureSelector::entry_updated
|
||||
,[this](QString const& path)
|
||||
{
|
||||
_scene_path = path;
|
||||
clearDynamicPorts();
|
||||
setValidationState(NodeValidationState::Valid);
|
||||
|
||||
_scene = new NodeScene(::registerDataModels(), this);
|
||||
|
||||
if (!_scene->load(QDir("./scripts/").absoluteFilePath(path)))
|
||||
{
|
||||
setValidationState(NodeValidationState::Error);
|
||||
setValidationMessage("Error: Scene loading failed.");
|
||||
return;
|
||||
}
|
||||
|
||||
_scene->validate();
|
||||
|
||||
// handle in signature
|
||||
auto begin_node = _scene->getBeginNode();
|
||||
|
||||
if (!begin_node)
|
||||
{
|
||||
setValidationState(NodeValidationState::Error);
|
||||
setValidationMessage("Error: No entry point found. (Begin node missing)");
|
||||
return;
|
||||
}
|
||||
|
||||
auto in_signature = static_cast<LogicBeginNode*>(begin_node->nodeDataModel())->getInSignature();
|
||||
for (int i = 1; i < in_signature->size(); ++i)
|
||||
{
|
||||
auto& port = (*in_signature)[i];
|
||||
|
||||
if (!port.connected)
|
||||
continue;
|
||||
|
||||
addPort<LogicData>(PortType::In, port.caption, true);
|
||||
_in_ports[_in_ports.size() - 1].data_type = port.data_type->instantiate();
|
||||
emit portAdded();
|
||||
}
|
||||
|
||||
auto return_node = _scene->getReturnNode();
|
||||
|
||||
if (return_node)
|
||||
{
|
||||
auto out_signature = static_cast<LogicReturnNode*>(return_node->nodeDataModel())->getOutSignature();
|
||||
for (int i = 1; i < out_signature->size(); ++i)
|
||||
{
|
||||
auto& port = (*out_signature)[i];
|
||||
|
||||
if (!port.connected)
|
||||
continue;
|
||||
|
||||
addPort<LogicData>(PortType::Out, port.caption, true);
|
||||
_out_ports[_out_ports.size() - 1].data_type = port.data_type->instantiate();
|
||||
emit portAdded();
|
||||
}
|
||||
}
|
||||
|
||||
delete _scene;
|
||||
_scene = nullptr;
|
||||
|
||||
emit visualsNeedUpdate();
|
||||
setProcedure(path);
|
||||
});
|
||||
|
||||
addPort<LogicData>(PortType::Out, "Logic", true, ConnectionPolicy::One);
|
||||
@@ -112,6 +53,8 @@ void LogicProcedureNode::compute()
|
||||
{
|
||||
setValidationState(NodeValidationState::Error);
|
||||
setValidationMessage("Error: Scene loading failed.");
|
||||
_out_ports[0].out_value = std::make_shared<LogicData>(false);
|
||||
Q_EMIT dataUpdated(0);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -124,6 +67,8 @@ void LogicProcedureNode::compute()
|
||||
{
|
||||
setValidationState(NodeValidationState::Error);
|
||||
setValidationMessage("Error: No entry point found. (Begin node missing)");
|
||||
_out_ports[0].out_value = std::make_shared<LogicData>(false);
|
||||
Q_EMIT dataUpdated(0);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -171,6 +116,9 @@ void LogicProcedureNode::compute()
|
||||
|
||||
setValidationMessage(message.str().c_str());
|
||||
delete _scene;
|
||||
|
||||
_out_ports[0].out_value = std::make_shared<LogicData>(false);
|
||||
Q_EMIT dataUpdated(0);
|
||||
return;
|
||||
|
||||
sig_index_ret++;
|
||||
@@ -181,13 +129,12 @@ void LogicProcedureNode::compute()
|
||||
Q_EMIT dataUpdated(i);
|
||||
}
|
||||
|
||||
_out_ports[0].out_value = std::make_shared<LogicData>(true);
|
||||
Q_EMIT dataUpdated(0);
|
||||
|
||||
delete _scene;
|
||||
|
||||
}
|
||||
|
||||
_out_ports[0].out_value = std::make_shared<LogicData>(true);
|
||||
Q_EMIT dataUpdated(0);
|
||||
|
||||
}
|
||||
|
||||
@@ -195,12 +142,48 @@ QJsonObject LogicProcedureNode::save() const
|
||||
{
|
||||
QJsonObject json_obj = BaseNode::save();
|
||||
|
||||
json_obj["procedure"] = static_cast<ProcedureSelector*>(_procedure_default)->getPath();
|
||||
|
||||
json_obj["n_dynamic_in_ports"] = static_cast<int>(_in_ports.size() - 2);
|
||||
json_obj["n_dynamic_out_ports"] = static_cast<int>(_out_ports.size() - 1);
|
||||
|
||||
for (int i = 2; i < _in_ports.size(); ++i)
|
||||
{
|
||||
json_obj[("in_port_" + std::to_string(i)).c_str()] = _in_ports[i].data_type->type().id;
|
||||
json_obj[("in_port_" + std::to_string(i) + "_caption").c_str()] = _in_ports[i].caption;
|
||||
}
|
||||
|
||||
for (int i = 1; i < _out_ports.size(); ++i)
|
||||
{
|
||||
json_obj[("out_port_" + std::to_string(i)).c_str()] = _out_ports[i].data_type->type().id;
|
||||
json_obj[("out_port_" + std::to_string(i) + "_caption").c_str()] = _out_ports[i].caption;
|
||||
}
|
||||
|
||||
return json_obj;
|
||||
}
|
||||
|
||||
void LogicProcedureNode::restore(const QJsonObject& json_obj)
|
||||
{
|
||||
BaseNode::restore(json_obj);
|
||||
|
||||
_scene_path = json_obj["procedure"].toString();
|
||||
|
||||
static_cast<ProcedureSelector*>(_procedure_default)->setPath(_scene_path);
|
||||
|
||||
for (int i = 0; i < json_obj["n_dynamic_in_ports"].toInt(); ++i)
|
||||
{
|
||||
addPort<LogicData>(PortType::In, json_obj[("in_port_" + std::to_string(i + 2) + "_caption").c_str()].toString(), true);
|
||||
_in_ports[_in_ports.size() - 1].data_type = TypeFactory::create(json_obj[("in_port_" + std::to_string(i + 2)).c_str()].toString().toStdString())->instantiate();
|
||||
emit portAdded();
|
||||
}
|
||||
|
||||
for (int i = 0; i < json_obj["n_dynamic_out_ports"].toInt(); ++i)
|
||||
{
|
||||
addPort<LogicData>(PortType::Out, json_obj[("out_port_" + std::to_string(i + 1) + "_caption").c_str()].toString(), true);
|
||||
_out_ports[_out_ports.size() - 1].data_type = TypeFactory::create(json_obj[("out_port_" + std::to_string(i + 1)).c_str()].toString().toStdString())->instantiate();
|
||||
emit portAdded();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
NodeValidationState LogicProcedureNode::validate()
|
||||
@@ -244,3 +227,67 @@ void LogicProcedureNode::clearDynamicPorts()
|
||||
}
|
||||
}
|
||||
|
||||
void LogicProcedureNode::setProcedure(const QString& path)
|
||||
{
|
||||
_scene_path = path;
|
||||
clearDynamicPorts();
|
||||
setValidationState(NodeValidationState::Valid);
|
||||
|
||||
_scene = new NodeScene(::registerDataModels(), this);
|
||||
|
||||
if (!_scene->load(QDir("./scripts/").absoluteFilePath(path)))
|
||||
{
|
||||
setValidationState(NodeValidationState::Error);
|
||||
setValidationMessage("Error: Scene loading failed.");
|
||||
return;
|
||||
}
|
||||
|
||||
_scene->validate();
|
||||
|
||||
// handle in signature
|
||||
auto begin_node = _scene->getBeginNode();
|
||||
|
||||
if (!begin_node)
|
||||
{
|
||||
setValidationState(NodeValidationState::Error);
|
||||
setValidationMessage("Error: No entry point found. (Begin node missing)");
|
||||
return;
|
||||
}
|
||||
|
||||
auto in_signature = static_cast<LogicBeginNode*>(begin_node->nodeDataModel())->getInSignature();
|
||||
for (int i = 1; i < in_signature->size(); ++i)
|
||||
{
|
||||
auto& port = (*in_signature)[i];
|
||||
|
||||
if (!port.connected)
|
||||
continue;
|
||||
|
||||
addPort<LogicData>(PortType::In, port.caption, true);
|
||||
_in_ports[_in_ports.size() - 1].data_type = port.data_type->instantiate();
|
||||
emit portAdded();
|
||||
}
|
||||
|
||||
auto return_node = _scene->getReturnNode();
|
||||
|
||||
if (return_node)
|
||||
{
|
||||
auto out_signature = static_cast<LogicReturnNode*>(return_node->nodeDataModel())->getOutSignature();
|
||||
for (int i = 1; i < out_signature->size(); ++i)
|
||||
{
|
||||
auto& port = (*out_signature)[i];
|
||||
|
||||
if (!port.connected)
|
||||
continue;
|
||||
|
||||
addPort<LogicData>(PortType::Out, port.caption, true);
|
||||
_out_ports[_out_ports.size() - 1].data_type = port.data_type->instantiate();
|
||||
emit portAdded();
|
||||
}
|
||||
}
|
||||
|
||||
delete _scene;
|
||||
_scene = nullptr;
|
||||
|
||||
emit visualsNeedUpdate();
|
||||
}
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ namespace noggit
|
||||
NodeValidationState validate() override;
|
||||
QJsonObject save() const override;
|
||||
void restore(QJsonObject const& json_obj) override;
|
||||
void setProcedure(QString const& path);
|
||||
|
||||
private:
|
||||
|
||||
|
||||
@@ -106,3 +106,14 @@ ProcedureSelector::ProcedureSelector(QWidget *parent)
|
||||
model->setNameFilters(filters_search);
|
||||
});
|
||||
}
|
||||
|
||||
QString ProcedureSelector::getPath()
|
||||
{
|
||||
return static_cast<QPushButton*>(layout()->itemAt(0)->widget())->text();
|
||||
}
|
||||
|
||||
void ProcedureSelector::setPath(QString const& path)
|
||||
{
|
||||
static_cast<QPushButton*>(layout()->itemAt(0)->widget())->setText(path);
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,8 @@ namespace noggit
|
||||
|
||||
public:
|
||||
explicit ProcedureSelector(QWidget* parent = nullptr);
|
||||
QString getPath();
|
||||
void setPath(QString const& path);
|
||||
|
||||
signals:
|
||||
void entry_updated(QString const& entry);
|
||||
|
||||
Reference in New Issue
Block a user