Пример #1
0
/**
 * Initializes the game world with the attributes provided.
 **/
void CWorld::RegisterInit(const CStrW& mapFile, const CScriptValRooted& settings, int playerID)
{
	// Load the map, if one was specified
	if (mapFile.length())
	{
		VfsPath mapfilename = VfsPath(mapFile).ChangeExtension(L".pmp");
		CMapReader* reader = 0;

		try
		{
			reader = new CMapReader;
			CTriggerManager* pTriggerManager = NULL;
			reader->LoadMap(mapfilename, settings, m_Terrain,
				CRenderer::IsInitialised() ? g_Renderer.GetWaterManager() : NULL,
				CRenderer::IsInitialised() ? g_Renderer.GetSkyManager() : NULL,
				&g_LightEnv, m_pGame->GetView(),
				m_pGame->GetView() ? m_pGame->GetView()->GetCinema() : NULL,
				pTriggerManager, CRenderer::IsInitialised() ? &g_Renderer.GetPostprocManager() : NULL,
				m_pGame->GetSimulation2(), &m_pGame->GetSimulation2()->GetSimContext(), playerID, false);
				// fails immediately, or registers for delay loading
		}
		catch (PSERROR_File& err)
		{
			delete reader;
			LOGERROR(L"Failed to load map %ls: %hs", mapfilename.string().c_str(), err.what());
			throw PSERROR_Game_World_MapLoadFailed("Failed to load map.\nCheck application log for details.");
		}
	}
}
Пример #2
0
static CMap *ReadCMap(InputStream *pSource)
{
	CMap *pCMap;
	CMapReader *pReader;

	pCMap = new CMap();
	pReader = new CMapReader(pCMap);
	pReader->Read(pSource);
	delete pReader;
	return pCMap;
}
Пример #3
0
void CWorld::RegisterInitRMS(const CStrW& scriptFile, const CScriptValRooted& settings, int playerID)
{
	// If scriptFile is empty, a blank map will be generated using settings (no RMS run)
	CMapReader* reader = 0;

	reader = new CMapReader;
	CTriggerManager* pTriggerManager = NULL;
	reader->LoadRandomMap(scriptFile, settings, m_Terrain,
		CRenderer::IsInitialised() ? g_Renderer.GetWaterManager() : NULL,
		CRenderer::IsInitialised() ? g_Renderer.GetSkyManager() : NULL,
		&g_LightEnv, m_pGame->GetView(),
		m_pGame->GetView() ? m_pGame->GetView()->GetCinema() : NULL,
		pTriggerManager, CRenderer::IsInitialised() ? &g_Renderer.GetPostprocManager() : NULL,
		m_pGame->GetSimulation2(), playerID);
		// registers for delay loading
}
Пример #4
0
/** Loads a cmap and returns the corresponding object. */
CMap* CMapManager::lookup (const string &name) {
	CMaps::iterator it = _cmaps.find(name);
	if (it != _cmaps.end())
		return it->second;

	if (_includedCMaps.find(name) != _includedCMaps.end()) {
		_level = 0;
		ostringstream oss;
		oss << "circular reference of CMap " << name;
		throw CMapReaderException(oss.str());
	}

	CMap *cmap=0;
	if (name == "Identity-H")
		cmap = new IdentityHCMap;
	else if (name == "Identity-V")
		cmap = new IdentityVCMap;
	else if (name == "unicode")
		cmap = new UnicodeCMap;
	if (cmap) {
		_cmaps[name] = cmap;
		return cmap;
	}
	// Load cmap data of file <name> and also process all cmaps referenced by operator "usecmap".
	// This can lead to a sequence of further calls of lookup(). In order to prevent infinite loops
	// due to (disallowed) circular cmap inclusions, we keep track of all cmaps processed during
	// a sequence of inclusions.
	_includedCMaps.insert(name);  // save name of current cmap being processed
	_level++;                     // increase nesting level
	try {
		CMapReader reader;
		if (!(cmap = reader.read(name))) {
			_level = 1;
			Message::wstream(true) << "CMap file '" << name << "' not found\n";
		}
		_cmaps[name] = cmap;
	}
	catch (const CMapReaderException &e) {
		Message::estream(true) << "CMap file " << name << ": " << e.what() << "\n";
	}
	if (--_level == 0)            // back again at initial nesting level?
		_includedCMaps.clear();    // => names of included cmaps are no longer needed
	return cmap;
}
Пример #5
0
CMapReader *sw_maprd_read(const char *_szFilePath)
{
	FILE *fp;
	fp=fopen(_szFilePath,"rb");
	if(fp == 0)
	{
		return NULL;
	}

	CMapReader *mr = new CMapReader();
	if(mr->Read(fp) == true)
	{
		fclose(fp);

		return mr;
	}else
	{
		fclose(fp);
		delete mr;
		return NULL;
	}
}
Пример #6
0
void CSimulation2Impl::Update(int turnLength, const std::vector<SimulationCommand>& commands)
{
	PROFILE3("sim update");
	PROFILE2_ATTR("turn %d", (int)m_TurnNumber);

	fixed turnLengthFixed = fixed::FromInt(turnLength) / 1000;

	/*
	 * In serialization test mode, we save the original (primary) simulation state before each turn update.
	 * We run the update, then load the saved state into a secondary context.
	 * We serialize that again and compare to the original serialization (to check that
	 * serialize->deserialize->serialize is equivalent to serialize).
	 * Then we run the update on the secondary context, and check that its new serialized
	 * state matches the primary context after the update (to check that the simulation doesn't depend
	 * on anything that's not serialized).
	 */

	const bool serializationTestDebugDump = false; // set true to save human-readable state dumps before an error is detected, for debugging (but slow)
	const bool serializationTestHash = true; // set true to save and compare hash of state

	SerializationTestState primaryStateBefore;
	if (m_EnableSerializationTest)
	{
		ENSURE(m_ComponentManager.SerializeState(primaryStateBefore.state));
		if (serializationTestDebugDump)
			ENSURE(m_ComponentManager.DumpDebugState(primaryStateBefore.debug, false));
		if (serializationTestHash)
			ENSURE(m_ComponentManager.ComputeStateHash(primaryStateBefore.hash, false));
	}


	UpdateComponents(m_SimContext, turnLengthFixed, commands);


	if (m_EnableSerializationTest)
	{
		// Initialise the secondary simulation
		CTerrain secondaryTerrain;
		CSimContext secondaryContext;
		secondaryContext.m_Terrain = &secondaryTerrain;
		CComponentManager secondaryComponentManager(secondaryContext, m_ComponentManager.GetScriptInterface().GetRuntime());
		secondaryComponentManager.LoadComponentTypes();
		ENSURE(LoadDefaultScripts(secondaryComponentManager, NULL));
		ResetComponentState(secondaryComponentManager, false, false);

		// Load the map into the secondary simulation

		LDR_BeginRegistering();
		CMapReader* mapReader = new CMapReader; // automatically deletes itself

		// TODO: this duplicates CWorld::RegisterInit and could probably be cleaned up a bit
		std::string mapType;
		m_ComponentManager.GetScriptInterface().GetProperty(m_InitAttributes.get(), "mapType", mapType);
		if (mapType == "random")
		{
			// TODO: support random map scripts
			debug_warn(L"Serialization test mode only supports scenarios");
		}
		else
		{
			std::wstring mapFile;
			m_ComponentManager.GetScriptInterface().GetProperty(m_InitAttributes.get(), "map", mapFile);

			VfsPath mapfilename = VfsPath(mapFile).ChangeExtension(L".pmp");
			mapReader->LoadMap(mapfilename, CScriptValRooted(), &secondaryTerrain, NULL, NULL, NULL, NULL, NULL, NULL,
				NULL, NULL, &secondaryContext, INVALID_PLAYER, true); // throws exception on failure
		}
		LDR_EndRegistering();
		ENSURE(LDR_NonprogressiveLoad() == INFO::OK);

		ENSURE(secondaryComponentManager.DeserializeState(primaryStateBefore.state));

		SerializationTestState secondaryStateBefore;
		ENSURE(secondaryComponentManager.SerializeState(secondaryStateBefore.state));
		if (serializationTestDebugDump)
			ENSURE(secondaryComponentManager.DumpDebugState(secondaryStateBefore.debug, false));
		if (serializationTestHash)
			ENSURE(secondaryComponentManager.ComputeStateHash(secondaryStateBefore.hash, false));

		if (primaryStateBefore.state.str() != secondaryStateBefore.state.str() ||
			primaryStateBefore.hash != secondaryStateBefore.hash)
		{
			ReportSerializationFailure(&primaryStateBefore, NULL, &secondaryStateBefore, NULL);
		}

		SerializationTestState primaryStateAfter;
		ENSURE(m_ComponentManager.SerializeState(primaryStateAfter.state));
		if (serializationTestHash)
			ENSURE(m_ComponentManager.ComputeStateHash(primaryStateAfter.hash, false));

		UpdateComponents(secondaryContext, turnLengthFixed,
			CloneCommandsFromOtherContext(m_ComponentManager.GetScriptInterface(), secondaryComponentManager.GetScriptInterface(), commands));

		SerializationTestState secondaryStateAfter;
		ENSURE(secondaryComponentManager.SerializeState(secondaryStateAfter.state));
		if (serializationTestHash)
			ENSURE(secondaryComponentManager.ComputeStateHash(secondaryStateAfter.hash, false));

		if (primaryStateAfter.state.str() != secondaryStateAfter.state.str() ||
			primaryStateAfter.hash != secondaryStateAfter.hash)
		{
			// Only do the (slow) dumping now we know we're going to need to report it
			ENSURE(m_ComponentManager.DumpDebugState(primaryStateAfter.debug, false));
			ENSURE(secondaryComponentManager.DumpDebugState(secondaryStateAfter.debug, false));

			ReportSerializationFailure(&primaryStateBefore, &primaryStateAfter, &secondaryStateBefore, &secondaryStateAfter);
		}
	}

//	if (m_TurnNumber == 0)
//		m_ComponentManager.GetScriptInterface().DumpHeap();

	// Run the GC occasionally
	// (TODO: we ought to schedule this for a frame where we're not
	// running the sim update, to spread the load)
	if (m_TurnNumber % 1 == 0)
		m_ComponentManager.GetScriptInterface().MaybeIncrementalRuntimeGC();

	if (m_EnableOOSLog)
		DumpState();

	// Start computing AI for the next turn
	CmpPtr<ICmpAIManager> cmpAIManager(m_SimContext, SYSTEM_ENTITY);
	if (cmpAIManager)
		cmpAIManager->StartComputation();

	++m_TurnNumber;
}
Пример #7
0
void CSimulation2Impl::Update(int turnLength, const std::vector<SimulationCommand>& commands)
{
	PROFILE3("sim update");
	PROFILE2_ATTR("turn %d", (int)m_TurnNumber);

	fixed turnLengthFixed = fixed::FromInt(turnLength) / 1000;

	/*
	 * In serialization test mode, we save the original (primary) simulation state before each turn update.
	 * We run the update, then load the saved state into a secondary context.
	 * We serialize that again and compare to the original serialization (to check that
	 * serialize->deserialize->serialize is equivalent to serialize).
	 * Then we run the update on the secondary context, and check that its new serialized
	 * state matches the primary context after the update (to check that the simulation doesn't depend
	 * on anything that's not serialized).
	 */

	const bool serializationTestDebugDump = false; // set true to save human-readable state dumps before an error is detected, for debugging (but slow)
	const bool serializationTestHash = true; // set true to save and compare hash of state

	SerializationTestState primaryStateBefore;
	ScriptInterface& scriptInterface = m_ComponentManager.GetScriptInterface();

	if (m_EnableSerializationTest)
	{
		ENSURE(m_ComponentManager.SerializeState(primaryStateBefore.state));
		if (serializationTestDebugDump)
			ENSURE(m_ComponentManager.DumpDebugState(primaryStateBefore.debug, false));
		if (serializationTestHash)
			ENSURE(m_ComponentManager.ComputeStateHash(primaryStateBefore.hash, false));
	}

	UpdateComponents(m_SimContext, turnLengthFixed, commands);


	if (m_EnableSerializationTest)
	{
		// Initialise the secondary simulation
		CTerrain secondaryTerrain;
		CSimContext secondaryContext;
		secondaryContext.m_Terrain = &secondaryTerrain;
		CComponentManager secondaryComponentManager(secondaryContext, scriptInterface.GetRuntime());
		secondaryComponentManager.LoadComponentTypes();
		std::set<VfsPath> secondaryLoadedScripts;
		ENSURE(LoadDefaultScripts(secondaryComponentManager, &secondaryLoadedScripts));
		ResetComponentState(secondaryComponentManager, false, false);

		// Load the trigger scripts after we have loaded the simulation.
		{
			JSContext* cx2 = secondaryComponentManager.GetScriptInterface().GetContext();
			JSAutoRequest rq2(cx2);
			JS::RootedValue mapSettingsCloned(cx2, 
				secondaryComponentManager.GetScriptInterface().CloneValueFromOtherContext(
					scriptInterface, m_MapSettings));
			ENSURE(LoadTriggerScripts(secondaryComponentManager, mapSettingsCloned, &secondaryLoadedScripts));
		}

		// Load the map into the secondary simulation

		LDR_BeginRegistering();
		CMapReader* mapReader = new CMapReader; // automatically deletes itself
			
		std::string mapType;
		scriptInterface.GetProperty(m_InitAttributes, "mapType", mapType);
		if (mapType == "random")
		{
			// TODO: support random map scripts
			debug_warn(L"Serialization test mode does not support random maps");
		}
		else
		{
			std::wstring mapFile;
			scriptInterface.GetProperty(m_InitAttributes, "map", mapFile);

			VfsPath mapfilename = VfsPath(mapFile).ChangeExtension(L".pmp");
			mapReader->LoadMap(mapfilename, scriptInterface.GetJSRuntime(), JS::UndefinedHandleValue,
				&secondaryTerrain, NULL, NULL, NULL, NULL, NULL, NULL,
				NULL, NULL, &secondaryContext, INVALID_PLAYER, true); // throws exception on failure
		}

		LDR_EndRegistering();
		ENSURE(LDR_NonprogressiveLoad() == INFO::OK);

		ENSURE(secondaryComponentManager.DeserializeState(primaryStateBefore.state));

		SerializationTestState secondaryStateBefore;
		ENSURE(secondaryComponentManager.SerializeState(secondaryStateBefore.state));
		if (serializationTestDebugDump)
			ENSURE(secondaryComponentManager.DumpDebugState(secondaryStateBefore.debug, false));
		if (serializationTestHash)
			ENSURE(secondaryComponentManager.ComputeStateHash(secondaryStateBefore.hash, false));

		if (primaryStateBefore.state.str() != secondaryStateBefore.state.str() ||
			primaryStateBefore.hash != secondaryStateBefore.hash)
		{
			ReportSerializationFailure(&primaryStateBefore, NULL, &secondaryStateBefore, NULL);
		}

		SerializationTestState primaryStateAfter;
		ENSURE(m_ComponentManager.SerializeState(primaryStateAfter.state));
		if (serializationTestHash)
			ENSURE(m_ComponentManager.ComputeStateHash(primaryStateAfter.hash, false));

		UpdateComponents(secondaryContext, turnLengthFixed,
			CloneCommandsFromOtherContext(scriptInterface, secondaryComponentManager.GetScriptInterface(), commands));
		SerializationTestState secondaryStateAfter;
		ENSURE(secondaryComponentManager.SerializeState(secondaryStateAfter.state));
		if (serializationTestHash)
			ENSURE(secondaryComponentManager.ComputeStateHash(secondaryStateAfter.hash, false));

		if (primaryStateAfter.state.str() != secondaryStateAfter.state.str() ||
			primaryStateAfter.hash != secondaryStateAfter.hash)
		{
			// Only do the (slow) dumping now we know we're going to need to report it
			ENSURE(m_ComponentManager.DumpDebugState(primaryStateAfter.debug, false));
			ENSURE(secondaryComponentManager.DumpDebugState(secondaryStateAfter.debug, false));

			ReportSerializationFailure(&primaryStateBefore, &primaryStateAfter, &secondaryStateBefore, &secondaryStateAfter);
		}
	}

//	if (m_TurnNumber == 0)
//		m_ComponentManager.GetScriptInterface().DumpHeap();

	// Run the GC occasionally
	// No delay because a lot of garbage accumulates in one turn and in non-visual replays there are
	// much more turns in the same time than in normal games.
	// Every 500 turns we run a shrinking GC, which decommits unused memory and frees all JIT code.
	// Based on testing, this seems to be a good compromise between memory usage and performance.
	// Also check the comment about gcPreserveCode in the ScriptInterface code and this forum topic:
	// http://www.wildfiregames.com/forum/index.php?showtopic=18466&p=300323
	//
	// (TODO: we ought to schedule this for a frame where we're not
	// running the sim update, to spread the load)
	if (m_TurnNumber % 500 == 0)
		scriptInterface.GetRuntime()->ShrinkingGC();
	else
		scriptInterface.GetRuntime()->MaybeIncrementalGC(0.0f);

	if (m_EnableOOSLog)
		DumpState();

	// Start computing AI for the next turn
	CmpPtr<ICmpAIManager> cmpAIManager(m_SimContext, SYSTEM_ENTITY);
	if (cmpAIManager)
		cmpAIManager->StartComputation();

	++m_TurnNumber;
}
Пример #8
0
		CMapReaderTest () {
			istringstream iss(cmapsrc);
			CMapReader reader;
			cmap = reader.read(iss, "Test-Map");
		}