implement list get operation

This commit is contained in:
sshumakov3
2020-12-26 17:39:28 +03:00
parent ec29d1ce8e
commit 87f10ce855
6 changed files with 234 additions and 1 deletions

View File

@@ -25,6 +25,7 @@
#include <noggit/Red/NodeEditor/Nodes/DataConstantNode.hpp>
#include <noggit/Red/NodeEditor/Nodes/DataListNode.hpp>
#include <noggit/Red/NodeEditor/Nodes/ListAddNode.hpp>
#include <noggit/Red/NodeEditor/Nodes/ListGetNode.hpp>
#include <noggit/Red/NodeEditor/Nodes/BaseNode.hpp>
#include <noggit/Red/NodeEditor/Nodes/Data/GenericTypeConverter.hpp>
#include <noggit/Red/NodeEditor/Nodes/Scene/NodeScene.hpp>
@@ -68,15 +69,27 @@ namespace noggit
// List
ret->registerModel<DataListNode>("Containers//List");
ret->registerModel<ListAddNode>("Containers//List");
ret->registerModel<ListGetNode>("Containers//List");
ret->REGISTER_TYPE_CONVERTER(Decimal, Integer);
ret->REGISTER_TYPE_CONVERTER(Decimal, Boolean);
ret->REGISTER_TYPE_CONVERTER(Decimal, UnsignedInteger);
ret->REGISTER_TYPE_CONVERTER(Integer, Decimal);
ret->REGISTER_TYPE_CONVERTER(Integer, Boolean);
ret->REGISTER_TYPE_CONVERTER(Integer, UnsignedInteger);
ret->REGISTER_TYPE_CONVERTER(Boolean, Decimal);
ret->REGISTER_TYPE_CONVERTER(Boolean, Integer);
ret->REGISTER_TYPE_CONVERTER(Boolean, UnsignedInteger);
ret->REGISTER_TYPE_CONVERTER(Integer, String);
ret->REGISTER_TYPE_CONVERTER(Decimal, String);
ret->REGISTER_TYPE_CONVERTER(UnsignedInteger, String);
ret->REGISTER_TYPE_CONVERTER(UnsignedInteger, Decimal);
ret->REGISTER_TYPE_CONVERTER(UnsignedInteger, Integer);
ret->REGISTER_TYPE_CONVERTER(UnsignedInteger, Boolean);
ret->REGISTER_TYPE_CONVERTER(Integer, Basic);
ret->REGISTER_TYPE_CONVERTER(UnsignedInteger, Basic);

View File

@@ -75,15 +75,24 @@ struct BasicDataConverter
DECLARE_TYPE_CONVERTER(Decimal, Integer, double, int)
DECLARE_TYPE_CONVERTER(Decimal, UnsignedInteger, double, unsigned int)
DECLARE_TYPE_CONVERTER(Decimal, Boolean, double, bool)
DECLARE_TYPE_CONVERTER(Integer, Decimal, int, double)
DECLARE_TYPE_CONVERTER(Integer, UnsignedInteger, int, unsigned int)
DECLARE_TYPE_CONVERTER(Integer, Boolean, int, bool)
DECLARE_TYPE_CONVERTER(Boolean, Integer, bool, int)
DECLARE_TYPE_CONVERTER(Boolean, UnsignedInteger, bool, unsigned int)
DECLARE_TYPE_CONVERTER(Boolean, Decimal, bool, double)
DECLARE_TYPE_CONVERTER(UnsignedInteger, Integer, unsigned int, int)
DECLARE_TYPE_CONVERTER(UnsignedInteger, Decimal, unsigned int, double)
DECLARE_TYPE_CONVERTER(UnsignedInteger, Boolean, unsigned int, bool)
DECLARE_TYPE_CONVERTER_EXT(Decimal, String, StringConverter<double>)
DECLARE_TYPE_CONVERTER_EXT(Integer, String, StringConverter<int>)
DECLARE_TYPE_CONVERTER_EXT(UnsignedInteger, String, StringConverter<unsigned int>)
// Polymorph types
DECLARE_TYPE_CONVERTER_EXT(Integer, Basic, BasicDataConverter<int>)

View File

@@ -73,6 +73,7 @@ QJsonObject DataConstantNode::save() const
QJsonObject json_obj = BaseNode::save();
json_obj["type"] = _type->currentText();
_in_ports[0].data_type->to_json(_in_ports[0].default_widget, json_obj, "value");
return json_obj;
}
@@ -82,6 +83,10 @@ void DataConstantNode::restore(const QJsonObject& json_obj)
BaseNode::restore(json_obj);
auto type = json_obj["type"].toString();
_in_ports[0].data_type->from_json(_in_ports[0].default_widget, json_obj, "value");
_type->setCurrentText(type);
}

View File

@@ -33,7 +33,7 @@ namespace noggit
private:
QComboBox* _type;
tsl::robin_map<std::string, std::string> _type_map = {{"Integer", "int"},
{"UnsignedInteger", "uint"},
{"Unsigned Integer", "uint"},
{"Boolean", "bool"},
{"Decimal", "double"},
{"String", "string"},

View File

@@ -0,0 +1,161 @@
// This file is part of Noggit3, licensed under GNU General Public License (version 3).
#include "ListGetNode.hpp"
#include "BaseNode.inl"
#include "Data/GenericData.hpp"
#include "Scene/NodeScene.hpp"
#include <external/NodeEditor/include/nodes/Node>
using QtNodes::Node;
using namespace noggit::Red::NodeEditor::Nodes;
ListGetNode::ListGetNode()
: LogicNodeBase()
{
setName("ListGetNode");
setCaption("Get");
_validation_state = NodeValidationState::Valid;
addPort<LogicData>(PortType::In, "Logic", true);
addDefaultWidget(new QLabel(&_embedded_widget), PortType::In, 0);
addPort<ListData>(PortType::In, "List[Any]", true);
addDefaultWidget(new QLabel(&_embedded_widget), PortType::In, 1);
addPort<UnsignedIntegerData>(PortType::In, "Index<UInteger>", true);
addDefaultWidget(_in_ports[2].data_type->default_widget(&_embedded_widget), PortType::In, 2);
addPort<LogicData>(PortType::Out, "Logic", true);
addPort<UndefinedData>(PortType::Out, "Value<Undefined>", true);
}
void ListGetNode::compute()
{
auto logic = static_cast<LogicData*>(_in_ports[0].in_value.lock().get());
if (!logic->value())
return;
auto list = static_cast<ListData*>(_in_ports[1].in_value.lock().get())->value();
auto index_ptr = static_cast<UnsignedIntegerData*>(_in_ports[2].in_value.lock().get());;
_out_ports[1].out_value = list->at((index_ptr ? index_ptr->value() : static_cast<QSpinBox*>(_in_ports[2].default_widget)->value()));
Q_EMIT dataUpdated(1);
_out_ports[0].out_value = std::make_shared<LogicData>(true);
Q_EMIT dataUpdated(0);
}
NodeValidationState ListGetNode::validate()
{
LogicNodeBase::validate();
auto list = static_cast<ListData*>(_in_ports[1].in_value.lock().get());
if (!list)
{
setValidationState(NodeValidationState::Error);
setValidationMessage("Error: Failed to evaluate list input.");
_out_ports[0].out_value = std::make_shared<LogicData>(false);
Q_EMIT dataUpdated(0);
}
return _validation_state;
}
QJsonObject ListGetNode::save() const
{
QJsonObject json_obj = LogicNodeBase::save();
json_obj["list_type"] = _in_ports[1].data_type->type().parameter_type_id;
return json_obj;
}
void ListGetNode::restore(const QJsonObject& json_obj)
{
LogicNodeBase::restore(json_obj);
auto type_id = json_obj["list_type"].toString();
auto type = TypeFactory::create(type_id.toStdString());
_in_ports[1].data_type->set_parameter_type(type_id);
_in_ports[1].caption = "List<" + type->type().name + ">";
if (!type_id.isEmpty())
{
_out_ports[1].data_type.reset(type);
_out_ports[1].caption = "Value<" + _out_ports[1].data_type->type().name + ">";
}
}
void ListGetNode::inputConnectionCreated(const Connection& connection)
{
BaseNode::inputConnectionCreated(connection);
auto port_index = connection.getPortIndex(PortType::In);
if (port_index == 1)
{
auto parameter_type = connection.dataType(PortType::Out).parameter_type_id;
_in_ports[1].data_type->set_parameter_type(parameter_type);
_in_ports[1].caption = connection.getNode(PortType::Out)->nodeDataModel()->portCaption(PortType::Out, connection.getPortIndex(PortType::Out));
_out_ports[1].data_type.reset(TypeFactory::create(parameter_type.toStdString()));
_out_ports[1].caption = "Value<" + _out_ports[1].data_type->type().name + ">";
// clean up connections if list type changes
if (_out_ports[1].connected)
{
auto this_node = connection.getNode(PortType::In);
auto connections = this_node->nodeState().connections(PortType::Out, 1);
for (auto& pair : connections)
{
if (pair.second->dataType(PortType::In).id != parameter_type)
{
static_cast<NodeScene*>(this_node->nodeGraphicsObject().scene())->deleteConnection(*pair.second);
}
}
}
}
}
void ListGetNode::inputConnectionDeleted(const Connection& connection)
{
BaseNode::inputConnectionDeleted(connection);
auto port_index = connection.getPortIndex(PortType::In);
if (port_index == 1)
{
_in_ports[1].data_type->set_parameter_type("");
_in_ports[1].caption = "List[Any]";
_out_ports[1].data_type.reset(TypeFactory::create("undefined"));
_out_ports[1].caption = "Value<Undefined>";
// clean up connections if list type changes
if (_out_ports[1].connected)
{
auto this_node = connection.getNode(PortType::In);
auto connections = this_node->nodeState().connections(PortType::Out, 1);
for (auto& pair : connections)
{
static_cast<NodeScene*>(this_node->nodeGraphicsObject().scene())->deleteConnection(*pair.second);
}
}
}
}

View File

@@ -0,0 +1,45 @@
// This file is part of Noggit3, licensed under GNU General Public License (version 3).
#ifndef NOGGIT_LISTGETNODE_HPP
#define NOGGIT_LISTGETNODE_HPP
#include "LogicNodeBase.hpp"
#include <QComboBox>
using QtNodes::PortType;
using QtNodes::PortIndex;
using QtNodes::NodeData;
using QtNodes::NodeDataType;
using QtNodes::NodeDataModel;
using QtNodes::NodeValidationState;
namespace noggit
{
namespace Red::NodeEditor::Nodes
{
class ListGetNode : public LogicNodeBase
{
Q_OBJECT
public:
ListGetNode();
void compute() override;
NodeValidationState validate() override;
QJsonObject save() const override;
void restore(QJsonObject const& json_obj) override;
public Q_SLOTS:
void inputConnectionCreated(const Connection& connection) override;
void inputConnectionDeleted(const Connection& connection) override;
private:
QComboBox* _operation;
};
}
}
#endif //NOGGIT_LISTGETNODE_HPP