void Scope::Adopt(Scope& child, const std::string& key, std::uint32_t index) { if (key == std::string()) throw std::exception("Key cannot be an empty string."); child.Orphan(); child.mParent = this; // try to find entry first in this scope Datum* d = Find(key); if (d != nullptr) { if (d->GetType() != Datum::Table) throw std::exception("Found entry is not a table!"); if (d->IsExternal()) throw std::exception("Table is external. Cannot modify data owned by something else."); std::uint32_t originalDatumSize = d->Size(); // if a scope is empty or not pointing to anything at the given index, we can just have it point to something else if (originalDatumSize <= index || d->GetTable(index) == nullptr || d->GetTable(index)->mOrder.Size() == 0) d->Set(&child, index); // otherwise, we add in the child scope and rearrange the datum array if necessary else { if (index < originalDatumSize) { d->SetSize(originalDatumSize + 1); for (std::uint32_t i = originalDatumSize; i > index; --i) { d->Set(d->GetTable(i - 1), i); } } else if (index > originalDatumSize) { index = originalDatumSize; } d->Set(&child, index); } } else { Datum scopeDatum; scopeDatum = &child; std::pair<std::string, Datum> pair(key, scopeDatum); HashMap<std::string, Datum>::Iterator iterator = mTable.Insert(pair); mOrder.PushBack(&(*iterator)); } }
void Datum::StringToMatrix(Datum& data, const std::string inputString, const std::uint32_t index) { float a[16]; sscanf_s(inputString.c_str(), "((%f, %f, %f, %f), (%f, %f, %f, %f), (%f, %f, %f, %f), (%f, %f, %f, %f))", &a[0], &a[1], &a[2], &a[3], &a[4], &a[5], &a[6], &a[7], &a[8], &a[9], &a[10], &a[11], &a[12], &a[13], &a[14], &a[15]); auto temp = glm::mat4(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]); data.Set(temp, index); }
void Datum::StringToVector(Datum& data, const std::string inputString, const std::uint32_t index) { float a, b, c, d = 0.0f; sscanf_s(inputString.c_str(), "%f, %f, %f, %f", &a, &b, &c, &d); auto temp = glm::vec4(a, b, c, d); data.Set(temp, index); }
void Scope::Orphan() { std::string scopeName; if (mParent != nullptr) { #ifdef DEBUG assert(mParent->FindName(this, scopeName)); #else mParent->FindName(this, scopeName); #endif Datum* d = mParent->Find(scopeName); std::uint32_t datumSize = d->Size(); for (std::uint32_t i = 0; i < datumSize; ++i) { if (d->GetTable(i) == this) { d->Set((Scope*)nullptr, i); break; } } } mParent = nullptr; }
Scope& Scope::AppendScope(const std::string& key) { Datum* datum = Find(key); //TODO: Push Back when removing from Vector //Found key, check if type is table if (datum) { if (datum->IsExternal() || (datum->GetType() != Datum::DatumType::Table)) { throw std::exception("This Datum is not of the right type"); } Scope* newScope = new Scope(); newScope->mParent = this; datum->Set(newScope, datum->Size()); return *datum->GetScope(datum->Size() - 1); } else { //key not found Datum& d = Append(key, Datum::DatumType::Table); Scope* newScope = new Scope(); newScope->mParent = this; d.Set(newScope, 0); return *d.GetScope(0); } }
Scope& Scope::operator=(const Scope& rhs) { if (this != &rhs) { Orphan(); Clear(); mTable.Resize(rhs.mTable.Size()); // this should be OK to call since the hash map is empty after Clear() for (std::uint32_t i = 0; i < rhs.mOrder.Size(); ++i) { if (rhs.mOrder[i]->second.GetType() != Datum::Table) { Datum& d = Append(rhs.mOrder[i]->first); d = rhs.mOrder[i]->second; } else { std::uint32_t datumSize = rhs.mOrder[i]->second.Size(); for (std::uint32_t datumCounter = 0; datumCounter < datumSize; ++datumCounter) { Scope& s = AppendScope(rhs.mOrder[i]->first); // s is a reference to a scope Datum* scopeDatum = Find(rhs.mOrder[i]->first); // scopeDatum contains s Scope* scopePointer = rhs.mOrder[i]->second.GetTable(datumCounter); // scope pointer is a pointer to the corresponding scope in scopeDatum if (scopePointer == nullptr) scopeDatum->Set((Scope*)nullptr, datumCounter); // if the scope in the rhs datum is null, this scope should also be null else s = *scopePointer; // recursive call } } } } return *this; }
/** *Finds our parent entity and deletes it * *@param curState the current worldstate to reference during update *@exception thrown if we do not have a valid entity parent, or if our target Entity is not set */ void ActionDestroyEntity::Update(const Library::WorldState& curState) { //Ensure our target entity name is set if (mEntity == "") { throw std::exception("Our entity target cannot be unnamed!"); } Scope* scope = this; Entity* entity = nullptr; bool condition = false; //Iterate upwards to find our containing entity while (!condition) { //Get the action scope above us scope = scope->GetParent(); if (scope == nullptr) { throw std::exception("We do not have an Entity or ActionList parent! This is invalid."); } //Get our real parent, who is either an entity of an action list scope = scope->GetParent(); if (scope == nullptr) { throw std::exception("We do not have an Entity or ActionList parent! This is invalid."); } //See if our grandparent scope is an Entity entity = scope->As<Entity>(); //If our grandparent is an actionlist we need to keep iterating upwards through the heirarchy to find the containing Entity //Else, we can delete the entity if (entity != nullptr) { condition = true; } } //Get the scope that contains the entity Scope* targetParent = entity->GetParent(); //Remove the entity from the parent scope if (targetParent != nullptr) { Datum* target = targetParent->Find(mEntity); if (target != nullptr) { Scope* scope = target->Get<Scope*>(); scope->Orphan(); delete scope; target->Set((Scope*)nullptr); } } }
void Scope::Adopt(Scope& childToAdopt, const std::string& key, const std::uint32_t index) { if (childToAdopt.GetParent()) childToAdopt.Orphan(); Datum * foundDatum = Find(key); if (foundDatum) { if ((foundDatum->GetType() != Datum::DatumType::Table) || foundDatum->IsExternal()) throw std::exception("You are trying to adopt into a invalid scope"); if ((foundDatum->GetType() == Datum::DatumType::Table)) { if (index >= foundDatum->Size()) { foundDatum->Set(&childToAdopt, index); foundDatum->GetScope(index)->mParent = this; } else { Scope* temp = foundDatum->GetScope(index); foundDatum->Set(&childToAdopt, index); foundDatum->GetScope(index)->mParent = this; for (std::uint32_t i = index + 1; i < foundDatum->Size(); ++i) { Scope* temp2 = foundDatum->GetScope(i); foundDatum->Set(temp, i); temp = temp2; } foundDatum->Set(temp, foundDatum->Size()); } } } else { Datum& d = Append(key, Datum::DatumType::Table); d.Set(&childToAdopt); d.GetScope()->mParent = this; } }
//Add a fresh scope with a given name Scope& Scope::AppendScope(const std::string& name) { Datum d; d.SetType(Datum::TABLE); Scope *s = new Scope(10); s->mParent = this; d.Set(s); std::pair <std::string, Datum> newItem(name, d); Hashmap<std::string, Datum>::Iterator newLocation = mHashMap.Insert(newItem); std::pair <std::string, Datum> *itemAdress = &(*newLocation); mOrderVector.PushBack(itemAdress); return *s; }
void Scope::Orphan() { if (mParent != nullptr) { std::uint32_t index = 0; Datum* datum = mParent->FindNestedScope(this, index); if (datum == nullptr) { throw std::exception("You are not a child of this parent"); } datum->Set(static_cast<Scope*>(nullptr), index); mParent = nullptr; } }
Scope& Scope::AppendScope(const std::string& key) { if (key == std::string()) throw std::exception("Key cannot be an empty string."); Scope* newScope = new Scope(); newScope->mParent = this; // try to find entry first in this scope Datum* d = Find(key); if (d != nullptr) { if (d->GetType() != Datum::Table && d->GetType() != Datum::Unknown) { delete newScope; throw std::exception("Found entry is not a table!"); } if (d->IsExternal()) { delete newScope; throw std::exception("Table entry is external. Cannot modify data owned by something else."); } // a new scope gets added into this table datum std::uint32_t datumSize = d->Size(); d->Set(newScope, datumSize); return *d->GetTable(datumSize); } // if no entry is found, create new datum with this scope Datum scopeDatum; scopeDatum = newScope; std::pair<std::string, Datum> pair(key, scopeDatum); HashMap<std::string, Datum>::Iterator iterator = mTable.Insert(pair); mOrder.PushBack(&(*iterator)); return *(iterator->second.GetTable()); }
//Add a scope to our table with a given name and index void Scope::Adopt(Scope* newChild, const std::string& name, std::uint32_t index) { newChild->Orphan(); Hashmap<std::string, Datum>::Iterator it = mHashMap.Find(name); //If the new item isn't present, add it to the hash map if (it == mHashMap.end()) { newChild->mParent = this; Datum d; d.SetType(Datum::TABLE); d.Set(newChild); std::pair <std::string, Datum> newItem(name, d); Hashmap<std::string, Datum>::Iterator newLocation = mHashMap.Insert(newItem); std::pair <std::string, Datum> *itemAdress = &((*newLocation)); mOrderVector.PushBack(itemAdress); } //Otherwise, set the scope item to the given index in the datum else { //Ensure that the datum we're adopting into doesn't have external memory if ((*it).second.IsExternal()) { return; } (*it).second.Set(newChild, index); } }
void Datum::StringToString(Datum& data, const std::string inputString, const std::uint32_t index) { data.Set(inputString, index); }
void Datum::StringToFloat(Datum& data, const std::string inputString, const std::uint32_t index) { std::float_t temp = static_cast<std::float_t>(std::atof(inputString.c_str())); data.Set(temp, index); }
void Datum::StringToInteger(Datum& data, const std::string inputString, const std::uint32_t index) { std::int32_t temp = std::atoi(inputString.c_str()); data.Set(temp, index); }