# HG changeset patch # User koryspansel # Date 1317421396 25200 # Node ID 8cefb65577ccc605fbcf1cd60d08605be6c1e606 # Parent 2444937929aef5f0bd217bbae3996a742ffc46d1 Clean up world states diff -r 2444937929ae -r 8cefb65577cc LightClone/Source/Core.h --- a/LightClone/Source/Core.h Tue Sep 27 13:30:10 2011 -0700 +++ b/LightClone/Source/Core.h Fri Sep 30 15:23:16 2011 -0700 @@ -11,17 +11,27 @@ #include /* - * GameState + * WorldState */ enum { - GameState_Idle, - GameState_LoadMap, - GameState_Active, - GameState_Complete, - GameState_Over, - GameState_Confirm, - GameState_Exit, + WorldState_Main, + WorldState_Game, + WorldState_Pause, + WorldState_Help, + WorldState_Confirm, + WorldState_Exit, +}; + +/* + * LogicState + */ +enum +{ + LogicState_LevelLoad, + LogicState_LevelComplete, + LogicState_GameActive, + LogicState_GameOver, }; /* @@ -39,7 +49,6 @@ enum { Action_Default, - Action_Complete, Action_Forward, Action_RotateCW, Action_RotateCCW, @@ -47,6 +56,7 @@ Action_Light, Action_FunctionA, Action_FunctionB, + Action_Complete, Action_Count = 7, }; diff -r 2444937929ae -r 8cefb65577cc LightClone/Source/Program.cpp --- a/LightClone/Source/Program.cpp Tue Sep 27 13:30:10 2011 -0700 +++ b/LightClone/Source/Program.cpp Fri Sep 30 15:23:16 2011 -0700 @@ -60,17 +60,15 @@ kMachine.Reset(); kMachine.ClearMemory(); - kMachine.RemoveAllFunctions(); + //kMachine.RemoveAllFunctions(); - for(uint32 i = 0; i < FunctionCount && eCode == Error_Success; ++i) - { - kMachine.AddFunction(i, kFunction[i].CalculateSize()); + //uint32 nSize = kMachine.GetMemorySize(); + //uint8* pData = kMachine.GetMemoryPointer(); - uint32 nSize = kMachine.GetFunctionSize(i); - uint8* pData = kMachine.GetFunctionMemory(i); - - eCode = Compile(i, pData, nSize); - } + //for(uint32 i = 0; i < FunctionCount && eCode == Error_Success; ++i) + //{ + // eCode = Compile(i, pData, nSize); + //} return eCode; } @@ -80,33 +78,67 @@ */ ErrorCode Program::Compile(uint32 nIndex, uint8* pData, uint32 nSize) const { - for(uint32 i = 0; i < Function::MaximumInstructionCount; ++i) + ErrorCode eCode = Error_Success; + + for(uint32 i = 0; i < Function::MaximumInstructionCount && eCode == Error_Success; ++i) { - const uint32 nAction = kFunction[nIndex].nInstruction[i]; + // encode user-defined actions + eCode = EncodeAction(kFunction[nIndex].nInstruction[i], pData, nSize); + } - if(Action_Forward <= nAction && nAction <= Action_Light) + if(eCode == Error_Success) + { + if(nSize > 0) + { + // add implicit return statement + *pData++ = Instruction_End; + } + else { - if(nSize < 2) - return Error_Fail; + eCode = Error_Fail; + } + } + + return eCode; +} +/* + * EncodeAction + */ +ErrorCode Program::EncodeAction(uint32 nAction, uint8*& pData, uint32& nSize) const +{ + if(Action_Forward <= nAction && nAction <= Action_Light) + { + if(nSize >= 2) + { *pData++ = Instruction_Action; *pData++ = nAction; - nSize -= 2; + return nSize -= 2, Error_Success; } - else + } + else - if(Action_FunctionA <= nAction && nAction <= Action_FunctionB) + if(Action_FunctionA <= nAction && nAction <= Action_FunctionB) + { + if(nSize >= 2) { - if(nSize < 2) - return Error_Fail; - *pData++ = Instruction_Call; *pData++ = nAction - Action_FunctionA + 1; - nSize -= 2; + return nSize -= 2, Error_Success; + } + } + else + + { + if(nSize >= 1) + { + *pData++ = Instruction_None; + + return nSize -= 1, Error_Success; } } - return Error_Success; + return Error_Fail; } diff -r 2444937929ae -r 8cefb65577cc LightClone/Source/Program.h --- a/LightClone/Source/Program.h Tue Sep 27 13:30:10 2011 -0700 +++ b/LightClone/Source/Program.h Fri Sep 30 15:23:16 2011 -0700 @@ -93,6 +93,11 @@ * Compile */ ErrorCode Compile(uint32 nFunction, uint8* pData, uint32 nSize) const; + + /* + * EncodeAction + */ + ErrorCode EncodeAction(uint32 nAction, uint8*& pData, uint32& nSize) const; }; #endif //__PROGRAM_H__ diff -r 2444937929ae -r 8cefb65577cc LightClone/Source/World.cpp --- a/LightClone/Source/World.cpp Tue Sep 27 13:30:10 2011 -0700 +++ b/LightClone/Source/World.cpp Fri Sep 30 15:23:16 2011 -0700 @@ -13,8 +13,8 @@ */ World::World() { - nGameState = GameState_Active; - nGameStatePrevious = GameState_Active; + nWorldState = WorldState_Main; + nLogicState = LogicState_LevelLoad; nSimulationState = SimulationState_Idle; nCurrentLevel = 0; } @@ -24,48 +24,49 @@ */ ErrorCode World::Initialize(ResourceManager* pResourceManager, InputManager* pInput) { - ErrorCode eCode = Error_Fail; + //ASSERT(pResourceManager != NULL); + //ASSERT(pInput != NULL); + + ErrorCode eCode = kEnvironment.Initialize(pResourceManager); + if(eCode != Error_Success) + { + TRACE("Error: Failed to initialize environment\n"); - if(pResourceManager && pInput) + Terminate(); + return eCode; + } + + eCode = kBot.Initialize(pResourceManager); + if(eCode != Error_Success) { - pInputManager = pInput; + TRACE("Error: Failed to initialize bot\n"); + + Terminate(); + return eCode; + } - eCode = kEnvironment.Initialize(pResourceManager); - if(eCode == Error_Success) - { - eCode = kBot.Initialize(pResourceManager); - if(eCode == Error_Success) - { - eCode = kProgram.Initialize(); - if(eCode == Error_Success) - { - eCode = InitializeInterface(pResourceManager); - if(eCode == Error_Success) - { - nCurrentLevel = 0; - nGameState = GameState_LoadMap; - } - else - { - TRACE("Error: Failed to initialize interface\n"); - } - } - else - { - TRACE("Error: Failed to initialize program\n"); - } - } - else - { - TRACE("Error: Failed to initialize bot\n"); - } - } - else - { - TRACE("Error: Failed to initialize environment\n"); - } + eCode = kProgram.Initialize(); + if(eCode == Error_Success) + { + TRACE("Error: Failed to initialize program\n"); + + Terminate(); + return eCode; } + eCode = InitializeInterface(pResourceManager); + if(eCode != Error_Success) + { + TRACE("Error: Failed to initialize interface\n"); + + Terminate(); + return eCode; + } + + pInputManager = pInput; + nLogicState = LogicState_LevelLoad; + nCurrentLevel = 0; + return eCode; } @@ -85,7 +86,8 @@ */ void World::Activate() { - nGameState = GameState_LoadMap; + nWorldState = WorldState_Game; + nLogicState = LogicState_LevelLoad; } /* @@ -93,7 +95,7 @@ */ void World::Deactivate() { - nGameState = GameState_Exit; + nWorldState = WorldState_Exit; } /* @@ -101,7 +103,7 @@ */ bool World::IsActive() { - return nGameState != GameState_Exit; + return nWorldState != WorldState_Exit; } /* @@ -140,56 +142,23 @@ */ void World::Update(float fElapsed) { - ProcessInput(fElapsed); - - if(nGameState == GameState_LoadMap) - { - char kBuffer[256]; - sprintf(kBuffer, "Data\\Maps\\Map%02d.map", nCurrentLevel++); - - ErrorCode eCode = Load(kBuffer); - if(eCode == Error_Success) - { - kProgram.Clear(); + kInterface.Update(fElapsed); - pMain->Clear(); - pFunctionA->Clear(); - pFunctionB->Clear(); - - nGameState = GameState_Active; - } - else - { - kMessageDialog.SetButton(0, "Ok", 0); - kMessageDialog.SetMessage("Congratulations!\nYou have completed the game"); - kMessageDialog.Show(); - - nGameState = GameState_Over; - } - - nSimulationState = SimulationState_Idle; + if(nWorldState == WorldState_Main) + { } else - if(nGameState == GameState_Active) + if(nWorldState == WorldState_Game) { - if(nSimulationState == SimulationState_Active) - { - if(kBot.Update(fElapsed)) - { - if(kEnvironment.RequirementsMet()) - { - kMessageDialog.SetButton(0, "Ok", 0); - kMessageDialog.SetMessage("Congratulations!\nYou have completed level %d", nCurrentLevel); - kMessageDialog.Show(); + UpdateInput(fElapsed); + UpdateLogic(fElapsed); + } + else - nGameState = GameState_Complete; - } - } - } + if(nWorldState == WorldState_Pause) + { } - - kInterface.Update(fElapsed); } /* @@ -201,30 +170,27 @@ kContext.Begin(nColor); - //TODO: Remove - if(nGameState >= GameState_Active) - { - D3DVIEWPORT9 kOriginal; - kContext.GetViewport(&kOriginal); + D3DVIEWPORT9 kOriginal; + kContext.GetViewport(&kOriginal); + + D3DVIEWPORT9 kViewport; + kViewport.X = 0; + kViewport.Y = 0; + kViewport.Width = ScreenSizeX - 280; + kViewport.Height = ScreenSizeY; + kViewport.MinZ = kOriginal.MinZ; + kViewport.MaxZ = kOriginal.MaxZ; - D3DVIEWPORT9 kViewport; - kViewport.X = 0; - kViewport.Y = 0; - kViewport.Width = ScreenSizeX - 280; - kViewport.Height = ScreenSizeY; - kViewport.MinZ = kOriginal.MinZ; - kViewport.MaxZ = kOriginal.MaxZ; + kContext.SetViewport(kViewport); - kContext.SetViewport(kViewport); - - kCameraController.SetMode(CameraMode_3D); - Render3D(kContext); + kCameraController.SetMode(CameraMode_3D); + kEnvironment.Render(kContext, kCameraController); + kBot.Render(kContext, kCameraController); - kContext.SetViewport(kOriginal); + kContext.SetViewport(kOriginal); - kCameraController.SetMode(CameraMode_2D); - Render2D(kContext); - } + kCameraController.SetMode(CameraMode_2D); + kInterface.Render(kContext, kCameraController); kContext.End(); } @@ -265,12 +231,12 @@ pMainLabel->SetPosition(26.0f, 149.0f); pMainLabel->SetDepth(256.0f); - pMain = new CodePanel(4, 3); - pMain->Initialize(pResourceManager); - pMain->SetTexture("Data\\Textures\\PanelB.png"); - pMain->SetPosition(16.0f, 160.0f); - pMain->Subscribe(CodePanel::EventAction, &World::OnAction, this); - pMain->SetDepth(256.0f); + pCode[0] = new CodePanel(4, 3); + pCode[0]->Initialize(pResourceManager); + pCode[0]->SetTexture("Data\\Textures\\PanelB.png"); + pCode[0]->SetPosition(16.0f, 160.0f); + pCode[0]->Subscribe(CodePanel::EventAction, &World::OnAction, this); + pCode[0]->SetDepth(256.0f); GuiLabel* pFunctionALabel = new GuiLabel(); pFunctionALabel->Initialize(pResourceManager); @@ -279,11 +245,11 @@ pFunctionALabel->SetColor(D3DCOLOR_XRGB(0, 0, 0)); pFunctionALabel->SetPosition(26.0f, 349.0f); - pFunctionA = new CodePanel(4, 2); - pFunctionA->Initialize(pResourceManager); - pFunctionA->SetTexture("Data\\Textures\\PanelA.png"); - pFunctionA->SetPosition(16.0f, 360.0f); - pFunctionA->Subscribe(CodePanel::EventAction, &World::OnAction, this); + pCode[1] = new CodePanel(4, 2); + pCode[1]->Initialize(pResourceManager); + pCode[1]->SetTexture("Data\\Textures\\PanelA.png"); + pCode[1]->SetPosition(16.0f, 360.0f); + pCode[1]->Subscribe(CodePanel::EventAction, &World::OnAction, this); GuiLabel* pFunctionBLabel = new GuiLabel(); pFunctionBLabel->Initialize(pResourceManager); @@ -292,11 +258,11 @@ pFunctionBLabel->SetColor(D3DCOLOR_XRGB(0, 0, 0)); pFunctionBLabel->SetPosition(26.0f, 493.0f); - pFunctionB = new CodePanel(4, 2); - pFunctionB->Initialize(pResourceManager); - pFunctionB->SetTexture("Data\\Textures\\PanelA.png"); - pFunctionB->SetPosition(16.0f, 504.0f); - pFunctionB->Subscribe(CodePanel::EventAction, &World::OnAction, this); + pCode[2] = new CodePanel(4, 2); + pCode[2]->Initialize(pResourceManager); + pCode[2]->SetTexture("Data\\Textures\\PanelA.png"); + pCode[2]->SetPosition(16.0f, 504.0f); + pCode[2]->Subscribe(CodePanel::EventAction, &World::OnAction, this); const float fButtonPadding = 32.0f; const float fButtonSpacing = 8.0f; @@ -348,57 +314,45 @@ pBackground->Add(pToolbar); pBackground->Add(pMainLabel); - pBackground->Add(pMain); + pBackground->Add(pCode[0]); pBackground->Add(pFunctionALabel); - pBackground->Add(pFunctionA); + pBackground->Add(pCode[1]); pBackground->Add(pFunctionBLabel); - pBackground->Add(pFunctionB); + pBackground->Add(pCode[2]); pBackground->Add(pButtonPlay); pBackground->Add(pButtonStop); pBackground->Add(pButtonReset); pBackground->Add(pButtonExit); - kMessageDialog.Initialize(pResourceManager); - kMessageDialog.Subscribe(GuiDialog::EventResult, &World::OnResult, this); + pMessageDialog = new MessageDialog(); + pMessageDialog->Initialize(pResourceManager); + pMessageDialog->Subscribe(GuiDialog::EventResult, &World::OnResult, this); - const D3DXVECTOR2& kMessageSize = kMessageDialog.GetDimensions(); - kMessageDialog.SetPosition(0.5f * ((ScreenSizeX - pBackground->GetWidth()) - kMessageSize.x), 0.5f * (ScreenSizeY - kMessageSize.y)); + const D3DXVECTOR2& kMessageSize = pMessageDialog->GetDimensions(); + pMessageDialog->SetPosition(0.5f * ((ScreenSizeX - pBackground->GetWidth()) - kMessageSize.x), 0.5f * (ScreenSizeY - kMessageSize.y)); - kConfirmDialog.Initialize(pResourceManager); - kConfirmDialog.Subscribe(GuiDialog::EventResult, &World::OnConfirm, this); + pConfirmDialog = new ChoiceDialog(); + pConfirmDialog->Initialize(pResourceManager); + pConfirmDialog->Subscribe(GuiDialog::EventResult, &World::OnConfirm, this); - const D3DXVECTOR2& kConfigSize = kMessageDialog.GetDimensions(); - kConfirmDialog.SetPosition(0.5f * ((ScreenSizeX - pBackground->GetWidth()) - kConfigSize.x), 0.5f * (ScreenSizeY - kConfigSize.y)); + const D3DXVECTOR2& kConfigSize = pConfirmDialog->GetDimensions(); + pConfirmDialog->SetPosition(0.5f * ((ScreenSizeX - pBackground->GetWidth()) - kConfigSize.x), 0.5f * (ScreenSizeY - kConfigSize.y)); + + //pHud = new GuiElement(); + //pHud->Add(pBackground); kInterface.Add(pBackground); - kInterface.Add(&kMessageDialog); - kInterface.Add(&kConfirmDialog); + kInterface.Add(pMessageDialog); + kInterface.Add(pConfirmDialog); } return eCode; } /* - * Render3D + * UpdateInput */ -void World::Render3D(RenderContext& kContext) -{ - kEnvironment.Render(kContext, kCameraController); - kBot.Render(kContext, kCameraController); -} - -/* - * Render2D - */ -void World::Render2D(RenderContext& kContext) -{ - kInterface.Render(kContext, kCameraController); -} - -/* - * ProcessInput - */ -void World::ProcessInput(float fElapsed) +void World::UpdateInput(float fElapsed) { pInputManager->Update(fElapsed); @@ -506,7 +460,7 @@ if(nCount > 0) { nCurrentLevel = 0; - nGameState = GameState_LoadMap; + nLogicState = LogicState_LevelLoad; for(uint32 i = 0; i < nCount; ++i) { @@ -525,8 +479,61 @@ nCount = 0; } } + #endif +} - #endif +/* + * UpdateLogic + */ +void World::UpdateLogic(float fElapsed) +{ + if(nLogicState == LogicState_LevelLoad) + { + char kBuffer[256]; + sprintf(kBuffer, "Data\\Maps\\Map%02d.map", nCurrentLevel++); + + ErrorCode eCode = Load(kBuffer); + if(eCode == Error_Success) + { + kProgram.Clear(); + + for(uint32 i = 0; i < MaximumCodePanels; ++i) + { + pCode[i]->Clear(); + } + + nLogicState = LogicState_GameActive; + } + else + { + pMessageDialog->SetButton(0, "Ok", 0); + pMessageDialog->SetMessage("Congratulations!\nYou have completed the game"); + pMessageDialog->Show(); + + nLogicState = LogicState_GameOver; + } + + nSimulationState = SimulationState_Idle; + } + else + + if(nLogicState == LogicState_GameActive) + { + if(nSimulationState == SimulationState_Active) + { + if(kBot.Update(fElapsed)) + { + if(kEnvironment.RequirementsMet()) + { + pMessageDialog->SetButton(0, "Ok", 0); + pMessageDialog->SetMessage("Congratulations!\nYou have completed level %d", nCurrentLevel); + pMessageDialog->Show(); + + nLogicState = LogicState_LevelComplete; + } + } + } + } } /* @@ -536,21 +543,12 @@ { ActionArguments& kActionArguments = (ActionArguments&)kArguments; - if(kArguments.pSource == pMain) - { - kProgram.SetAction(0, kActionArguments.nSlot, pMain->GetAction(kActionArguments.nSlot)); - } - else - - if(kArguments.pSource == pFunctionA) + for(uint32 i = 0; i < MaximumCodePanels; ++i) { - kProgram.SetAction(1, kActionArguments.nSlot, pFunctionA->GetAction(kActionArguments.nSlot)); - } - else - - if(kArguments.pSource == pFunctionB) - { - kProgram.SetAction(2, kActionArguments.nSlot, pFunctionB->GetAction(kActionArguments.nSlot)); + if(kArguments.pSource == pCode[i]) + { + kProgram.SetAction(i, kActionArguments.nSlot, pCode[i]->GetAction(kActionArguments.nSlot)); + } } } @@ -596,9 +594,10 @@ { kProgram.Clear(); - pMain->Clear(); - pFunctionA->Clear(); - pFunctionB->Clear(); + for(uint32 i = 0; i < MaximumCodePanels; ++i) + { + pCode[i]->Clear(); + } } /* @@ -606,13 +605,12 @@ */ void World::OnExit(GuiEventArguments& kArguments) { - kConfirmDialog.SetMessage("Are you sure you want to exit?"); - kConfirmDialog.SetButton(0, "Yes", DialogResult_Yes); - kConfirmDialog.SetButton(1, "No", DialogResult_No); - kConfirmDialog.Show(); + pConfirmDialog->SetMessage("Are you sure you want to exit?"); + pConfirmDialog->SetButton(0, "Yes", DialogResult_Yes); + pConfirmDialog->SetButton(1, "No", DialogResult_No); + pConfirmDialog->Show(); - nGameStatePrevious = nGameState; - nGameState = GameState_Confirm; + nWorldState = WorldState_Confirm; } /* @@ -620,16 +618,22 @@ */ void World::OnResult(GuiEventArguments& kArguments) { - if(nGameState == GameState_Complete) + if(nWorldState == WorldState_Game) { - nGameState = GameState_LoadMap; - } - else + if(nLogicState == LogicState_LevelComplete) + { + nLogicState = LogicState_LevelLoad; + } + else - if(nGameState == GameState_Over) - { - nCurrentLevel = 0; - nGameState = GameState_LoadMap; + if(nLogicState == LogicState_GameOver) + { + nCurrentLevel = 0; + nLogicState = LogicState_LevelLoad; + + //TODO: Return to main menu + nWorldState = WorldState_Main; + } } } @@ -638,16 +642,19 @@ */ void World::OnConfirm(GuiEventArguments& kArguments) { - GuiResultArguments& kResultArguments = (GuiResultArguments&)kArguments; - - if(kResultArguments.nResult == DialogResult_Yes) + if(nWorldState == WorldState_Confirm) { - nGameState = GameState_Exit; - } - else + GuiResultArguments& kResultArguments = (GuiResultArguments&)kArguments; - if(kResultArguments.nResult == DialogResult_No) - { - nGameState = nGameStatePrevious; + if(kResultArguments.nResult == DialogResult_Yes) + { + Deactivate(); + } + else + + if(kResultArguments.nResult == DialogResult_No) + { + nWorldState = WorldState_Game; + } } } diff -r 2444937929ae -r 8cefb65577cc LightClone/Source/World.h --- a/LightClone/Source/World.h Tue Sep 27 13:30:10 2011 -0700 +++ b/LightClone/Source/World.h Fri Sep 30 15:23:16 2011 -0700 @@ -21,11 +21,26 @@ #include "Dialog.h" /* + * MessageDialog + */ +typedef Dialog<1> MessageDialog; + +/* + * ChoiceDialog + */ +typedef Dialog<2> ChoiceDialog; + +/* * World */ class World { /* + * MaximumCodePanels + */ + static const uint32 MaximumCodePanels = 3; + + /* * pInputManager */ InputManager* pInputManager; @@ -51,14 +66,14 @@ Program kProgram; /* - * nGameState + * nWorldState */ - uint32 nGameState; + uint32 nWorldState; /* - * nGameStatePrevious + * nLogicState */ - uint32 nGameStatePrevious; + uint32 nLogicState; /* * nSimulationState @@ -81,6 +96,26 @@ GuiInterface kInterface; /* + * pMenuMain + */ + GuiElement* pMenuMain; + + /* + * pMenuHelp + */ + GuiElement* pMenuHelp; + + /* + * pMenuPause + */ + GuiElement* pMenuPause; + + /* + * pHud + */ + GuiElement* pHud; + + /* * pBackground */ GuiImage* pBackground; @@ -111,29 +146,19 @@ CodePanel* pToolbar; /* - * pMain + * pCode */ - CodePanel* pMain; - - /* - * pFunctionA - */ - CodePanel* pFunctionA; + CodePanel* pCode[MaximumCodePanels]; /* - * pFunctionB + * pMessageDialog */ - CodePanel* pFunctionB; + MessageDialog* pMessageDialog; /* - * kMessageDialog + * pConfirmDialog */ - Dialog<1> kMessageDialog; - - /* - * kConfirmDialog - */ - Dialog<2> kConfirmDialog; + ChoiceDialog* pConfirmDialog; public: @@ -190,16 +215,6 @@ ErrorCode InitializeInterface(ResourceManager* pResourceManager); /* - * Render3D - */ - void Render3D(RenderContext& kContext); - - /* - * Render2D - */ - void Render2D(RenderContext& kContext); - - /* * RenderEnvironment */ void RenderEnvironment(RenderContext& kContext, Environment* pEnvironment); @@ -210,9 +225,14 @@ void RenderBot(RenderContext& kContext, Environment* pEnvironment, Bot* pBot); /* - * ProcessInput + * UpdateInput */ - void ProcessInput(float fElapsed); + void UpdateInput(float fElapsed); + + /* + * UpdateLogic + */ + void UpdateLogic(float fElapsed); /* * OnAction diff -r 2444937929ae -r 8cefb65577cc LightClone/ToDo.txt --- a/LightClone/ToDo.txt Tue Sep 27 13:30:10 2011 -0700 +++ b/LightClone/ToDo.txt Fri Sep 30 15:23:16 2011 -0700 @@ -1,9 +1,8 @@ -1. Only draw slots that are being used -2. Button tool tips -3. Main menu -4. Pause menu -5. Robot model & texture -7. Help interface -8. Implement gui batching -9. Add depth to gui elements -10. Move render manager into gui element \ No newline at end of file +1. Button tool tips +2. Main menu +3. Pause menu +4. Robot model & texture +5. Help interface +6. Add asserts +7. Move resource manager into a service provider container +8. Refactor virtual machine \ No newline at end of file