Ejemplo n.º 1
0
	/**
	*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);
			}
		}
	}
	//Handle character data
	bool XMLParseHelperExpression::CharDataHandler(XmlParseMaster::SharedData* data, std::string charData, std::uint32_t length)
	{
		SharedDataWorld* reinterpereted = data->As<SharedDataWorld>();
		Scope* curAction = reinterpereted->GetAction();
		if (reinterpereted != nullptr && curAction != nullptr)
		{
			ActionExpression* ae = curAction->As<ActionExpression>();
			if (ae == nullptr)
			{
				return false;
			}

			/*
			Format for infix expressions

			lhs = operand1 operator1 operand2 operator2 ... operandN operatorN operandN+1

			*/

			//Read the char data into a string
			std::string stringData;

			for (std::uint32_t i = 0; i < length; i++)
			{
				stringData.push_back(charData[i]);
			}

			//Split the character data into tokens
			//The pieces of the expression are only seperated by whitespace
			SList<std::string> tokens;
			std::istringstream iss(stringData);
			std::string s;
			std::string s2;

			while (getline(iss, s, ' '))
			{
				tokens.PushBack(s);
			}

			//Get the table container refered to using the '.' syntax
			//If the table in question is 'this', then it is referring to a datum in the same scope as the action
			//Otherwise, we only allow for accessing other items in the same sector scope
			//If there is no '.' in the first token, we assume that the item in question is a datum declared in scope of the raw sector the entity containing this action is in
			//We check the raw sector case first

			Scope* container;

			if (tokens.Front().find('.') == std::string::npos)//Check if ther is no '.' character in the first token
			{
				if (reinterpereted->GetSector()->Find(tokens.Front()) != nullptr)//Check to see if the datum we're looking for is sitting in the raw sector
				{
					container = reinterpereted->GetSector();
					ae->SetTarget(container->Find(tokens.Front()));
				}
				else
				{
					throw std::exception("Container specified as  lvalue in expression could not be found");
				}
			}
			else
			{
				//Reset the stringtream so we can parse the before and after the '.'
				iss.str(tokens.Front());
				iss.clear();

				getline(iss, s, '.');
				getline(iss, s2);


				if (s == "this")
				{
					container = ae->GetContainer();

					//In the context of an ActionList, we need to go up the chain until we hit an entity
					/*while (container->Is("ActionList"))
					{
						container = ae->GetContainer();
					}*/
				}
				else
				{
					if (reinterpereted->GetSector()->Entities()->Find(s) != nullptr)//Check to see if the datum we're looking for is a part of another entity in this sector
					{
						container = reinterpereted->GetSector()->Entities()->Find(s)->Get<Scope*>();
					}
					else
					{
						throw std::exception("Container specified as lvalue in expression could not be found");
					}
				}


				if (container == nullptr)
				{
					throw std::exception("Container specified as lvalue in expression could not be found");
				}

				//Check that the first token refers to an lvalue that exists in the appropriate scope. Set it if it exists
				ae->SetTarget(container->Search(s2));
			}


			//If the target doesn't exist, things are bad
			if (ae->GetTarget() == nullptr)
			{
				throw std::exception("Expression target does not exist");
			}

			tokens.PopFront();

			//Check that the next token is the assignment operator "="
			if (tokens.Front() != "=")
			{
				throw std::exception("Expression missing assignment operator");
			}
			tokens.PopFront();			

			//Pass off the tokens to shunting yard
			ae->SetExpression(ShuntingYard(tokens));

			return true;
		}
		return false;
	}