mirror of
https://gitea.wildfiregames.com/0ad/0ad.git
synced 2026-09-21 20:06:40 +00:00
Load entity templates for the AI via the progressive loader.
Display message while loading the map list for the setup screen. This was SVN commit r9019.
This commit is contained in:
@@ -44,6 +44,11 @@ var g_CivData = {};
|
||||
var g_MapFilters = [];
|
||||
|
||||
|
||||
// To prevent the display locking up while we load the map metadata,
|
||||
// we'll start with a 'loading' message and switch to the main screen in the
|
||||
// tick handler
|
||||
var g_LoadingState = 0; // 0 = not started, 1 = loading, 2 = loaded
|
||||
|
||||
function init(attribs)
|
||||
{
|
||||
switch (attribs.type)
|
||||
@@ -63,7 +68,11 @@ function init(attribs)
|
||||
default:
|
||||
error("Unexpected 'type' in gamesetup init: "+attribs.type);
|
||||
}
|
||||
}
|
||||
|
||||
// Called after the map data is loaded and cached
|
||||
function initMain()
|
||||
{
|
||||
// Load AI list
|
||||
g_AIs = Engine.GetAIs();
|
||||
|
||||
@@ -98,7 +107,7 @@ function init(attribs)
|
||||
{
|
||||
// Set a default map
|
||||
// TODO: This should be remembered from the last session
|
||||
if (attribs.type == "offline")
|
||||
if (!g_IsNetworked)
|
||||
g_GameAttributes.map = "Miletus";
|
||||
else
|
||||
g_GameAttributes.map = "Median Oasis";
|
||||
@@ -244,6 +253,19 @@ function cancelSetup()
|
||||
|
||||
function onTick()
|
||||
{
|
||||
// First tick happens before first render, so don't load yet
|
||||
if (g_LoadingState == 0)
|
||||
{
|
||||
g_LoadingState++;
|
||||
}
|
||||
else if (g_LoadingState == 1)
|
||||
{
|
||||
getGUIObjectByName("loadingWindow").hidden = true;
|
||||
getGUIObjectByName("setupWindow").hidden = false;
|
||||
initMain();
|
||||
g_LoadingState++;
|
||||
}
|
||||
|
||||
while (true)
|
||||
{
|
||||
var message = Engine.PollNetworkClient();
|
||||
|
||||
@@ -11,7 +11,19 @@
|
||||
<!-- Add a translucent black background to fade out the menu page -->
|
||||
<object type="image" z="0" sprite="bkTranslucent"/>
|
||||
|
||||
<object type="image" style="wheatWindow" size="50%-400 50%-300 50%+400 50%+300">
|
||||
<object type="image" style="wheatWindow" size="50%-190 50%-80 50%+190 50%+80" name="loadingWindow">
|
||||
|
||||
<object type="text" style="wheatWindowTitleBar">
|
||||
Loading
|
||||
</object>
|
||||
|
||||
<object type="text" text_align="center" text_valign="center">
|
||||
Loading map data. Please wait...
|
||||
</object>
|
||||
|
||||
</object>
|
||||
|
||||
<object type="image" style="wheatWindow" size="50%-400 50%-300 50%+400 50%+300" hidden="true" name="setupWindow">
|
||||
|
||||
<action on="Tick">
|
||||
onTick();
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include "ps/CLogger.h"
|
||||
#include "ps/CStr.h"
|
||||
#include "ps/Loader.h"
|
||||
#include "ps/LoaderThunks.h"
|
||||
#include "ps/Overlay.h"
|
||||
#include "ps/Profile.h"
|
||||
#include "ps/Replay.h"
|
||||
@@ -121,6 +122,8 @@ void CGame::RegisterInit(const CScriptValRooted& attribs)
|
||||
|
||||
LDR_BeginRegistering();
|
||||
|
||||
RegMemFun(m_Simulation2, &CSimulation2::ProgressiveLoad, L"Simulation init", 1000);
|
||||
|
||||
// RC, 040804 - GameView needs to be initialized before World, otherwise GameView initialization
|
||||
// overwrites anything stored in the map file that gets loaded by CWorld::Initialize with default
|
||||
// values. At the minute, it's just lighting settings, but could be extended to store camera position.
|
||||
|
||||
@@ -151,6 +151,33 @@ public:
|
||||
bool culling;
|
||||
};
|
||||
|
||||
/**
|
||||
* Handle progressive loading of resources.
|
||||
* A component that listens to this message must do the following:
|
||||
* - Increase *msg.total by the non-zero number of loading tasks this component can perform.
|
||||
* - If *msg.progressed == true, return and do nothing.
|
||||
* - If you've loaded everything, increase *msg.progress by the value you added to .total
|
||||
* - Otherwise do some loading, set *msg.progressed = true, and increase *msg.progress by a
|
||||
* value indicating how much progress you've made in total (0 <= p <= what you added to .total)
|
||||
* In some situations these messages will never be sent - components must ensure they
|
||||
* load all their data themselves before using it in that case.
|
||||
*/
|
||||
class CMessageProgressiveLoad : public CMessage
|
||||
{
|
||||
public:
|
||||
DEFAULT_MESSAGE_IMPL(ProgressiveLoad)
|
||||
|
||||
CMessageProgressiveLoad(bool* progressed, int* total, int* progress) :
|
||||
progressed(progressed), total(total), progress(progress)
|
||||
{
|
||||
}
|
||||
|
||||
bool* progressed;
|
||||
int* total;
|
||||
int* progress;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* This is sent immediately after a new entity's components have all been created
|
||||
* and initialised.
|
||||
|
||||
@@ -27,8 +27,9 @@
|
||||
#include "simulation2/components/ICmpCommandQueue.h"
|
||||
#include "simulation2/components/ICmpTemplateManager.h"
|
||||
|
||||
#include "lib/file/file_system_util.h"
|
||||
#include "lib/timer.h"
|
||||
#include "lib/utf8.h"
|
||||
#include "lib/file/file_system_util.h"
|
||||
#include "maths/MathUtil.h"
|
||||
#include "ps/CLogger.h"
|
||||
#include "ps/Filesystem.h"
|
||||
@@ -118,6 +119,7 @@ public:
|
||||
return static_cast<CSimulation2Impl*>(param)->ReloadChangedFile(path);
|
||||
}
|
||||
|
||||
int ProgressiveLoad();
|
||||
bool Update(int turnLength, const std::vector<SimulationCommand>& commands);
|
||||
void Interpolate(float frameLength, float frameOffset);
|
||||
|
||||
@@ -177,6 +179,34 @@ LibError CSimulation2Impl::ReloadChangedFile(const VfsPath& path)
|
||||
return INFO::OK;
|
||||
}
|
||||
|
||||
int CSimulation2Impl::ProgressiveLoad()
|
||||
{
|
||||
// yield after this time is reached. balances increased progress bar
|
||||
// smoothness vs. slowing down loading.
|
||||
const double end_time = timer_Time() + 200e-3;
|
||||
|
||||
int ret;
|
||||
|
||||
do
|
||||
{
|
||||
bool progressed = false;
|
||||
int total = 0;
|
||||
int progress = 0;
|
||||
|
||||
CMessageProgressiveLoad msg(&progressed, &total, &progress);
|
||||
|
||||
m_ComponentManager.BroadcastMessage(msg);
|
||||
|
||||
if (!progressed || total == 0)
|
||||
return 0; // we have nothing left to load
|
||||
|
||||
ret = Clamp(100*progress / total, 1, 100);
|
||||
}
|
||||
while (timer_Time() < end_time);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool CSimulation2Impl::Update(int turnLength, const std::vector<SimulationCommand>& commands)
|
||||
{
|
||||
fixed turnLengthFixed = fixed::FromInt(turnLength) / 1000;
|
||||
@@ -448,6 +478,11 @@ void CSimulation2::LoadMapSettings()
|
||||
GetScriptInterface().LoadScript(L"map startup script", m->m_StartupScript);
|
||||
}
|
||||
|
||||
int CSimulation2::ProgressiveLoad()
|
||||
{
|
||||
return m->ProgressiveLoad();
|
||||
}
|
||||
|
||||
LibError CSimulation2::ReloadChangedFile(const VfsPath& path)
|
||||
{
|
||||
return m->ReloadChangedFile(path);
|
||||
|
||||
@@ -109,6 +109,11 @@ public:
|
||||
*/
|
||||
CScriptVal GetMapSettings();
|
||||
|
||||
/**
|
||||
* RegMemFun incremental loader function.
|
||||
*/
|
||||
int ProgressiveLoad();
|
||||
|
||||
/**
|
||||
* Reload any scripts that were loaded from the given filename.
|
||||
* (This is used to implement hotloading.)
|
||||
|
||||
@@ -37,6 +37,7 @@ MESSAGE(Update_MotionUnit)
|
||||
MESSAGE(Update_Final)
|
||||
MESSAGE(Interpolate) // non-deterministic (use with caution)
|
||||
MESSAGE(RenderSubmit) // non-deterministic (use with caution)
|
||||
MESSAGE(ProgressiveLoad) // non-deterministic (use with caution)
|
||||
MESSAGE(Create)
|
||||
MESSAGE(Destroy)
|
||||
MESSAGE(OwnershipChanged)
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
#include "simulation2/system/Component.h"
|
||||
#include "ICmpAIManager.h"
|
||||
|
||||
#include "simulation2/MessageTypes.h"
|
||||
|
||||
#include "graphics/Terrain.h"
|
||||
#include "lib/timer.h"
|
||||
#include "lib/tex/tex.h"
|
||||
@@ -470,8 +472,9 @@ private:
|
||||
class CCmpAIManager : public ICmpAIManager
|
||||
{
|
||||
public:
|
||||
static void ClassInit(CComponentManager& UNUSED(componentManager))
|
||||
static void ClassInit(CComponentManager& componentManager)
|
||||
{
|
||||
componentManager.SubscribeToMessageType(MT_ProgressiveLoad);
|
||||
}
|
||||
|
||||
DEFAULT_COMPONENT_ALLOCATOR(AIManager)
|
||||
@@ -483,7 +486,7 @@ public:
|
||||
|
||||
virtual void Init(const CParamNode& UNUSED(paramNode))
|
||||
{
|
||||
LoadEntityTemplates();
|
||||
StartLoadEntityTemplates();
|
||||
}
|
||||
|
||||
virtual void Deinit()
|
||||
@@ -510,6 +513,28 @@ public:
|
||||
UNUSED2(deserialize);
|
||||
}
|
||||
|
||||
virtual void HandleMessage(const CMessage& msg, bool UNUSED(global))
|
||||
{
|
||||
switch (msg.GetType())
|
||||
{
|
||||
case MT_ProgressiveLoad:
|
||||
{
|
||||
const CMessageProgressiveLoad& msgData = static_cast<const CMessageProgressiveLoad&> (msg);
|
||||
|
||||
*msgData.total += m_TemplateNames.size();
|
||||
|
||||
if (*msgData.progressed)
|
||||
break;
|
||||
|
||||
if (ContinueLoadEntityTemplates())
|
||||
*msgData.progressed = true;
|
||||
|
||||
*msgData.progress += m_TemplateLoadedIdx;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
virtual void AddPlayer(std::wstring id, player_id_t player)
|
||||
{
|
||||
m_Worker.AddPlayer(id, player, true);
|
||||
@@ -519,6 +544,8 @@ public:
|
||||
{
|
||||
PROFILE("AI setup");
|
||||
|
||||
ForceLoadEntityTemplates();
|
||||
|
||||
ScriptInterface& scriptInterface = GetSimContext().GetScriptInterface();
|
||||
|
||||
CmpPtr<ICmpAIInterface> cmpAIInterface(GetSimContext(), SYSTEM_ENTITY);
|
||||
@@ -561,26 +588,47 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
void LoadEntityTemplates()
|
||||
std::vector<std::string> m_TemplateNames;
|
||||
size_t m_TemplateLoadedIdx;
|
||||
std::vector<std::pair<std::string, const CParamNode*> > m_Templates;
|
||||
|
||||
void StartLoadEntityTemplates()
|
||||
{
|
||||
TIMER(L"LoadEntityTemplates");
|
||||
CmpPtr<ICmpTemplateManager> cmpTemplateManager(GetSimContext(), SYSTEM_ENTITY);
|
||||
debug_assert(!cmpTemplateManager.null());
|
||||
|
||||
m_TemplateNames = cmpTemplateManager->FindAllTemplates(false);
|
||||
m_TemplateLoadedIdx = 0;
|
||||
m_Templates.reserve(m_TemplateNames.size());
|
||||
}
|
||||
|
||||
// Tries to load the next entity template. Returns true if we did some work.
|
||||
bool ContinueLoadEntityTemplates()
|
||||
{
|
||||
if (m_TemplateLoadedIdx >= m_TemplateNames.size())
|
||||
return false;
|
||||
|
||||
CmpPtr<ICmpTemplateManager> cmpTemplateManager(GetSimContext(), SYSTEM_ENTITY);
|
||||
debug_assert(!cmpTemplateManager.null());
|
||||
|
||||
std::vector<std::string> templateNames = cmpTemplateManager->FindAllTemplates(false);
|
||||
const CParamNode* node = cmpTemplateManager->GetTemplateWithoutValidation(m_TemplateNames[m_TemplateLoadedIdx]);
|
||||
if (node)
|
||||
m_Templates.push_back(std::make_pair(m_TemplateNames[m_TemplateLoadedIdx], node));
|
||||
|
||||
std::vector<std::pair<std::string, const CParamNode*> > templates;
|
||||
templates.reserve(templateNames.size());
|
||||
m_TemplateLoadedIdx++;
|
||||
|
||||
for (size_t i = 0; i < templateNames.size(); ++i)
|
||||
// If this was the last template, send the data to the worker
|
||||
if (m_TemplateLoadedIdx == m_TemplateNames.size())
|
||||
m_Worker.LoadEntityTemplates(m_Templates);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ForceLoadEntityTemplates()
|
||||
{
|
||||
while (ContinueLoadEntityTemplates())
|
||||
{
|
||||
const CParamNode* node = cmpTemplateManager->GetTemplateWithoutValidation(templateNames[i]);
|
||||
if (node)
|
||||
templates.push_back(std::make_pair(templateNames[i], node));
|
||||
}
|
||||
|
||||
m_Worker.LoadEntityTemplates(templates);
|
||||
}
|
||||
|
||||
void LoadPathfinderClasses(CScriptVal state)
|
||||
|
||||
@@ -120,6 +120,18 @@ CMessage* CMessageRenderSubmit::FromJSVal(ScriptInterface& UNUSED(scriptInterfac
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
jsval CMessageProgressiveLoad::ToJSVal(ScriptInterface& UNUSED(scriptInterface)) const
|
||||
{
|
||||
return JSVAL_VOID;
|
||||
}
|
||||
|
||||
CMessage* CMessageProgressiveLoad::FromJSVal(ScriptInterface& UNUSED(scriptInterface), jsval UNUSED(val))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
jsval CMessageCreate::ToJSVal(ScriptInterface& scriptInterface) const
|
||||
{
|
||||
TOJSVAL_SETUP();
|
||||
|
||||
Reference in New Issue
Block a user