forked from mirrors/0ad
Start Atlas by closing the root page
Theere is now an `Engine.startAtlas` property that will start Atlas when it's returned from the root page. The `Engine.RestartInAtlas` function is removed.
This commit is contained in:
@@ -0,0 +1,4 @@
|
|||||||
|
async function init(arg)
|
||||||
|
{
|
||||||
|
return arg ? Engine.startAtlas : undefined;
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<objects>
|
||||||
|
<script file="gui/Result/Result.js"/>
|
||||||
|
</objects>
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<page>
|
||||||
|
<include>Result/Result.xml</include>
|
||||||
|
</page>
|
||||||
@@ -275,7 +275,7 @@ var g_MainMenuItems = [
|
|||||||
{
|
{
|
||||||
"caption": translate("Scenario Editor"),
|
"caption": translate("Scenario Editor"),
|
||||||
"tooltip": translate('Open the Atlas Scenario Editor in a new window. You can run this more reliably by starting the game with the command-line argument "-editor".'),
|
"tooltip": translate('Open the Atlas Scenario Editor in a new window. You can run this more reliably by starting the game with the command-line argument "-editor".'),
|
||||||
"onPress": async() => {
|
"onPress": async(closePageCallback) => {
|
||||||
if (!Engine.AtlasIsAvailable())
|
if (!Engine.AtlasIsAvailable())
|
||||||
{
|
{
|
||||||
messageBox(
|
messageBox(
|
||||||
@@ -292,7 +292,7 @@ var g_MainMenuItems = [
|
|||||||
[translate("No"), translate("Yes")]);
|
[translate("No"), translate("Yes")]);
|
||||||
|
|
||||||
if (buttonIndex === 1)
|
if (buttonIndex === 1)
|
||||||
Engine.RestartInAtlas();
|
closePageCallback(Engine.startAtlas);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -35,11 +35,14 @@
|
|||||||
#include "scriptinterface/ScriptInterface.h"
|
#include "scriptinterface/ScriptInterface.h"
|
||||||
#include "scriptinterface/StructuredClone.h"
|
#include "scriptinterface/StructuredClone.h"
|
||||||
|
|
||||||
|
#include "js/Equality.h"
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
|
||||||
const CStr EVENT_NAME_GAME_LOAD_PROGRESS = "GameLoadProgress";
|
const CStr EVENT_NAME_GAME_LOAD_PROGRESS = "GameLoadProgress";
|
||||||
const CStr EVENT_NAME_WINDOW_RESIZED = "WindowResized";
|
const CStr EVENT_NAME_WINDOW_RESIZED = "WindowResized";
|
||||||
|
constexpr const char* START_ATLAS{"startAtlas"};
|
||||||
|
|
||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
|
|
||||||
@@ -165,6 +168,12 @@ void CGUIManager::SGUIPage::LoadPage(ScriptContext& scriptContext)
|
|||||||
sendingPromise = std::make_shared<JS::PersistentRootedObject>(rq.cx,
|
sendingPromise = std::make_shared<JS::PersistentRootedObject>(rq.cx,
|
||||||
JS::NewPromiseObject(rq.cx, nullptr));
|
JS::NewPromiseObject(rq.cx, nullptr));
|
||||||
|
|
||||||
|
{
|
||||||
|
JS::RootedString jsName{rq.cx, JS_NewStringCopyZ(rq.cx, START_ATLAS)};
|
||||||
|
JS::RootedValue symbol{rq.cx, JS::SymbolValue(JS::NewSymbol(rq.cx, jsName))};
|
||||||
|
JS::RootedValue nativeScope{rq.cx, JS::ObjectValue(*rq.nativeScope)};
|
||||||
|
Script::SetProperty(rq, nativeScope, START_ATLAS, symbol, true);
|
||||||
|
}
|
||||||
gui->AddObjectTypes();
|
gui->AddObjectTypes();
|
||||||
|
|
||||||
VfsPath path = VfsPath("gui") / m_Name;
|
VfsPath path = VfsPath("gui") / m_Name;
|
||||||
@@ -257,7 +266,7 @@ JS::Value CGUIManager::SGUIPage::ReplacePromise(ScriptInterface& scriptInterface
|
|||||||
return JS::ObjectValue(**receivingPromise);
|
return JS::ObjectValue(**receivingPromise);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<CGUIManager::SGUIPage::CloseResult> CGUIManager::SGUIPage::MaybeClose()
|
std::optional<CGUIManager::SGUIPage::CloseResult> CGUIManager::SGUIPage::MaybeClose(const bool topmostPage)
|
||||||
{
|
{
|
||||||
if (JS::GetPromiseState(*sendingPromise) == JS::PromiseState::Pending)
|
if (JS::GetPromiseState(*sendingPromise) == JS::PromiseState::Pending)
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
@@ -267,8 +276,20 @@ std::optional<CGUIManager::SGUIPage::CloseResult> CGUIManager::SGUIPage::MaybeCl
|
|||||||
|
|
||||||
const ScriptRequest rq{gui->GetScriptInterface()};
|
const ScriptRequest rq{gui->GetScriptInterface()};
|
||||||
JS::RootedValue arg{rq.cx, JS::GetPromiseResult(*sendingPromise)};
|
JS::RootedValue arg{rq.cx, JS::GetPromiseResult(*sendingPromise)};
|
||||||
return CGUIManager::SGUIPage::CloseResult{Script::WriteStructuredClone(rq, arg),
|
const bool rejected{JS::GetPromiseState(*sendingPromise) == JS::PromiseState::Rejected};
|
||||||
JS::GetPromiseState(*sendingPromise) == JS::PromiseState::Rejected};
|
if (topmostPage)
|
||||||
|
{
|
||||||
|
JS::RootedValue nativeScope{rq.cx, JS::ObjectValue(*rq.nativeScope)};
|
||||||
|
JS::RootedValue symbol{rq.cx};
|
||||||
|
Script::GetProperty(rq, nativeScope, START_ATLAS, &symbol);
|
||||||
|
bool equals;
|
||||||
|
if (!JS::StrictlyEqual(rq.cx, arg, symbol, &equals))
|
||||||
|
throw std::runtime_error{"Error while comparing return value to a symbol."};
|
||||||
|
|
||||||
|
if (equals)
|
||||||
|
return CGUIManager::SGUIPage::CloseResult{nullptr, rejected};
|
||||||
|
}
|
||||||
|
return CGUIManager::SGUIPage::CloseResult{Script::WriteStructuredClone(rq, arg), rejected};
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGUIManager::SGUIPage::Refocus(const CloseResult& result)
|
void CGUIManager::SGUIPage::Refocus(const CloseResult& result)
|
||||||
@@ -375,7 +396,7 @@ void CGUIManager::SendEventToAll(const CStr& eventName, JS::HandleValueArray par
|
|||||||
p.gui->SendEventToAll(eventName, paramData);
|
p.gui->SendEventToAll(eventName, paramData);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGUIManager::TickObjects()
|
std::optional<bool> CGUIManager::TickObjects()
|
||||||
{
|
{
|
||||||
PROFILE3("gui tick");
|
PROFILE3("gui tick");
|
||||||
|
|
||||||
@@ -394,16 +415,20 @@ void CGUIManager::TickObjects()
|
|||||||
while (!m_PageStack.empty())
|
while (!m_PageStack.empty())
|
||||||
{
|
{
|
||||||
const size_t stackSize{m_PageStack.size()};
|
const size_t stackSize{m_PageStack.size()};
|
||||||
const std::optional<SGUIPage::CloseResult> result{m_PageStack.back().MaybeClose()};
|
const std::optional<SGUIPage::CloseResult> result{
|
||||||
|
m_PageStack.back().MaybeClose(stackSize == 1)};
|
||||||
if (!result.has_value())
|
if (!result.has_value())
|
||||||
break;
|
break;
|
||||||
ENSURE(m_PageStack.size() == stackSize);
|
ENSURE(m_PageStack.size() == stackSize);
|
||||||
m_PageStack.pop_back();
|
m_PageStack.pop_back();
|
||||||
if (!m_PageStack.empty())
|
if (m_PageStack.empty())
|
||||||
|
return !result.value().arg;
|
||||||
|
else
|
||||||
m_PageStack.back().Refocus(result.value());
|
m_PageStack.back().Refocus(result.value());
|
||||||
|
|
||||||
m_ScriptContext.RunJobs();
|
m_ScriptContext.RunJobs();
|
||||||
}
|
}
|
||||||
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGUIManager::Draw(CCanvas2D& canvas) const
|
void CGUIManager::Draw(CCanvas2D& canvas) const
|
||||||
|
|||||||
@@ -96,8 +96,10 @@ public:
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* See CGUI::TickObjects; applies to @em all loaded pages.
|
* See CGUI::TickObjects; applies to @em all loaded pages.
|
||||||
|
* When the root page is closed it's returned wheter Atlas should be
|
||||||
|
* started.
|
||||||
*/
|
*/
|
||||||
void TickObjects();
|
std::optional<bool> TickObjects();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* See CGUI::Draw; applies to @em all loaded pages.
|
* See CGUI::Draw; applies to @em all loaded pages.
|
||||||
@@ -156,7 +158,7 @@ private:
|
|||||||
* returns the result of the @c init function.
|
* returns the result of the @c init function.
|
||||||
* If this page wasn't closed an empty optional is returned.
|
* If this page wasn't closed an empty optional is returned.
|
||||||
*/
|
*/
|
||||||
std::optional<CloseResult> MaybeClose();
|
std::optional<CloseResult> MaybeClose(const bool topmostPage);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function should be called when a child page got closed. The
|
* This function should be called when a child page got closed. The
|
||||||
|
|||||||
@@ -284,4 +284,16 @@ public:
|
|||||||
CloseTopmostPage();
|
CloseTopmostPage();
|
||||||
TS_ASSERT_EQUALS(g_GUI->GetPageCount(), 0);
|
TS_ASSERT_EQUALS(g_GUI->GetPageCount(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void test_Result()
|
||||||
|
{
|
||||||
|
const ScriptRequest rq{g_GUI->GetScriptInterface()};
|
||||||
|
g_GUI->OpenChildPage(L"Result/page_Result.xml",
|
||||||
|
Script::WriteStructuredClone(rq, JS::FalseHandleValue));
|
||||||
|
TS_ASSERT(!g_GUI->TickObjects().value());
|
||||||
|
|
||||||
|
g_GUI->OpenChildPage(L"Result/page_Result.xml",
|
||||||
|
Script::WriteStructuredClone(rq, JS::TrueHandleValue));
|
||||||
|
TS_ASSERT(g_GUI->TickObjects().value());
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
+3
-8
@@ -172,11 +172,6 @@ void RestartEngine()
|
|||||||
g_Shutdown = ShutdownType::Restart;
|
g_Shutdown = ShutdownType::Restart;
|
||||||
}
|
}
|
||||||
|
|
||||||
void StartAtlas()
|
|
||||||
{
|
|
||||||
g_Shutdown = ShutdownType::RestartAsAtlas;
|
|
||||||
}
|
|
||||||
|
|
||||||
// main app message handler
|
// main app message handler
|
||||||
static InReaction MainInputHandler(const SDL_Event_* ev)
|
static InReaction MainInputHandler(const SDL_Event_* ev)
|
||||||
{
|
{
|
||||||
@@ -430,9 +425,9 @@ static void Frame(RL::Interface* rlInterface)
|
|||||||
if (g_NetClient)
|
if (g_NetClient)
|
||||||
g_NetClient->Poll();
|
g_NetClient->Poll();
|
||||||
|
|
||||||
g_GUI->TickObjects();
|
std::optional<bool> completionCommand{g_GUI->TickObjects()};
|
||||||
if (g_GUI->GetPageCount() == 0)
|
if (completionCommand.has_value())
|
||||||
QuitEngine();
|
g_Shutdown = completionCommand.value() ? ShutdownType::RestartAsAtlas : ShutdownType::Quit;
|
||||||
|
|
||||||
if (rlInterface)
|
if (rlInterface)
|
||||||
rlInterface->TryApplyMessage();
|
rlInterface->TryApplyMessage();
|
||||||
|
|||||||
@@ -34,15 +34,8 @@
|
|||||||
#include "scriptinterface/FunctionWrapper.h"
|
#include "scriptinterface/FunctionWrapper.h"
|
||||||
#include "tools/atlas/GameInterface/GameLoop.h"
|
#include "tools/atlas/GameInterface/GameLoop.h"
|
||||||
|
|
||||||
extern void StartAtlas();
|
|
||||||
|
|
||||||
namespace JSI_Main
|
namespace JSI_Main
|
||||||
{
|
{
|
||||||
void StartAtlas()
|
|
||||||
{
|
|
||||||
::StartAtlas();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AtlasIsAvailable()
|
bool AtlasIsAvailable()
|
||||||
{
|
{
|
||||||
return ATLAS_IsAvailable();
|
return ATLAS_IsAvailable();
|
||||||
@@ -120,7 +113,6 @@ std::string CalculateMD5(const std::string& input)
|
|||||||
|
|
||||||
void RegisterScriptFunctions(const ScriptRequest& rq)
|
void RegisterScriptFunctions(const ScriptRequest& rq)
|
||||||
{
|
{
|
||||||
ScriptFunction::Register<&StartAtlas>(rq, "RestartInAtlas");
|
|
||||||
ScriptFunction::Register<&AtlasIsAvailable>(rq, "AtlasIsAvailable");
|
ScriptFunction::Register<&AtlasIsAvailable>(rq, "AtlasIsAvailable");
|
||||||
ScriptFunction::Register<&IsAtlasRunning>(rq, "IsAtlasRunning");
|
ScriptFunction::Register<&IsAtlasRunning>(rq, "IsAtlasRunning");
|
||||||
ScriptFunction::Register<&OpenURL>(rq, "OpenURL");
|
ScriptFunction::Register<&OpenURL>(rq, "OpenURL");
|
||||||
|
|||||||
Reference in New Issue
Block a user