mirror of
https://github.com/4ian/GDevelop.git
synced 2025-10-15 10:19:04 +00:00

* Each row should be easier to read in a glance * You can now collapse collection variables for a better readability * Reorder and move of variables is now available with drag n drop * You can now undo and redo changes * Paste one or more variables at any level of depth you want * Search in the names and values of each variables with a filter effect
205 lines
6.1 KiB
C++
205 lines
6.1 KiB
C++
/*
|
|
* GDevelop Core
|
|
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
|
* reserved. This project is released under the MIT License.
|
|
*/
|
|
#include "GDCore/Project/VariablesContainer.h"
|
|
|
|
#include <algorithm>
|
|
#include <iostream>
|
|
|
|
#include "GDCore/Project/Variable.h"
|
|
#include "GDCore/Serialization/SerializerElement.h"
|
|
#include "GDCore/String.h"
|
|
#include "GDCore/TinyXml/tinyxml.h"
|
|
|
|
namespace gd {
|
|
|
|
gd::Variable VariablesContainer::badVariable;
|
|
gd::String VariablesContainer::badName;
|
|
|
|
namespace {
|
|
|
|
// Tool functor used below
|
|
class VariableHasName {
|
|
public:
|
|
VariableHasName(gd::String const& name_) : name(name_) {}
|
|
|
|
bool operator()(
|
|
const std::pair<gd::String, std::shared_ptr<gd::Variable>>& p) {
|
|
return (p.first == name);
|
|
}
|
|
|
|
gd::String name;
|
|
};
|
|
} // namespace
|
|
|
|
VariablesContainer::VariablesContainer() {}
|
|
|
|
bool VariablesContainer::Has(const gd::String& name) const {
|
|
auto i =
|
|
std::find_if(variables.begin(), variables.end(), VariableHasName(name));
|
|
return (i != variables.end());
|
|
}
|
|
|
|
Variable& VariablesContainer::Get(const gd::String& name) {
|
|
auto i =
|
|
std::find_if(variables.begin(), variables.end(), VariableHasName(name));
|
|
if (i != variables.end()) return *i->second;
|
|
|
|
return badVariable;
|
|
}
|
|
|
|
const Variable& VariablesContainer::Get(const gd::String& name) const {
|
|
auto i =
|
|
std::find_if(variables.begin(), variables.end(), VariableHasName(name));
|
|
if (i != variables.end()) return *i->second;
|
|
|
|
return badVariable;
|
|
}
|
|
|
|
Variable& VariablesContainer::Get(std::size_t index) {
|
|
if (index < variables.size()) return *variables[index].second;
|
|
|
|
return badVariable;
|
|
}
|
|
|
|
const Variable& VariablesContainer::Get(std::size_t index) const {
|
|
if (index < variables.size()) return *variables[index].second;
|
|
|
|
return badVariable;
|
|
}
|
|
|
|
const gd::String& VariablesContainer::GetNameAt(std::size_t index) const {
|
|
if (index < variables.size()) return variables[index].first;
|
|
|
|
return badName;
|
|
}
|
|
|
|
Variable& VariablesContainer::Insert(const gd::String& name,
|
|
const gd::Variable& variable,
|
|
std::size_t position) {
|
|
auto newVariable = std::make_shared<gd::Variable>(variable);
|
|
if (position < variables.size()) {
|
|
variables.insert(variables.begin() + position,
|
|
std::make_pair(name, newVariable));
|
|
return *variables[position].second;
|
|
} else {
|
|
variables.push_back(std::make_pair(name, newVariable));
|
|
return *variables.back().second;
|
|
}
|
|
}
|
|
|
|
void VariablesContainer::Remove(const gd::String& varName) {
|
|
variables.erase(
|
|
std::remove_if(
|
|
variables.begin(), variables.end(), VariableHasName(varName)),
|
|
variables.end());
|
|
}
|
|
|
|
void VariablesContainer::RemoveRecursively(
|
|
const gd::Variable& variableToRemove) {
|
|
variables.erase(
|
|
std::remove_if(
|
|
variables.begin(),
|
|
variables.end(),
|
|
[&variableToRemove](
|
|
const std::pair<gd::String, std::shared_ptr<gd::Variable>>&
|
|
nameAndVariable) {
|
|
return &variableToRemove == nameAndVariable.second.get();
|
|
}),
|
|
variables.end());
|
|
|
|
for (auto& it : variables) {
|
|
it.second->RemoveRecursively(variableToRemove);
|
|
}
|
|
}
|
|
|
|
std::size_t VariablesContainer::GetPosition(const gd::String& name) const {
|
|
for (std::size_t i = 0; i < variables.size(); ++i) {
|
|
if (variables[i].first == name) return i;
|
|
}
|
|
|
|
return gd::String::npos;
|
|
}
|
|
|
|
Variable& VariablesContainer::InsertNew(const gd::String& name,
|
|
std::size_t position) {
|
|
Variable newVariable;
|
|
return Insert(name, newVariable, position);
|
|
}
|
|
|
|
bool VariablesContainer::Rename(const gd::String& oldName,
|
|
const gd::String& newName) {
|
|
if (Has(newName)) return false;
|
|
|
|
auto i = std::find_if(
|
|
variables.begin(), variables.end(), VariableHasName(oldName));
|
|
if (i != variables.end()) i->first = newName;
|
|
|
|
return true;
|
|
}
|
|
|
|
void VariablesContainer::Swap(std::size_t firstVariableIndex,
|
|
std::size_t secondVariableIndex) {
|
|
if (firstVariableIndex >= variables.size() ||
|
|
secondVariableIndex >= variables.size())
|
|
return;
|
|
|
|
auto temp = variables[firstVariableIndex];
|
|
variables[firstVariableIndex] = variables[secondVariableIndex];
|
|
variables[secondVariableIndex] = temp;
|
|
}
|
|
|
|
void VariablesContainer::Move(std::size_t oldIndex, std::size_t newIndex) {
|
|
if (oldIndex >= variables.size() || newIndex >= variables.size() ||
|
|
oldIndex == newIndex)
|
|
return;
|
|
|
|
auto nameAndVariable = variables[oldIndex];
|
|
variables.erase(variables.begin() + oldIndex);
|
|
variables.insert(variables.begin() + newIndex, nameAndVariable);
|
|
}
|
|
|
|
void VariablesContainer::SerializeTo(SerializerElement& element) const {
|
|
element.ConsiderAsArrayOf("variable");
|
|
for (std::size_t j = 0; j < variables.size(); j++) {
|
|
SerializerElement& variableElement = element.AddChild("variable");
|
|
variableElement.SetAttribute("name", variables[j].first);
|
|
variables[j].second->SerializeTo(variableElement);
|
|
}
|
|
}
|
|
|
|
void VariablesContainer::UnserializeFrom(const SerializerElement& element) {
|
|
Clear();
|
|
element.ConsiderAsArrayOf("variable", "Variable");
|
|
for (std::size_t j = 0; j < element.GetChildrenCount(); j++) {
|
|
const SerializerElement& variableElement = element.GetChild(j);
|
|
|
|
Variable variable;
|
|
variable.UnserializeFrom(variableElement);
|
|
Insert(
|
|
variableElement.GetStringAttribute("name", "", "Name"), variable, -1);
|
|
}
|
|
}
|
|
|
|
VariablesContainer::VariablesContainer(const VariablesContainer& other) {
|
|
Init(other);
|
|
}
|
|
|
|
VariablesContainer& VariablesContainer::operator=(
|
|
const VariablesContainer& other) {
|
|
if (this != &other) Init(other);
|
|
|
|
return *this;
|
|
}
|
|
|
|
void VariablesContainer::Init(const gd::VariablesContainer& other) {
|
|
variables.clear();
|
|
for (auto& it : other.variables) {
|
|
variables.push_back(
|
|
std::make_pair(it.first, std::make_shared<gd::Variable>(*it.second)));
|
|
}
|
|
}
|
|
} // namespace gd
|