mirror of
https://gitea.wildfiregames.com/0ad/0ad.git
synced 2026-06-21 03:06:29 +00:00
Support std::optional in FromJSVal
This commit introduces support for std::optional<T> in
Script::FromJSVal. When a JavaScript value is undefined or null, the
resulting optional is set to std::nullopt; otherwise, the value is
converted and wrapped.
This change allows components to cleanly handle optional script values
without needing manual null checks or exception handling in C++.
As a direct application of this feature, the Identity component now uses
std::optional<std::wstring> for the return value of GetCiv(). This
resolves a bug where formation templates (e.g., those inheriting from
template_formation.xml) do not explicitly define a civ. After commit
03f7903fec, the code assumed GetCiv() would always return a valid
string, leading to undefined behavior when it was missing.
With this update:
- GetCiv() returning undefined results in an empty optional.
- The Identity component defaults to an empty civilization string ("")
when the civ is not defined.
- This avoids crashes or actor parsing errors for civ-less templates and
improves robustness in script-C++ interaction.
Closes: #8107
Fixes: #8091
This commit is contained in:
@@ -23,6 +23,8 @@
|
||||
#include "ScriptExtraHeaders.h" // for typed arrays
|
||||
|
||||
#include <limits>
|
||||
#include <optional>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
namespace Script
|
||||
@@ -32,6 +34,21 @@ namespace Script
|
||||
*/
|
||||
template<typename T> bool FromJSVal(const ScriptRequest& rq, const JS::HandleValue val, T& ret);
|
||||
|
||||
template<typename T>
|
||||
bool FromJSVal(const ScriptRequest& rq, JS::HandleValue v, std::optional<T>& out)
|
||||
{
|
||||
if (v.isNullOrUndefined())
|
||||
{
|
||||
out = std::nullopt;
|
||||
return true;
|
||||
}
|
||||
T value;
|
||||
if (!FromJSVal(rq, v, value))
|
||||
return false;
|
||||
out = std::move(value);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a C++ type to a JS::Value. (This might trigger GC. The return
|
||||
* value must be rooted if you don't want it to be collected.)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2022 Wildfire Games.
|
||||
/* Copyright (C) 2025 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
@@ -21,6 +21,7 @@
|
||||
|
||||
#include "simulation2/system/InterfaceScripted.h"
|
||||
#include "simulation2/scripting/ScriptComponent.h"
|
||||
#include <optional>
|
||||
|
||||
|
||||
BEGIN_INTERFACE_WRAPPER(Identity)
|
||||
@@ -43,7 +44,8 @@ public:
|
||||
|
||||
std::wstring GetCiv() override
|
||||
{
|
||||
return m_Script.Call<std::wstring>("GetCiv");
|
||||
std::optional<std::wstring> civ{m_Script.Call<std::optional<std::wstring>>("GetCiv")};
|
||||
return !civ || !civ.has_value() ? L"" : *civ;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user