From edc35c371d137412f159a97fc44b499feecf84f5 Mon Sep 17 00:00:00 2001 From: Marko Semet Date: Tue, 9 Jul 2019 15:33:56 +0200 Subject: [PATCH] Vorgotten to add --- include/sirEdit/data/serialize.hpp | 29 +++ include/sirEdit/data/specUpdater.hpp | 268 ++++++++++++++++++++++++++- 2 files changed, 290 insertions(+), 7 deletions(-) diff --git a/include/sirEdit/data/serialize.hpp b/include/sirEdit/data/serialize.hpp index 71a270b..8978d30 100644 --- a/include/sirEdit/data/serialize.hpp +++ b/include/sirEdit/data/serialize.hpp @@ -160,6 +160,35 @@ namespace sirEdit::data { this->__serializer.removeTool(const_cast(&tool)); updateCall(this->__change_callback); } + void importTools(const std::vector& tools) { + std::unordered_map 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& callback_field, const std::function& callback_type) { // Set state FIELD_STATE old = tool.getFieldSetState(field, type); diff --git a/include/sirEdit/data/specUpdater.hpp b/include/sirEdit/data/specUpdater.hpp index a74596c..3378bcc 100644 --- a/include/sirEdit/data/specUpdater.hpp +++ b/include/sirEdit/data/specUpdater.hpp @@ -1,15 +1,18 @@ #pragma once #include #include +#include #include #include namespace sirEdit::data { class SpecModify { private: - std::unordered_map oldToNewType; - std::unordered_map oldToNewField; - std::vector fields; + mutable std::unordered_map oldToNewType; + mutable std::unordered_map oldToNewField; + std::unordered_set fields; + bool __hasCycle = false; + std::unordered_map> 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 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(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(newType) != nullptr || dynamic_cast(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 toAdd, std::function checkType = [](const Type* t) -> bool {return true; }, std::function checkField = [](const Field* t) -> bool {return true; }) { + void meltTypes(std::vector toAdd, std::function checkType = [](const Type* t) -> bool {return true; }, std::function 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(&j)); + } + } + + Tool parseTool(const Tool& tool, const std::vector& toolTypes) { + // Definitions + std::unordered_map> 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 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 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 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 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 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 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 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 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; } }; }