Pyrogenesis HEAD
Pyrogenesis, a RTS Engine
ScriptComponent.h
Go to the documentation of this file.
1/* Copyright (C) 2022 Wildfire Games.
2 * This file is part of 0 A.D.
3 *
4 * 0 A.D. is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * 0 A.D. is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#ifndef INCLUDED_SCRIPTCOMPONENT
19#define INCLUDED_SCRIPTCOMPONENT
20
21// These headers are included because they are required in component implementation,
22// so including them here transitively makes sense.
31
32#include "ps/CLogger.h"
33
35{
37public:
38 CComponentTypeScript(const ScriptInterface& scriptInterface, JS::HandleValue instance);
39
40 JS::Value GetInstance() const { return m_Instance.get(); }
41
42 void Init(const CParamNode& paramNode, entity_id_t ent);
43 void Deinit();
44 void HandleMessage(const CMessage& msg, bool global);
45
46 void Serialize(ISerializer& serialize);
47 void Deserialize(const CParamNode& paramNode, IDeserializer& deserialize, entity_id_t ent);
48
49 template<typename R, typename... Ts>
50 R Call(const char* funcname, const Ts&... params) const
51 {
52 R ret;
54 if (ScriptFunction::Call(rq, m_Instance, funcname, ret, params...))
55 return ret;
56 LOGERROR("Error calling component script function %s", funcname);
57 return R();
58 }
59
60 // CallRef is mainly used for returning script values with correct stack rooting.
61 template<typename R, typename... Ts>
62 void CallRef(const char* funcname, R ret, const Ts&... params) const
63 {
65 if (!ScriptFunction::Call(rq, m_Instance, funcname, ret, params...))
66 LOGERROR("Error calling component script function %s", funcname);
67 }
68
69 template<typename... Ts>
70 void CallVoid(const char* funcname, const Ts&... params) const
71 {
73 if (!ScriptFunction::CallVoid(rq, m_Instance, funcname, params...))
74 LOGERROR("Error calling component script function %s", funcname);
75 }
76
77private:
79 JS::PersistentRootedValue m_Instance;
80};
81
82#define REGISTER_COMPONENT_SCRIPT_WRAPPER(cname) \
83 void RegisterComponentType_##cname(CComponentManager& mgr) \
84 { \
85 IComponent::RegisterComponentTypeScriptWrapper(mgr, CCmp##cname::GetInterfaceId(), CID_##cname, CCmp##cname::Allocate, CCmp##cname::Deallocate, #cname, CCmp##cname::GetSchema()); \
86 CCmp##cname::ClassInit(mgr); \
87 }
88
89
90#define DEFAULT_SCRIPT_WRAPPER(cname) \
91 static void ClassInit(CComponentManager& UNUSED(componentManager)) { } \
92 static IComponent* Allocate(const ScriptInterface& scriptInterface, JS::HandleValue instance) \
93 { \
94 return new CCmp##cname(scriptInterface, instance); \
95 } \
96 static void Deallocate(IComponent* cmp) \
97 { \
98 delete static_cast<CCmp##cname*> (cmp); \
99 } \
100 CCmp##cname(const ScriptInterface& scriptInterface, JS::HandleValue instance) : m_Script(scriptInterface, instance) { } \
101 static std::string GetSchema() \
102 { \
103 return "<a:component type='script-wrapper'/><empty/>"; \
104 } \
105 void Init(const CParamNode& paramNode) override \
106 { \
107 m_Script.Init(paramNode, GetEntityId()); \
108 } \
109 void Deinit() override \
110 { \
111 m_Script.Deinit(); \
112 } \
113 void HandleMessage(const CMessage& msg, bool global) override \
114 { \
115 m_Script.HandleMessage(msg, global); \
116 } \
117 void Serialize(ISerializer& serialize) override \
118 { \
119 m_Script.Serialize(serialize); \
120 } \
121 void Deserialize(const CParamNode& paramNode, IDeserializer& deserialize) override \
122 { \
123 m_Script.Deserialize(paramNode, deserialize, GetEntityId()); \
124 } \
125 JS::Value GetJSInstance() const override \
126 { \
127 return m_Script.GetInstance(); \
128 } \
129 int GetComponentTypeId() const override \
130 { \
131 return CID_##cname; \
132 } \
133 private: \
134 CComponentTypeScript m_Script; \
135 public:
136
137#endif // INCLUDED_SCRIPTCOMPONENT
#define LOGERROR(...)
Definition: CLogger.h:37
Definition: ScriptComponent.h:35
void Deinit()
Definition: ScriptComponent.cpp:43
JS::PersistentRootedValue m_Instance
Definition: ScriptComponent.h:79
JS::Value GetInstance() const
Definition: ScriptComponent.h:40
const ScriptInterface & m_ScriptInterface
Definition: ScriptComponent.h:78
void HandleMessage(const CMessage &msg, bool global)
Definition: ScriptComponent.cpp:49
NONCOPYABLE(CComponentTypeScript)
void CallVoid(const char *funcname, const Ts &... params) const
Definition: ScriptComponent.h:70
void Serialize(ISerializer &serialize)
Definition: ScriptComponent.cpp:61
void Init(const CParamNode &paramNode, entity_id_t ent)
Definition: ScriptComponent.cpp:35
CComponentTypeScript(const ScriptInterface &scriptInterface, JS::HandleValue instance)
Definition: ScriptComponent.cpp:29
void CallRef(const char *funcname, R ret, const Ts &... params) const
Definition: ScriptComponent.h:62
R Call(const char *funcname, const Ts &... params) const
Definition: ScriptComponent.h:50
void Deserialize(const CParamNode &paramNode, IDeserializer &deserialize, entity_id_t ent)
Definition: ScriptComponent.cpp:81
Definition: Message.h:26
An entity initialisation parameter node.
Definition: ParamNode.h:151
Deserialization interface; see serialization overview.
Definition: IDeserializer.h:35
Serialization interface; see serialization overview.
Definition: ISerializer.h:121
static bool CallVoid(const ScriptRequest &rq, JS::HandleValue val, const char *name, const Args &... args)
Call a JS function name, property of object val, with the arguments args.
Definition: FunctionWrapper.h:357
static bool Call(const ScriptRequest &rq, JS::HandleValue val, const char *name, R &ret, const Args &... args)
Call a JS function name, property of object val, with the arguments args.
Definition: FunctionWrapper.h:340
Abstraction around a SpiderMonkey JS::Realm.
Definition: ScriptInterface.h:72
Spidermonkey maintains some 'local' state via the JSContext* object.
Definition: ScriptRequest.h:60
u32 entity_id_t
Entity ID type.
Definition: Entity.h:29