void Scope::Clear() { //Delete allocated memory for (std::uint32_t i = 0; i < mOrderVector.Size(); i++) { if (mOrderVector[i]->second.GetType() == Datum::TABLE && !mOrderVector[i]->second.IsExternal()) { for (std::uint32_t j = 0; j < mOrderVector[i]->second.Size(); j++) { if (!mOrderVector[i]->second.IsExternal()) { Scope *temp = mOrderVector[i]->second.Get<Scope*>(j); if (temp != nullptr) { if (temp->mParent != nullptr) { delete temp; } else { temp->Orphan(); } } } } } } mHashMap.Clear(); mOrderVector.Clear(); }
/** *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& 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 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; } }