Ticket #3647: clone_commands_for_serializationtest_v1.patch

File clone_commands_for_serializationtest_v1.patch, 6.3 KB (added by elexis, 8 years ago)

Fixes the bug, but should be optimized performance-wise as this patch initializes the secondary context and component manager in non-serializationtestmode too.

  • source/simulation2/Simulation2.cpp

    void CSimulation2Impl::Update(int turnLe  
    330330
    331331    fixed turnLengthFixed = fixed::FromInt(turnLength) / 1000;
    332332
    333333    /*
    334334     * In serialization test mode, we save the original (primary) simulation state before each turn update.
    335335     * We run the update, then load the saved state into a secondary context.
    336336     * We serialize that again and compare to the original serialization (to check that
    337337     * serialize->deserialize->serialize is equivalent to serialize).
    338338     * Then we run the update on the secondary context, and check that its new serialized
    339339     * state matches the primary context after the update (to check that the simulation doesn't depend
    340340     * on anything that's not serialized).
    341341     */
    342342
    343343    const bool serializationTestDebugDump = false; // set true to save human-readable state dumps before an error is detected, for debugging (but slow)
    344344    const bool serializationTestHash = true; // set true to save and compare hash of state
    345345
    346346    SerializationTestState primaryStateBefore;
    347347    ScriptInterface& scriptInterface = m_ComponentManager.GetScriptInterface();
    348348
     349    // Initialise the secondary simulation
     350    CTerrain secondaryTerrain;
     351    CSimContext secondaryContext;
     352    secondaryContext.m_Terrain = &secondaryTerrain;
     353    CComponentManager secondaryComponentManager(secondaryContext, scriptInterface.GetRuntime());
     354    std::vector<SimulationCommand> clonedCommands;
     355    SerializationTestState secondaryStateBefore;
    349356    if (m_EnableSerializationTest)
    350357    {
    351358        ENSURE(m_ComponentManager.SerializeState(primaryStateBefore.state));
    352359        if (serializationTestDebugDump)
    353360            ENSURE(m_ComponentManager.DumpDebugState(primaryStateBefore.debug, false));
    354361        if (serializationTestHash)
    355362            ENSURE(m_ComponentManager.ComputeStateHash(primaryStateBefore.hash, false));
    356     }
    357 
    358     UpdateComponents(m_SimContext, turnLengthFixed, commands);
    359363
    360 
    361     if (m_EnableSerializationTest)
    362     {
    363         // Initialise the secondary simulation
    364         CTerrain secondaryTerrain;
    365         CSimContext secondaryContext;
    366         secondaryContext.m_Terrain = &secondaryTerrain;
    367         CComponentManager secondaryComponentManager(secondaryContext, scriptInterface.GetRuntime());
    368364        secondaryComponentManager.LoadComponentTypes();
    369365        std::set<VfsPath> secondaryLoadedScripts;
    370366        ENSURE(LoadDefaultScripts(secondaryComponentManager, &secondaryLoadedScripts));
    371367        ResetComponentState(secondaryComponentManager, false, false);
    372368
     369        // Clone commands before UpdateComponents() might modify them in the primary simulation
     370        clonedCommands = CloneCommandsFromOtherContext(scriptInterface, secondaryComponentManager.GetScriptInterface(), commands);
     371
    373372        // Load the trigger scripts after we have loaded the simulation.
    374373        {
    375374            JSContext* cx2 = secondaryComponentManager.GetScriptInterface().GetContext();
    376375            JSAutoRequest rq2(cx2);
    377376            JS::RootedValue mapSettingsCloned(cx2,
    378377                secondaryComponentManager.GetScriptInterface().CloneValueFromOtherContext(
    379378                    scriptInterface, m_MapSettings));
    380379            ENSURE(LoadTriggerScripts(secondaryComponentManager, mapSettingsCloned, &secondaryLoadedScripts));
    381380        }
    382381
    383382        // Load the map into the secondary simulation
    384383
    385384        LDR_BeginRegistering();
    386385        CMapReader* mapReader = new CMapReader; // automatically deletes itself
    387386           
    388387        std::string mapType;
    389388        scriptInterface.GetProperty(m_InitAttributes, "mapType", mapType);
    390389        if (mapType == "random")
    391390        {
    392391            // TODO: support random map scripts
    393392            debug_warn(L"Serialization test mode does not support random maps");
    394393        }
    395394        else
    396395        {
    397396            std::wstring mapFile;
    398397            scriptInterface.GetProperty(m_InitAttributes, "map", mapFile);
    399398
    400399            VfsPath mapfilename = VfsPath(mapFile).ChangeExtension(L".pmp");
    401400            mapReader->LoadMap(mapfilename, scriptInterface.GetJSRuntime(), JS::UndefinedHandleValue,
    402401                &secondaryTerrain, NULL, NULL, NULL, NULL, NULL, NULL,
    403402                NULL, NULL, &secondaryContext, INVALID_PLAYER, true); // throws exception on failure
    404403        }
    405404
    406405        LDR_EndRegistering();
    407406        ENSURE(LDR_NonprogressiveLoad() == INFO::OK);
    408407
    409408        ENSURE(secondaryComponentManager.DeserializeState(primaryStateBefore.state));
    410409
    411         SerializationTestState secondaryStateBefore;
    412410        ENSURE(secondaryComponentManager.SerializeState(secondaryStateBefore.state));
    413411        if (serializationTestDebugDump)
    414412            ENSURE(secondaryComponentManager.DumpDebugState(secondaryStateBefore.debug, false));
    415413        if (serializationTestHash)
    416414            ENSURE(secondaryComponentManager.ComputeStateHash(secondaryStateBefore.hash, false));
    417415
    418416        if (primaryStateBefore.state.str() != secondaryStateBefore.state.str() ||
    419417            primaryStateBefore.hash != secondaryStateBefore.hash)
    420418        {
    421419            ReportSerializationFailure(&primaryStateBefore, NULL, &secondaryStateBefore, NULL);
    422420        }
     421    }
     422
     423    // Execute the commands of that turn in the primary simulation
     424    UpdateComponents(m_SimContext, turnLengthFixed, commands);
    423425
     426    // Execute the commands of that turn in the secondary simulation and compare hash values
     427    if (m_EnableSerializationTest)
     428    {
    424429        SerializationTestState primaryStateAfter;
    425430        ENSURE(m_ComponentManager.SerializeState(primaryStateAfter.state));
    426431        if (serializationTestHash)
    427432            ENSURE(m_ComponentManager.ComputeStateHash(primaryStateAfter.hash, false));
    428433
    429         UpdateComponents(secondaryContext, turnLengthFixed,
    430             CloneCommandsFromOtherContext(scriptInterface, secondaryComponentManager.GetScriptInterface(), commands));
     434        UpdateComponents(secondaryContext, turnLengthFixed, clonedCommands);
    431435        SerializationTestState secondaryStateAfter;
    432436        ENSURE(secondaryComponentManager.SerializeState(secondaryStateAfter.state));
    433437        if (serializationTestHash)
    434438            ENSURE(secondaryComponentManager.ComputeStateHash(secondaryStateAfter.hash, false));
    435439
    436440        if (primaryStateAfter.state.str() != secondaryStateAfter.state.str() ||
    437441            primaryStateAfter.hash != secondaryStateAfter.hash)
    438442        {
    439443            // Only do the (slow) dumping now we know we're going to need to report it
    440444            ENSURE(m_ComponentManager.DumpDebugState(primaryStateAfter.debug, false));
    441445            ENSURE(secondaryComponentManager.DumpDebugState(secondaryStateAfter.debug, false));
    442446
    443447            ReportSerializationFailure(&primaryStateBefore, &primaryStateAfter, &secondaryStateBefore, &secondaryStateAfter);
    444448        }
    445449    }
    446450
    447451//  if (m_TurnNumber == 0)
    448452//      m_ComponentManager.GetScriptInterface().DumpHeap();
    449453