Files
oak-editor/app/node/inputarray.cpp
T
itsmattkc 0ea98be443 ensure objects are in the correct thread when loading
Since we load in a separate thread, when the QObject based objects are
instantiated, they're created with affinity to that separate thread. Now we
specifically ensure they are moved to the main thread after their creation.
2020-01-14 00:10:21 +11:00

195 lines
4.5 KiB
C++

#include "inputarray.h"
#include <QApplication>
#include "common/xmlreadloop.h"
#include "node.h"
NodeInputArray::NodeInputArray(const QString &id, const DataType &type, const QVariant &default_value) :
NodeInput(id, type, default_value),
default_value_(default_value)
{
}
bool NodeInputArray::IsArray()
{
return true;
}
int NodeInputArray::GetSize() const
{
return sub_params_.size();
}
void NodeInputArray::Prepend()
{
InsertAt(0);
}
void NodeInputArray::SetSize(int size, bool lock)
{
int old_size = GetSize();
if (size == old_size) {
return;
}
if (size < old_size) {
// If the new size is less, delete all extraneous parameters
for (int i=size;i<old_size;i++) {
NodeInput* sub_param = sub_params_.at(i);
delete sub_param;
}
}
if (lock)
parentNode()->LockUserInput();
sub_params_.resize(size);
if (size > old_size) {
// If the new size is greater, create valid parameters for each slot
for (int i=old_size;i<size;i++) {
QString sub_id = id();
sub_id.append(QString::number(i));
Q_ASSERT(!parentNode()->HasParamWithID(sub_id));
NodeInput* new_param = new NodeInput(sub_id, data_type(), default_value_);
new_param->setParent(this);
sub_params_.replace(i, new_param);
connect(new_param, &NodeInput::ValueChanged, this, &NodeInput::ValueChanged);
connect(new_param, &NodeInput::EdgeAdded, this, &NodeInput::EdgeAdded);
connect(new_param, &NodeInput::EdgeRemoved, this, &NodeInput::EdgeRemoved);
}
}
if (lock)
parentNode()->UnlockUserInput();
emit SizeChanged(size);
}
bool NodeInputArray::ContainsSubParameter(NodeInput *input) const
{
return sub_params_.contains(input);
}
int NodeInputArray::IndexOfSubParameter(NodeInput *input) const
{
return sub_params_.indexOf(input);
}
NodeInput *NodeInputArray::At(int index) const
{
return sub_params_.at(index);
}
NodeInput *NodeInputArray::First() const
{
return sub_params_.first();
}
NodeInput *NodeInputArray::Last() const
{
return sub_params_.last();
}
const QVector<NodeInput *> &NodeInputArray::sub_params()
{
return sub_params_;
}
void NodeInputArray::InsertAt(int index)
{
// Add another input at the end
Append();
// Shift all connections from index down
for (int i=sub_params_.size()-1;i>index;i--) {
NodeInput* this_param = sub_params_.at(i);
NodeInput* prev_param = sub_params_.at(i-1);
if (this_param->IsConnected()) {
// Disconnect whatever is at this parameter (presumably its connection has already been copied so we can just remove it)
NodeParam::DisconnectEdge(this_param->edges().first());
}
if (prev_param->IsConnected()) {
// Get edge here (only one since it's an input)
NodeEdgePtr edge = prev_param->edges().first();
// Disconnect it
NodeParam::DisconnectEdge(edge);
// Create a new edge between it and the next one down
NodeParam::ConnectEdge(edge->output(),
this_param);
}
}
}
void NodeInputArray::Append()
{
SetSize(GetSize() + 1);
}
void NodeInputArray::RemoveLast()
{
SetSize(GetSize() - 1);
}
void NodeInputArray::RemoveAt(int index)
{
// Shift all connections from index down
for (int i=index;i<sub_params_.size();i++) {
NodeInput* this_param = sub_params_.at(i);
if (this_param->IsConnected()) {
// Disconnect current edge
NodeParam::DisconnectEdge(this_param->edges().first());
}
if (i < sub_params_.size() - 1) {
NodeInput* next_param = sub_params_.at(i + 1);
if (next_param->IsConnected()) {
// Get edge from next param
NodeEdgePtr edge = next_param->edges().first();
// Disconnect it
NodeParam::DisconnectEdge(edge);
// Reconnect it to this param
NodeParam::ConnectEdge(edge->output(),
this_param);
}
}
}
RemoveLast();
}
void NodeInputArray::LoadInternal(QXmlStreamReader *reader, QHash<quintptr, NodeOutput*>& param_ptrs, QList<SerializedConnection> &input_connections)
{
if (reader->name() == "subparameters") {
XMLReadLoop(reader, "subparameters") {
if (reader->name() == "input") {
Append();
At(GetSize() - 1)->Load(reader, param_ptrs, input_connections);
}
}
}
}
void NodeInputArray::SaveInternal(QXmlStreamWriter *writer) const
{
writer->writeStartElement("subparameters");
foreach (NodeInput* sub, sub_params_) {
sub->Save(writer);
}
writer->writeEndElement(); // subparameters
}