Vorgotten to add
parent
4ec86937fd
commit
edc35c371d
|
@ -160,6 +160,35 @@ namespace sirEdit::data {
|
|||
this->__serializer.removeTool(const_cast<Tool*>(&tool));
|
||||
updateCall(this->__change_callback);
|
||||
}
|
||||
void importTools(const std::vector<Tool*>& tools) {
|
||||
std::unordered_map<std::string, const Tool*> toolNames; // load tool names
|
||||
for(auto& i : this->__serializer.getTools())
|
||||
toolNames[i->getName()] = i;
|
||||
|
||||
// Add tools
|
||||
for(auto& i : tools) {
|
||||
size_t counter = 1;
|
||||
while(true) {
|
||||
// Generate name for tool
|
||||
std::string name = i->getName();
|
||||
if(counter > 1)
|
||||
name += "(" + std::to_string(counter) + ")";
|
||||
|
||||
// Try to insert tool
|
||||
auto tmp = toolNames.find(name);
|
||||
if(tmp == toolNames.end()) {
|
||||
toolNames[name] = i;
|
||||
Tool* tmp2 = new Tool(*i);
|
||||
tmp2->getName() = name;
|
||||
this->__serializer.addTool(tmp2);
|
||||
break;
|
||||
}
|
||||
else
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
updateCall(this->__change_callback);
|
||||
}
|
||||
void setFieldStatus(const Tool& tool, const Type& type, const Field& field, FIELD_STATE state, const std::function<void(const Type&, const Field&, FIELD_STATE, FIELD_STATE)>& callback_field, const std::function<void(const Type&, TYPE_STATE, TYPE_STATE)>& callback_type) {
|
||||
// Set state
|
||||
FIELD_STATE old = tool.getFieldSetState(field, type);
|
||||
|
|
|
@ -1,15 +1,18 @@
|
|||
#pragma once
|
||||
#include <sirEdit/data/tools.hpp>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <functional>
|
||||
#include <algorithm>
|
||||
|
||||
namespace sirEdit::data {
|
||||
class SpecModify {
|
||||
private:
|
||||
std::unordered_map<const Type*, const Type*> oldToNewType;
|
||||
std::unordered_map<const Field*, const Field*> oldToNewField;
|
||||
std::vector<Field*> fields;
|
||||
mutable std::unordered_map<const Type*, const Type*> oldToNewType;
|
||||
mutable std::unordered_map<const Field*, const Field*> oldToNewField;
|
||||
std::unordered_set<Field*> fields;
|
||||
bool __hasCycle = false;
|
||||
std::unordered_map<const Field*, std::vector<Field*>> requiredViews;
|
||||
|
||||
bool compareType(const Type& a, const Type& b) const {
|
||||
if(a.getName() != b.getName() ||
|
||||
|
@ -46,7 +49,9 @@ namespace sirEdit::data {
|
|||
}
|
||||
|
||||
Type* typeCopy(const Type* source, Type* super) {
|
||||
return doBaseType(source, [source]()-> Type* {
|
||||
// Create new type
|
||||
Type* result = doBaseType(source, [source]()-> Type* {
|
||||
return new Type(source->getName(), source->getComment());
|
||||
}, [source, super]() -> Type* {
|
||||
return new TypeInterface(source->getName(), source->getComment(), {}, {}, super);
|
||||
}, [source, super]() -> Type* {
|
||||
|
@ -63,6 +68,13 @@ namespace sirEdit::data {
|
|||
std::vector<Type*> types;
|
||||
|
||||
const Type* findType(const Type& like) const {
|
||||
// Try to use cache
|
||||
{
|
||||
auto tmp = this->oldToNewType.find(&like);
|
||||
if(tmp != this->oldToNewType.end())
|
||||
return tmp->second;
|
||||
}
|
||||
|
||||
for(auto i : this->types) {
|
||||
if(this->compareType(like, *i))
|
||||
return i;
|
||||
|
@ -75,8 +87,15 @@ namespace sirEdit::data {
|
|||
return i;
|
||||
}
|
||||
return nullptr;
|
||||
|
||||
// Update cache and return
|
||||
if(result != nullptr)
|
||||
this->oldToNewField[&like] = result;
|
||||
return result;
|
||||
}
|
||||
|
||||
Type* addType(const Type* reference) {
|
||||
// Check if allready exists
|
||||
auto res = this->findType(*reference);
|
||||
if(res != nullptr)
|
||||
return const_cast<Type*>(res);
|
||||
|
@ -86,14 +105,22 @@ namespace sirEdit::data {
|
|||
if(super != nullptr)
|
||||
super = this->addType(super);
|
||||
Type* newType = this->typeCopy(reference, super);
|
||||
this->types.push_back(newType);
|
||||
if(dynamic_cast<TypeWithFields*>(newType) != nullptr || dynamic_cast<TypeEnum*>(newType) != nullptr) // Don't add base types!
|
||||
this->types.push_back(newType);
|
||||
|
||||
// Add to cache and return
|
||||
this->oldToNewType.insert({reference, newType});
|
||||
this->oldToNewType.insert({newType, newType}); // Can optimse things
|
||||
return newType;
|
||||
}
|
||||
|
||||
void meldTypes(std::vector<const Type*> toAdd, std::function<bool(const Type*)> checkType = [](const Type* t) -> bool {return true; }, std::function<bool(const Field*)> checkField = [](const Field* t) -> bool {return true; }) {
|
||||
void meltTypes(std::vector<const Type*> toAdd, std::function<bool(const Type*)> checkType = [](const Type* t) -> bool {return true; }, std::function<bool(const Field*)> checkField = [](const Field* t) -> bool {return true; }) {
|
||||
// Add all types
|
||||
for(auto i : toAdd)
|
||||
if(checkType(i))
|
||||
this->addType(i);
|
||||
|
||||
// Update type context
|
||||
for(auto i : toAdd) {
|
||||
if(!checkType(i))
|
||||
continue;
|
||||
|
@ -109,9 +136,236 @@ namespace sirEdit::data {
|
|||
}
|
||||
|
||||
// TODO:
|
||||
|
||||
void updateFields() {
|
||||
for(auto& i : this->types) {
|
||||
oldToNewType[i] = i;
|
||||
for(auto& j : getFields(*i))
|
||||
this->fields.insert(const_cast<Field*>(&j));
|
||||
}
|
||||
}
|
||||
|
||||
Tool parseTool(const Tool& tool, const std::vector<const Type*>& toolTypes) {
|
||||
// Definitions
|
||||
std::unordered_map<std::string, std::vector<Type*>> toolNames; // Find type names
|
||||
for(auto& i : this->types) {
|
||||
auto tmp = toolNames.find(i->getName());
|
||||
if(tmp == toolNames.end())
|
||||
toolNames[i->getName()] = {i};
|
||||
else
|
||||
tmp->second.push_back(i);
|
||||
}
|
||||
|
||||
// TODO: check circles
|
||||
std::function<const Type*(const Type&)> findType = [&](const Type& type) -> const Type* { // Find type
|
||||
// Allready now
|
||||
{
|
||||
auto tmp = this->oldToNewType.find(&type);
|
||||
if(tmp != this->oldToNewType.end())
|
||||
return tmp->second;
|
||||
}
|
||||
|
||||
// Get candidates (name)
|
||||
std::unordered_set<const Type*> candidates;
|
||||
for(auto& i : this->types)
|
||||
if(i->getName() == type.getName())
|
||||
candidates.insert(i);
|
||||
if(candidates.size() == 1)
|
||||
return *(candidates.begin());
|
||||
if(candidates.size() == 0)
|
||||
return nullptr;
|
||||
|
||||
// Get check if super same
|
||||
{
|
||||
std::unordered_set<const Type*> tmp;
|
||||
for(auto& i : candidates) {
|
||||
if((getSuper(*i) == nullptr) != (getSuper(type) == nullptr))
|
||||
continue;
|
||||
if(findType(type) == findType(*i))
|
||||
tmp.insert(i);
|
||||
}
|
||||
candidates = std::move(tmp);
|
||||
}
|
||||
if(candidates.size() == 1)
|
||||
return *(candidates.begin());
|
||||
if(candidates.size() == 0)
|
||||
return nullptr;
|
||||
|
||||
// Be exact
|
||||
{
|
||||
std::unordered_set<const Type*> tmp;
|
||||
for(auto& i : candidates) {
|
||||
if(i->getComment() != type.getComment())
|
||||
continue;
|
||||
if(i->getHints() != type.getHints() || i->getRestrictions() != type.getRestrictions())
|
||||
continue;
|
||||
if(i->getMetaTypeName() == type.getMetaTypeName())
|
||||
continue;
|
||||
tmp.insert(i);
|
||||
}
|
||||
candidates = std::move(tmp);
|
||||
}
|
||||
if(candidates.size() == 0)
|
||||
return nullptr;
|
||||
else
|
||||
return *(candidates.begin());
|
||||
};
|
||||
|
||||
std::function<const Field*(const Field&, const Type* type)> findField = [&](const Field& field, const Type* typeTmp) -> const Field* { // Find field
|
||||
// Find type
|
||||
{
|
||||
for(auto& i : toolTypes)
|
||||
if(typeTmp == nullptr) {
|
||||
for(auto& j : getFields(*i))
|
||||
if(&j == &field) {
|
||||
typeTmp = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
break;
|
||||
if(typeTmp == nullptr)
|
||||
return nullptr;
|
||||
}
|
||||
const Type& type = *typeTmp;
|
||||
|
||||
// Find fields (by name)
|
||||
std::unordered_set<const Field*> candidates;
|
||||
for(auto& i : getFields(type))
|
||||
if(i.getName() == field.getName())
|
||||
candidates.insert(&i);
|
||||
if(candidates.size() == 1)
|
||||
return *(candidates.begin());
|
||||
if(candidates.size() == 0)
|
||||
return nullptr;
|
||||
|
||||
// Find by type
|
||||
{
|
||||
std::unordered_set<const Field*> tmp;
|
||||
for(auto& i : candidates) {
|
||||
if(i->getType().combination != field.getType().combination ||
|
||||
i->getType().arraySize != field.getType().arraySize)
|
||||
continue;
|
||||
if(i->getMeta().type != field.getMeta().type ||
|
||||
i->getMeta().isAuto != field.getMeta().isAuto ||
|
||||
i->getMeta().customeLanguage != field.getMeta().customeLanguage ||
|
||||
i->getMeta().customeTypename != field.getMeta().customeTypename ||
|
||||
i->getMeta().customeOptions != field.getMeta().customeOptions ||
|
||||
i->getMeta().view != field.getMeta().view)
|
||||
continue;
|
||||
if(field.getType().types.size() != i->getType().types.size())
|
||||
continue;
|
||||
bool tmp3 = false;
|
||||
for(auto& j : field.getType().types) {
|
||||
auto tmp2 = findType(*j);
|
||||
if(tmp2 == nullptr || tmp2 != findType(*j)) {
|
||||
tmp3 = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(tmp3)
|
||||
continue;
|
||||
if((field.getMeta().view == nullptr) != (i->getMeta().view == nullptr))
|
||||
continue;
|
||||
if(findField(*(i->getMeta().view), nullptr) != findField(*(field.getMeta().view), nullptr))
|
||||
continue;
|
||||
tmp.insert(i);
|
||||
}
|
||||
candidates = std::move(tmp);
|
||||
}
|
||||
if(candidates.size() == 1)
|
||||
return *(candidates.begin());
|
||||
if(candidates.size() == 0)
|
||||
return nullptr;
|
||||
|
||||
// Be exact
|
||||
{
|
||||
std::unordered_set<const Field*> tmp;
|
||||
for(auto& i : candidates) {
|
||||
if(i->getComment() != type.getComment())
|
||||
continue;
|
||||
if(i->getHints() != type.getHints() || i->getRestrictions() != type.getRestrictions())
|
||||
continue;
|
||||
tmp.insert(i);
|
||||
}
|
||||
candidates = std::move(tmp);
|
||||
}
|
||||
if(candidates.size() == 0)
|
||||
return nullptr;
|
||||
else
|
||||
return *(candidates.begin());
|
||||
};
|
||||
|
||||
// Update tool
|
||||
Tool result = tool;
|
||||
result.getStatesFields().clear();
|
||||
result.getStatesTypes().clear();
|
||||
|
||||
// Update fields
|
||||
for(auto& i : tool.getStatesFields())
|
||||
for(auto& j : i.second) {
|
||||
if(j.second == FIELD_STATE::NO) // Not important
|
||||
continue;
|
||||
const Type* type = findType(*(j.first));
|
||||
const Field* field = nullptr;
|
||||
if(type != nullptr)
|
||||
field = findField(*(i.first), type);
|
||||
if(type == nullptr || field == nullptr) { // Not found
|
||||
if(result.getName().size() == 0 || result.getName()[0] != '!')
|
||||
result.getName() = "!" + result.getName();
|
||||
result.getDescription() += "\n" + j.first->getName() + "." + i.first->getName() + " was ";
|
||||
switch(j.second) {
|
||||
case FIELD_STATE::UNUSED:
|
||||
result.getDescription() += "UNUSED";
|
||||
break;
|
||||
case FIELD_STATE::READ:
|
||||
result.getDescription() += "READ";
|
||||
break;
|
||||
case FIELD_STATE::WRITE:
|
||||
result.getDescription() += "WRITE";
|
||||
break;
|
||||
case FIELD_STATE::CREATE:
|
||||
result.getDescription() += "CREATE";
|
||||
break;
|
||||
default:
|
||||
throw; // Should never happen!
|
||||
}
|
||||
}
|
||||
else
|
||||
result.setFieldState(*type, *field, j.second);
|
||||
}
|
||||
|
||||
// Update type
|
||||
for(auto& i : tool.getStatesTypes()) {
|
||||
if(std::get<1>(i.second) == TYPE_STATE::NO) // Not important
|
||||
continue;
|
||||
const Type* type = findType(*(i.first));
|
||||
if(type == nullptr) {
|
||||
if(result.getName().size() == 0 || result.getName()[0] != '!')
|
||||
result.getName() = "!" + result.getName();
|
||||
result.getDescription() += "\n" + i.first->getName() + " was ";
|
||||
switch(std::get<1>(i.second)) {
|
||||
case TYPE_STATE::UNUSED:
|
||||
result.getDescription() += "UNUSED";
|
||||
break;
|
||||
case TYPE_STATE::READ:
|
||||
result.getDescription() += "READ";
|
||||
break;
|
||||
case TYPE_STATE::WRITE:
|
||||
result.getDescription() += "WRITE";
|
||||
break;
|
||||
case TYPE_STATE::DELETE:
|
||||
result.getDescription() += "DELETE";
|
||||
break;
|
||||
default:
|
||||
throw; // Should never happen!
|
||||
}
|
||||
}
|
||||
else
|
||||
result.setTypeState(*type, std::get<1>(i.second));
|
||||
}
|
||||
|
||||
// Return tool
|
||||
return result;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue