Index: source/lobby/XmppClient.h =================================================================== --- source/lobby/XmppClient.h +++ source/lobby/XmppClient.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Wildfire Games. +/* Copyright (C) 2020 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -23,7 +23,6 @@ #include #include "glooxwrapper/glooxwrapper.h" -#include "scriptinterface/ScriptVal.h" class ScriptInterface; Index: source/lobby/scripting/JSInterface_Lobby.cpp =================================================================== --- source/lobby/scripting/JSInterface_Lobby.cpp +++ source/lobby/scripting/JSInterface_Lobby.cpp @@ -27,7 +27,6 @@ #include "ps/CStr.h" #include "ps/Util.h" #include "scriptinterface/ScriptInterface.h" -#include "scriptinterface/ScriptVal.h" #include "third_party/encryption/pkcs5_pbkdf2.h" Index: source/network/NetClient.h =================================================================== --- source/network/NetClient.h +++ source/network/NetClient.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Wildfire Games. +/* Copyright (C) 2020 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -21,7 +21,6 @@ #include "network/fsm.h" #include "network/NetFileTransfer.h" #include "network/NetHost.h" -#include "scriptinterface/ScriptVal.h" #include "scriptinterface/ScriptInterface.h" #include "ps/CStr.h" Index: source/network/NetMessages.h =================================================================== --- source/network/NetMessages.h +++ source/network/NetMessages.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2018 Wildfire Games. +/* Copyright (C) 2020 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -24,7 +24,7 @@ #define NETMESSAGES_H #include "ps/CStr.h" -#include "scriptinterface/ScriptVal.h" +#include "scriptinterface/ScriptTypes.h" #define PS_PROTOCOL_MAGIC 0x5073013f // 'P', 's', 0x01, '?' #define PS_PROTOCOL_MAGIC_RESPONSE 0x50630121 // 'P', 'c', 0x01, '!' Index: source/network/NetSession.h =================================================================== --- source/network/NetSession.h +++ source/network/NetSession.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Wildfire Games. +/* Copyright (C) 2020 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -22,7 +22,6 @@ #include "network/NetFileTransfer.h" #include "network/NetHost.h" #include "ps/CStr.h" -#include "scriptinterface/ScriptVal.h" /** * Report the peer if we didn't receive a packet after this time (milliseconds). Index: source/ps/Game.h =================================================================== --- source/ps/Game.h +++ source/ps/Game.h @@ -22,7 +22,7 @@ #include "ps/Errors.h" #include "ps/Filesystem.h" -#include "scriptinterface/ScriptVal.h" +#include "scriptinterface/ScriptTypes.h" #include "simulation2/helpers/Player.h" class CWorld; Index: source/ps/scripting/JSInterface_VFS.cpp =================================================================== --- source/ps/scripting/JSInterface_VFS.cpp +++ source/ps/scripting/JSInterface_VFS.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Wildfire Games. +/* Copyright (C) 2020 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -23,7 +23,6 @@ #include "ps/CLogger.h" #include "ps/CStr.h" #include "ps/Filesystem.h" -#include "scriptinterface/ScriptVal.h" #include "scriptinterface/ScriptInterface.h" #include Index: source/scriptinterface/ScriptVal.h =================================================================== --- source/scriptinterface/ScriptVal.h +++ /dev/null @@ -1,85 +0,0 @@ -/* Copyright (C) 2020 Wildfire Games. - * This file is part of 0 A.D. - * - * 0 A.D. is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * 0 A.D. is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with 0 A.D. If not, see . - */ - -#ifndef INCLUDED_SCRIPTVAL -#define INCLUDED_SCRIPTVAL - -#include "ScriptTypes.h" - -/** - * A default constructible wrapper around JS::PersistentRootedValue - * - * It's a very common case that we need to store JS::Values on the heap as - * class members and only need them conditionally or want to initialize - * them after the constructor because we don't have the runtime available yet. - * Use it in these cases, but prefer to use JS::PersistentRootedValue directly - * if initializing it with a runtime/context in the constructor isn't a problem. - */ - template -class DefPersistentRooted -{ -public: - DefPersistentRooted() - { - } - - DefPersistentRooted(JSRuntime* rt) - { - m_Val.reset(new JS::PersistentRooted(rt)); - } - - DefPersistentRooted(JSRuntime* rt, JS::HandleValue val) - { - m_Val.reset(new JS::PersistentRooted(rt, val)); - } - - DefPersistentRooted(JSContext* cx, JS::Handle val) - { - m_Val.reset(new JS::PersistentRooted(cx, val)); - } - - void clear() - { - m_Val = nullptr; - } - - inline bool uninitialized() - { - return m_Val == nullptr; - } - - inline JS::PersistentRooted& get() const - { - ENSURE(m_Val); - return *m_Val; - } - - inline void set(JSRuntime* rt, T val) - { - m_Val.reset(new JS::PersistentRooted(rt, val)); - } - - inline void set(JSContext* cx, T val) - { - m_Val.reset(new JS::PersistentRooted(cx, val)); - } - -private: - std::unique_ptr > m_Val; -}; - -#endif // INCLUDED_SCRIPTVAL Index: source/simulation2/Simulation2.h =================================================================== --- source/simulation2/Simulation2.h +++ source/simulation2/Simulation2.h @@ -19,7 +19,6 @@ #define INCLUDED_SIMULATION2 #include "lib/file/vfs/vfs_path.h" -#include "scriptinterface/ScriptVal.h" #include "simulation2/helpers/SimulationCommand.h" #include "simulation2/system/CmpPtr.h" #include "simulation2/system/Components.h" Index: source/simulation2/scripting/MessageTypeConversions.cpp =================================================================== --- source/simulation2/scripting/MessageTypeConversions.cpp +++ source/simulation2/scripting/MessageTypeConversions.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Wildfire Games. +/* Copyright (C) 2020 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -54,10 +54,10 @@ JS::Value CMessage::ToJSValCached(const ScriptInterface& scriptInterface) const { - if (!m_Cached) - m_Cached.reset(new JS::PersistentRootedValue(scriptInterface.GetJSRuntime(), ToJSVal(scriptInterface))); + if (!m_Cached.initialized()) + m_Cached.init(scriptInterface.GetJSRuntime(), ToJSVal(scriptInterface)); - return m_Cached->get(); + return m_Cached; } //////////////////////////////// Index: source/simulation2/serialization/ISerializer.h =================================================================== --- source/simulation2/serialization/ISerializer.h +++ source/simulation2/serialization/ISerializer.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2011 Wildfire Games. +/* Copyright (C) 2020 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -20,7 +20,6 @@ #include "maths/Fixed.h" #include "ps/Errors.h" -#include "scriptinterface/ScriptVal.h" ERROR_GROUP(Serialize); ERROR_TYPE(Serialize, OutOfBounds); Index: source/simulation2/system/ComponentManager.h =================================================================== --- source/simulation2/system/ComponentManager.h +++ source/simulation2/system/ComponentManager.h @@ -20,7 +20,6 @@ #include "ps/Filesystem.h" #include "scriptinterface/ScriptInterface.h" -#include "scriptinterface/ScriptVal.h" #include "simulation2/helpers/Player.h" #include "simulation2/system/Components.h" #include "simulation2/system/Entity.h" @@ -70,8 +69,8 @@ AllocFunc alloc; DeallocFunc dealloc; std::string name; - std::string schema; // RelaxNG fragment - DefPersistentRooted ctor; // only valid if type == CT_Script + std::string schema; // RelaxNG fragment. + JS::PersistentRootedValue ctor; // Only valid if type == CT_Script. }; public: Index: source/simulation2/system/ComponentManager.cpp =================================================================== --- source/simulation2/system/ComponentManager.cpp +++ source/simulation2/system/ComponentManager.cpp @@ -254,10 +254,14 @@ ctWrapper.alloc, ctWrapper.dealloc, cname, - schema, - DefPersistentRooted(cx, ctor) + schema }; componentManager->m_ComponentTypesById[cid] = std::move(ct); + // Done out-of line as the PersistentRooted needs to take ownership of ctor, + // and that does not work with moving the PersistentRooted as of SM45. + // Call reset() because we might be hotloading and need to clear existing ctor. + componentManager->m_ComponentTypesById[cid].ctor.reset(); + componentManager->m_ComponentTypesById[cid].ctor.init(cx, ctor); componentManager->m_CurrentComponent = cid; // needed by Subscribe @@ -537,7 +541,7 @@ void CComponentManager::RegisterComponentType(InterfaceId iid, ComponentTypeId cid, AllocFunc alloc, DeallocFunc dealloc, const char* name, const std::string& schema) { - ComponentType c{ CT_Native, iid, alloc, dealloc, name, schema, DefPersistentRooted() }; + ComponentType c{ CT_Native, iid, alloc, dealloc, name, schema }; m_ComponentTypesById.insert(std::make_pair(cid, std::move(c))); m_ComponentTypeIdsByName[name] = cid; } @@ -545,7 +549,7 @@ void CComponentManager::RegisterComponentTypeScriptWrapper(InterfaceId iid, ComponentTypeId cid, AllocFunc alloc, DeallocFunc dealloc, const char* name, const std::string& schema) { - ComponentType c{ CT_ScriptWrapper, iid, alloc, dealloc, name, schema, DefPersistentRooted() }; + ComponentType c{ CT_ScriptWrapper, iid, alloc, dealloc, name, schema }; m_ComponentTypesById.insert(std::make_pair(cid, std::move(c))); m_ComponentTypeIdsByName[name] = cid; // TODO: merge with RegisterComponentType @@ -757,7 +761,7 @@ JS::RootedValue obj(cx); if (ct.type == CT_Script) { - m_ScriptInterface.CallConstructor(ct.ctor.get(), JS::HandleValueArray::empty(), &obj); + m_ScriptInterface.CallConstructor(ct.ctor, JS::HandleValueArray::empty(), &obj); if (obj.isNull()) { LOGERROR("Script component constructor failed"); Index: source/simulation2/system/Message.h =================================================================== --- source/simulation2/system/Message.h +++ source/simulation2/system/Message.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2017 Wildfire Games. +/* Copyright (C) 2020 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -19,7 +19,6 @@ #define INCLUDED_MESSAGE #include "scriptinterface/ScriptTypes.h" -#include "scriptinterface/ScriptVal.h" class CMessage { @@ -34,7 +33,7 @@ virtual JS::Value ToJSVal(const ScriptInterface&) const = 0; JS::Value ToJSValCached(const ScriptInterface&) const; private: - mutable std::unique_ptr m_Cached; + mutable JS::PersistentRootedValue m_Cached; }; // TODO: GetType could be replaced with a plain member variable to avoid some // virtual calls, if that turns out to be worthwhile