Esempio n. 1
0
entity_id_t CComponentManager::AddEntity(const std::wstring& templateName, entity_id_t ent)
{
	ICmpTemplateManager *cmpTemplateManager = static_cast<ICmpTemplateManager*> (QueryInterface(SYSTEM_ENTITY, IID_TemplateManager));
	if (!cmpTemplateManager)
	{
		debug_warn(L"No ICmpTemplateManager loaded");
		return INVALID_ENTITY;
	}

	// TODO: should assert that ent doesn't exist

	const CParamNode* tmpl = cmpTemplateManager->LoadTemplate(ent, utf8_from_wstring(templateName), -1);
	if (!tmpl)
		return INVALID_ENTITY; // LoadTemplate will have reported the error

	CEntityHandle handle = AllocateEntityHandle(ent);

	// Construct a component for each child of the root element
	const CParamNode::ChildrenMap& tmplChilds = tmpl->GetChildren();
	for (CParamNode::ChildrenMap::const_iterator it = tmplChilds.begin(); it != tmplChilds.end(); ++it)
	{
		// Ignore attributes on the root element
		if (it->first.length() && it->first[0] == '@')
			continue;

		CComponentManager::ComponentTypeId cid = LookupCID(it->first);
		if (cid == CID__Invalid)
		{
			LOGERROR(L"Unrecognised component type name '%hs' in entity template '%ls'", it->first.c_str(), templateName.c_str());
			return INVALID_ENTITY;
		}

		if (!AddComponent(handle, cid, it->second))
		{
			LOGERROR(L"Failed to construct component type name '%hs' in entity template '%ls'", it->first.c_str(), templateName.c_str());
			return INVALID_ENTITY;
		}
		// TODO: maybe we should delete already-constructed components if one of them fails?
	}

	CMessageCreate msg(ent);
	PostMessage(ent, msg);

	return ent;
}
Esempio n. 2
0
bool CComponentManager::DeserializeState(std::istream& stream)
{
	CStdDeserializer deserializer(m_ScriptInterface, stream);

	ResetState();

	std::string rng;
	deserializer.StringASCII("rng", rng, 0, 32);
	DeserializeRNG(rng, m_RNG);

	deserializer.NumberU32_Unbounded("next entity id", m_NextEntityId); // TODO: use sensible bounds

	uint32_t numComponentTypes;
	deserializer.NumberU32_Unbounded("num component types", numComponentTypes);

	ICmpTemplateManager* templateManager = NULL;
	CParamNode noParam;

	for (size_t i = 0; i < numComponentTypes; ++i)
	{
		std::string ctname;
		deserializer.StringASCII("name", ctname, 0, 255);

		ComponentTypeId ctid = LookupCID(ctname);
		if (ctid == CID__Invalid)
		{
			LOGERROR(L"Deserialization saw unrecognised component type '%hs'", ctname.c_str());
			return false;
		}

		uint32_t numComponents;
		deserializer.NumberU32_Unbounded("num components", numComponents);

		for (size_t j = 0; j < numComponents; ++j)
		{
			entity_id_t ent;
			deserializer.NumberU32_Unbounded("entity id", ent);
			IComponent* component = ConstructComponent(ent, ctid);
			if (!component)
				return false;

			// Try to find the template for this entity
			const CParamNode* entTemplate = NULL;
			if (templateManager && ent != SYSTEM_ENTITY) // (system entities don't use templates)
				entTemplate = templateManager->LoadLatestTemplate(ent);

			// Deserialize, with the appropriate template for this component
			if (entTemplate)
				component->Deserialize(entTemplate->GetChild(ctname.c_str()), deserializer);
			else
				component->Deserialize(noParam, deserializer);

			// If this was the template manager, remember it so we can use it when
			// deserializing any further non-system entities
			if (ent == SYSTEM_ENTITY && ctid == CID_TemplateManager)
				templateManager = static_cast<ICmpTemplateManager*> (component);
		}
	}

	if (stream.peek() != EOF)
	{
		LOGERROR(L"Deserialization didn't reach EOF");
		return false;
	}

	// TODO: catch exceptions
	return true;
}