!TX (CryEngine) (DEV-6170) Added missed virtual dtors, removed unnecessary semicolons...
[CRYENGINE.git] / Code / CryEngine / CryCommon / CryScriptSystem / IScriptSystem.h
blob160bfcf57991061208c104e44dc6df9d1040bec6
1 // Copyright 2001-2018 Crytek GmbH / Crytek Group. All rights reserved.
3 //! \cond INTERNAL
5 #pragma once
7 #include <CryCore/CryVariant.h>
8 #include <CryCore/functor.h>
9 #include <CryCore/AlignmentTools.h>
10 #include <CrySystem/ISystem.h>
11 #include <CrySystem/IEngineModule.h>
13 class ICrySizer;
14 class SmartScriptTable;
16 struct IFunctionHandler;
17 struct IScriptTable;
18 struct ISerialize;
19 struct ISystem;
20 struct IWeakScriptObject;
22 //! Script function reference.
23 struct SScriptFuncHandle {};
24 typedef SScriptFuncHandle* HSCRIPTFUNCTION;
26 //! ScriptHandle type used to pass pointers and handles to/from Lua script.
27 //! As Lua script do not natively support integers, full range integers used as handles must be stored in Lua using this class.
28 union ScriptHandle
30 UINT_PTR n;
31 void* ptr;
33 ScriptHandle() : ptr(0) {}
34 ScriptHandle(int i) : n(i) {}
35 ScriptHandle(void* p) : ptr(p) {}
37 bool operator==(const ScriptHandle& rhs) const { return ptr == rhs.ptr; }
40 //! Template to wrap an int into a ScriptHandle (to guarantee the proper handling of full-range ints).
41 template<typename IntType>
42 inline ScriptHandle IntToHandle(IntType const nInt) { ScriptHandle h; h.n = static_cast<UINT_PTR>(nInt); return h; }
44 //! Template to convert a ScriptHandle to an int type.
45 template<typename IntType>
46 inline IntType HandleToInt(ScriptHandle const hHandle) { return static_cast<IntType>(hHandle.n); }
48 struct ScriptUserData
50 void* ptr;
51 int nRef;
53 ScriptUserData() : ptr(nullptr), nRef(0) {}
54 ScriptUserData(void* const _ptr, int ref) : ptr(_ptr), nRef(ref) {}
56 bool operator==(const ScriptUserData& rhs) const { return ptr == rhs.ptr && nRef == rhs.nRef; }
59 typedef int HBREAKPOINT;
61 enum ELuaDebugMode
63 eLDM_NoDebug = 0,
64 eLDM_FullDebug = 1,
65 eLDM_OnlyErrors = 2
68 enum BreakState
70 bsStepNext,
71 bsStepInto,
72 bsStepOut,
73 bsContinue,
74 bsNoBreak
77 ////////////////////////////////////////////////////////////////////////////
78 enum ScriptVarType
80 svtNull = 0,
81 svtString,
82 svtNumber,
83 svtBool,
84 svtFunction,
85 svtObject,
86 svtPointer,
87 svtUserData,
90 //! Any Script value.
91 enum class EScriptAnyType
93 Any = 0,
94 Nil,
95 Boolean,
96 Handle,
97 Number,
98 String,
99 Table,
100 Function,
101 UserData,
102 Vector,
105 struct ScriptAnyValue
107 ~ScriptAnyValue(); // Implemented at the end of header.
109 ScriptAnyValue() {}
110 ScriptAnyValue(EScriptAnyType type); // Implemented at the end of header.
111 ScriptAnyValue(bool bValue) : m_data(bValue) {}
112 ScriptAnyValue(int value) : m_data(static_cast<float>(value)) {}
113 ScriptAnyValue(unsigned int value) : m_data(static_cast<float>(value)) {}
114 ScriptAnyValue(float value) : m_data(value) {}
115 ScriptAnyValue(const char* value) : m_data(value) {}
116 ScriptAnyValue(ScriptHandle value) : m_data(value) {}
117 ScriptAnyValue(HSCRIPTFUNCTION value);
118 ScriptAnyValue(const Vec3& value) : m_data(value) {}
119 ScriptAnyValue(const Ang3& value) : m_data(static_cast<Vec3>(value)) {}
120 ScriptAnyValue(const ScriptUserData& value) : m_data(value) {}
121 ScriptAnyValue(IScriptTable* value); // Implemented at the end of header.
122 ScriptAnyValue(const SmartScriptTable& value); // Implemented at the end of header.
124 ScriptAnyValue(const ScriptAnyValue& value); // Implemented at the end of header.
125 void Swap(ScriptAnyValue& value); // Implemented at the end of header.
127 ScriptAnyValue& operator=(const ScriptAnyValue& rhs)
129 ScriptAnyValue temp(rhs);
130 Swap(temp);
131 return *this;
134 //! Compares 2 values.
135 bool operator==(const ScriptAnyValue& rhs) const;
136 bool operator!=(const ScriptAnyValue& rhs) const { return !(*this == rhs); }
138 bool CopyTo(bool& value) const { if (GetType() == EScriptAnyType::Boolean) { value = GetBool(); return true; } return false; }
139 bool CopyTo(int& value) const { if (GetType() == EScriptAnyType::Number) { value = static_cast<int>(GetNumber()); return true; } return false; }
140 bool CopyTo(unsigned int& value) const { if (GetType() == EScriptAnyType::Number) { value = static_cast<unsigned int>(GetNumber()); return true; } return false; }
141 bool CopyTo(float& value) const { if (GetType() == EScriptAnyType::Number) { value = GetNumber(); return true; } return false; }
142 bool CopyTo(const char*& value) const { if (GetType() == EScriptAnyType::String) { value = GetString(); return true; } return false; }
143 bool CopyTo(char*& value) const { if (GetType() == EScriptAnyType::String) { value = const_cast<char*>(GetString()); return true; } return false; }
144 bool CopyTo(string& value) const { if (GetType() == EScriptAnyType::String) { value = GetString(); return true; } return false; }
145 bool CopyTo(ScriptHandle& value) const { if (GetType() == EScriptAnyType::Handle) { value = GetScriptHandle(); return true; } return false; }
146 bool CopyTo(HSCRIPTFUNCTION& value) const;
147 bool CopyTo(Vec3& value) const { if (GetType() == EScriptAnyType::Vector) { value = GetVector(); return true; } return false; }
148 bool CopyTo(Ang3& value) const { if (GetType() == EScriptAnyType::Vector) { value = GetVector(); return true; } return false; }
149 bool CopyTo(ScriptUserData &value) { if (GetType() == EScriptAnyType::UserData) { value = GetUserData(); return true; } return false; }
150 bool CopyTo(IScriptTable*& value) const; // Implemented at the end of header.
151 bool CopyTo(SmartScriptTable& value) const; // Implemented at the end of header.
152 bool CopyFromTableToXYZ(float& x, float& y, float& z) const;
153 bool CopyFromTableTo(Vec3& value) const { return CopyFromTableToXYZ(value.x, value.y, value.z); }
154 bool CopyFromTableTo(Ang3& value) const { return CopyFromTableToXYZ(value.x, value.y, value.z); }
156 //! Clears any variable to uninitialized state.
157 // Implemented at the end of header.
158 void Clear();
160 //! Only initialize type.
161 ScriptAnyValue(bool, int) { m_data.emplace<bool>(); }
162 ScriptAnyValue(int, int) { m_data.emplace<float>(); }
163 ScriptAnyValue(unsigned int, int) { m_data.emplace<float>(); }
164 ScriptAnyValue(float&, int) { m_data.emplace<float>(); }
165 ScriptAnyValue(const char*, int) { m_data.emplace<const char*>(); }
166 ScriptAnyValue(ScriptHandle, int) { m_data.emplace<ScriptHandle>(); }
167 ScriptAnyValue(HSCRIPTFUNCTION, int) { m_data.emplace<HSCRIPTFUNCTION>(); }
168 ScriptAnyValue(Vec3&, int) { m_data.emplace<Vec3>(); }
169 ScriptAnyValue(Ang3&, int) { m_data.emplace<Vec3>(); }
170 ScriptAnyValue(ScriptUserData, int) { m_data.emplace<ScriptUserData>(); }
171 ScriptAnyValue(IScriptTable* _table, int);
172 ScriptAnyValue(const SmartScriptTable& value, int);
174 ScriptVarType GetVarType() const
176 switch (GetType())
178 case EScriptAnyType::Any:
179 return svtNull;
180 case EScriptAnyType::Nil:
181 return svtNull;
182 case EScriptAnyType::Boolean:
183 return svtBool;
184 case EScriptAnyType::Handle:
185 return svtPointer;
186 case EScriptAnyType::Number:
187 return svtNumber;
188 case EScriptAnyType::String:
189 return svtString;
190 case EScriptAnyType::Table:
191 return svtObject;
192 case EScriptAnyType::Function:
193 return svtFunction;
194 case EScriptAnyType::UserData:
195 return svtUserData;
196 case EScriptAnyType::Vector:
197 return svtObject;
198 default:
199 return svtNull;
203 void GetMemoryUsage(ICrySizer* pSizer) const {}
205 EScriptAnyType GetType() const
207 return static_cast<EScriptAnyType>(m_data.index());;
210 void SetAny()
212 m_data.emplace<static_cast<size_t>(EScriptAnyType::Any)>(nullptr);
215 void SetNil()
217 m_data.emplace<static_cast<size_t>(EScriptAnyType::Nil)>(nullptr);
220 bool GetBool() const
222 CRY_ASSERT(GetType() == EScriptAnyType::Boolean && stl::holds_alternative<bool>(m_data));
223 return stl::get<bool>(m_data);
225 void SetBool(bool bValue)
227 m_data = bValue;
230 ScriptHandle GetScriptHandle() const
232 CRY_ASSERT(GetType() == EScriptAnyType::Handle && stl::holds_alternative<ScriptHandle>(m_data));
233 return stl::get<ScriptHandle>(m_data);
235 void SetScriptHandle(ScriptHandle value)
237 m_data = value;
240 float GetNumber() const
242 CRY_ASSERT(GetType() == EScriptAnyType::Number && stl::holds_alternative<float>(m_data));
243 return stl::get<float>(m_data);
245 void SetNumber(float value)
247 m_data = value;
250 const char* GetString() const
252 CRY_ASSERT(GetType() == EScriptAnyType::String && stl::holds_alternative<const char*>(m_data));
253 return stl::get<const char*>(m_data);
255 void SetString(const char* szValue)
257 m_data = szValue;
260 IScriptTable* GetScriptTable()
262 CRY_ASSERT(GetType() == EScriptAnyType::Table && stl::holds_alternative<IScriptTable*>(m_data));
263 return stl::get<IScriptTable*>(m_data);
265 IScriptTable* GetScriptTable() const
267 return const_cast<ScriptAnyValue*>(this)->GetScriptTable();
269 void SetScriptTable(IScriptTable* const pValue)
271 m_data = pValue;
274 HSCRIPTFUNCTION GetScriptFunction()
276 CRY_ASSERT(GetType() == EScriptAnyType::Function && stl::holds_alternative<HSCRIPTFUNCTION>(m_data));
277 return stl::get<HSCRIPTFUNCTION>(m_data);
279 const HSCRIPTFUNCTION GetScriptFunction() const
281 return const_cast<ScriptAnyValue*>(this)->GetScriptFunction();
283 void SetScriptFunction(HSCRIPTFUNCTION value)
285 m_data = value;
288 const ScriptUserData& GetUserData() const
290 CRY_ASSERT(GetType() == EScriptAnyType::UserData && stl::holds_alternative<ScriptUserData>(m_data));
291 return stl::get<ScriptUserData>(m_data);
293 void SetUserData(const ScriptUserData& value)
295 m_data = value;
298 const Vec3& GetVector() const
300 CRY_ASSERT(GetType() == EScriptAnyType::Vector && stl::holds_alternative<Vec3>(m_data));
301 return stl::get<Vec3>(m_data);
303 void SetVector(const Vec3& value)
305 m_data = value;
308 private:
309 typedef CryVariant<
310 void*,
311 std::nullptr_t,
312 bool,
313 ScriptHandle,
314 float,
315 const char*,
316 IScriptTable*,
317 HSCRIPTFUNCTION,
318 ScriptUserData,
319 Vec3
320 > TScriptVariant;
322 static_assert(std::is_same<stl::variant_alternative<static_cast<size_t>(EScriptAnyType::Any), TScriptVariant>::type, void*>::value, "Enum value and variant index do not match!");
323 static_assert(std::is_same<stl::variant_alternative<static_cast<size_t>(EScriptAnyType::Nil), TScriptVariant>::type, std::nullptr_t>::value, "Enum value and variant index do not match!");
324 static_assert(std::is_same<stl::variant_alternative<static_cast<size_t>(EScriptAnyType::Boolean), TScriptVariant>::type, bool>::value, "Enum value and variant index do not match!");
325 static_assert(std::is_same<stl::variant_alternative<static_cast<size_t>(EScriptAnyType::Number), TScriptVariant>::type, float>::value, "Enum value and variant index do not match!");
326 static_assert(std::is_same<stl::variant_alternative<static_cast<size_t>(EScriptAnyType::String), TScriptVariant>::type, const char*>::value, "Enum value and variant index do not match!");
327 static_assert(std::is_same<stl::variant_alternative<static_cast<size_t>(EScriptAnyType::Table), TScriptVariant>::type, IScriptTable*>::value, "Enum value and variant index do not match!");
328 static_assert(std::is_same<stl::variant_alternative<static_cast<size_t>(EScriptAnyType::Function), TScriptVariant>::type, HSCRIPTFUNCTION>::value, "Enum value and variant index do not match!");
329 static_assert(std::is_same<stl::variant_alternative<static_cast<size_t>(EScriptAnyType::UserData), TScriptVariant>::type, ScriptUserData>::value, "Enum value and variant index do not match!");
330 static_assert(std::is_same<stl::variant_alternative<static_cast<size_t>(EScriptAnyType::Vector), TScriptVariant>::type, Vec3>::value, "Enum value and variant index do not match!");
332 TScriptVariant m_data;
335 struct IScriptSystemEngineModule : public Cry::IDefaultModule
337 CRYINTERFACE_DECLARE_GUID(IScriptSystemEngineModule, "39b5373f-b298-4aa1-b691-88ed53cf5f9d"_cry_guid);
340 //! Scripting Engine interface.
341 //! This interface is mapped 1:1 on a script state.
342 //! All scripts loaded from the same interface instance are visible with each others'.
343 struct IScriptSystem
345 // <interfuscator:shuffle>
346 virtual ~IScriptSystem(){}
348 //! Updates the system, per frame.
349 virtual void Update(void) = 0;
351 //! Sets the rate of Garbage Collection for script system.
352 //! \param fRate Rate in seconds.
353 virtual void SetGCFrequency(const float fRate) = 0;
355 //! Sets the environment of the given function.
356 //! \param scriptFunction Function to receive the environment.
357 //! \param pEnv Environment to set.
358 virtual void SetEnvironment(HSCRIPTFUNCTION scriptFunction, IScriptTable* pEnv) = 0;
360 //! Gets the environment of the given function.
361 //! \param scriptFunction Function to receive the environment.
362 //! \return Pointer to a script table containing the environment
363 virtual IScriptTable* GetEnvironment(HSCRIPTFUNCTION scriptFunction) = 0;
365 //! Loads and runs a script file.
366 //! \param sFileName Path of the script file.
367 //! \param bRaiseError When set to true, the script engine will call CryWarning when an error in the script file occurs.
368 //! \return false if the execution fails, otherwise it will be true.
369 //! \note All global variables and functions declared in the executed script will persist for all the script system lifetime.
370 virtual bool ExecuteFile(const char* sFileName, bool bRaiseError = true, bool bForceReload = false, IScriptTable* pEnv = 0) = 0;
372 //! Executes an ASCII buffer.
373 //! \param sBuffer An 8bit ASCII buffer containing the script that must be executed.
374 //! \param bRaiseError When set to true, the script engine will call CryWarning when an error in the script file occurs.
375 //! \param sBufferDescription Used as a name to describe the buffer.
376 //! \return false if the execution fails, otherwise it will be true.
377 //! \note All global variables and functions declared in the executed script will persist for all the script system lifetime.
378 virtual bool ExecuteBuffer(const char* sBuffer, size_t nSize, const char* sBufferDescription = "", IScriptTable* pEnv = 0) = 0;
380 //! Unloads a script.
381 //! \param sFileName Path of the script file.
382 //! \note The script engine never loads the same file twice because it internally stores a list of the loaded files. Calling this functions will remove the script file from this list.
383 //! \see UnloadScripts.
384 virtual void UnloadScript(const char* sFileName) = 0;
386 //! Unloads all the scripts.
387 virtual void UnloadScripts() = 0;
389 //! Reloads a script.
390 //! \param sFileName Path of the script file to reload.
391 //! \param bRaiseError When set to true, the script engine will call CryWarning when an error in the script file occurs.
392 //! \return False if the execution fails, otherwise it will be true.
393 //! \see ReloadScripts
394 virtual bool ReloadScript(const char* sFileName, bool bRaiseError = true) = 0;
396 //! Reloads all the scripts previously loaded.
397 //! \return False if the execution of one of the script fails, otherwise it will be true.
398 virtual bool ReloadScripts() = 0;
400 //! Generates an OnLoadedScriptDump() for every loaded script.
401 virtual void DumpLoadedScripts() = 0;
403 //! Creates a new IScriptTable table accessible to the scripts.
404 //! \return Pointer to the created object, with the reference count of 0.
405 virtual IScriptTable* CreateTable(bool bEmpty = false) = 0;
407 //! Starts a call to script function.
408 //! \param sTableName Name of the script table that contains the function.
409 //! \param sFuncName Function name.
410 //! \note To call a function in the script object you must: call BeginCall, push all parameters whit PushParam, then call EndCall.
411 //! \code
412 //! m_ScriptSystem->BeginCall("Player","OnInit");.
413 //! m_ScriptSystem->PushParam(pObj);.
414 //! m_ScriptSystem->PushParam(nTime);.
415 //! m_ScriptSystem->EndCall();.
416 //! \endcode
417 virtual int BeginCall(HSCRIPTFUNCTION hFunc) = 0;
419 //! Calls a named method inside specified table.
420 virtual int BeginCall(const char* sFuncName) = 0; // From void to int for error checking.
421 virtual int BeginCall(const char* sTableName, const char* sFuncName) = 0;
423 //! Calls a named method inside specified table.
424 virtual int BeginCall(IScriptTable* pTable, const char* sFuncName) = 0;
426 //! Ends a call to script function.
427 virtual bool EndCall() = 0;
429 //! Ends a call to script function.
430 //! \param[out] any Reference to the variable that will store the eventual return value.
431 virtual bool EndCallAny(ScriptAnyValue& any) = 0;
433 //! Ends a call to script function.
434 //! \param[out] anys Reference to the variable that will store the eventual returning values.
435 virtual bool EndCallAnyN(int n, ScriptAnyValue* anys) = 0;
437 //! Gets reference to the Lua function.
438 //! \note This reference must be released with IScriptSystem::ReleaseFunc().
439 //! \see IScriptSystem::ReleaseFunc()
440 //! @{.
441 virtual HSCRIPTFUNCTION GetFunctionPtr(const char* sFuncName) = 0;
442 virtual HSCRIPTFUNCTION GetFunctionPtr(const char* sTableName, const char* sFuncName) = 0;
443 //! @}.
445 //! Adds new reference to function referenced by HSCRIPTFUNCTION.
446 virtual HSCRIPTFUNCTION AddFuncRef(HSCRIPTFUNCTION f) = 0;
448 //! Adds new reference to function referenced by HSCRIPTFUNCTION.
449 virtual bool CompareFuncRef(HSCRIPTFUNCTION f1, HSCRIPTFUNCTION f2) = 0;
451 //! Frees references created with GetFunctionPtr or GetValue for HSCRIPTFUNCTION.
452 virtual void ReleaseFunc(HSCRIPTFUNCTION f) = 0;
454 //! Properly clones a ScriptAnyValue. It will create new references to objects if appropriate.
455 virtual ScriptAnyValue CloneAny(const ScriptAnyValue& any) = 0;
457 //! Properly releases a ScriptAnyValue. It will release references to objects if appropriate.
458 virtual void ReleaseAny(const ScriptAnyValue& any) = 0;
460 //! Push a parameter during a function call.
461 virtual void PushFuncParamAny(const ScriptAnyValue& any) = 0;
463 //! Set Global value.
464 virtual void SetGlobalAny(const char* sKey, const ScriptAnyValue& any) = 0;
466 //! Get Global value.
467 virtual bool GetGlobalAny(const char* sKey, ScriptAnyValue& any) = 0;
469 //! Set Global value to Null.
470 virtual void SetGlobalToNull(const char* sKey) { SetGlobalAny(sKey, ScriptAnyValue(EScriptAnyType::Nil)); }
472 virtual IScriptTable* CreateUserData(void* ptr, size_t size) = 0;
474 //! Forces a Garbage collection cycle.
475 //! \note In the current status of the engine the automatic GC is disabled so this function must be called explicitly.
476 virtual void ForceGarbageCollection() = 0;
478 //! Gets number of "garbaged" object.
479 virtual int GetCGCount() = 0;
481 //! \deprecated This is a legacy function.
482 virtual void SetGCThreshhold(int nKb) = 0;
484 //! Releases and destroys the script system.
485 virtual void Release() = 0;
487 //! \note Debug functions.
488 //! @{.
489 virtual void ShowDebugger(const char* pszSourceFile, int iLine, const char* pszReason) = 0;
491 virtual HBREAKPOINT AddBreakPoint(const char* sFile, int nLineNumber) = 0;
492 virtual IScriptTable* GetLocalVariables(int nLevel, bool bRecursive) = 0;
494 //! \return A table containing 1 entry per stack level(aka per call). An entry will look like this table.
495 //! \code
496 //! [1]={
497 //! Description="function bau()",.
498 //! Line=234,.
499 //! Sourcefile="/scripts/bla/bla/bla.lua".
500 //! }
501 //! \endcode
502 virtual IScriptTable* GetCallsStack() = 0;
504 //! Dump callstack to log, can be used during exception handling.
505 virtual void DumpCallStack() = 0;
507 virtual void DebugContinue() = 0;
508 virtual void DebugStepNext() = 0;
509 virtual void DebugStepInto() = 0;
510 virtual void DebugDisable() = 0;
511 virtual BreakState GetBreakState() = 0;
512 //! @}.
514 virtual void GetMemoryStatistics(ICrySizer* pSizer) const = 0;
516 //! \note Is not recursive but combines the hash values of the whole table when the specifies variable is a table, otherwise has to be a Lua function.
517 //! \param sPath Zero terminated path to the variable (e.g. _localplayer.cnt), max 255 characters.
518 //! \param szKey Zero terminated name of the variable (e.g. luaFunc), max 255 characters.
519 //! \param dwHash It is used as input and output.
520 virtual void GetScriptHash(const char* sPath, const char* szKey, unsigned int& dwHash) = 0;
522 virtual void RaiseError(const char* format, ...) PRINTF_PARAMS(2, 3) = 0;
524 //! \note Called one time after initialization of system to register script system console vars.
525 virtual void PostInit() = 0;
527 //////////////////////////////////////////////////////////////////////////
528 virtual void LoadScriptedSurfaceTypes(const char* sFolder, bool bReload) = 0;
530 //! Serializes script timers.
531 virtual void SerializeTimers(ISerialize* pSer) = 0;
533 //! Resets all the script timers.
534 virtual void ResetTimers() = 0;
536 virtual int GetStackSize() const = 0;
538 //! Retrieves size of memory allocated in script.
539 virtual uint32 GetScriptAllocSize() = 0;
541 //! Facility to pre-catch any Lua buffer.
542 virtual HSCRIPTFUNCTION CompileBuffer(const char* sBuffer, size_t nSize, const char* sBufferDesc) = 0;
543 virtual int PreCacheBuffer(const char* sBuffer, size_t nSize, const char* sBufferDesc) = 0;
544 virtual int BeginPreCachedBuffer(int iIndex) = 0;
545 virtual void ClearPreCachedBuffer() = 0;
547 //! Allocate or deallocate through the script system's allocator.
548 virtual void* Allocate(size_t sz) = 0;
549 virtual size_t Deallocate(void* ptr) = 0;
550 // </interfuscator:shuffle>
552 template<class T>
553 bool EndCall(T& value)
555 ScriptAnyValue any(value, 0);
556 return EndCallAny(any) && any.CopyTo(value);
559 template<class T> void PushFuncParam(const T& value) { PushFuncParamAny(value); }
561 template<class T> void SetGlobalValue(const char* sKey, const T& value) { SetGlobalAny(sKey, ScriptAnyValue(value)); }
562 template<class T> bool GetGlobalValue(const char* sKey, T& value)
564 ScriptAnyValue any(value, 0);
565 return GetGlobalAny(sKey, any) && any.CopyTo(value);
569 class CCheckScriptStack
571 public:
572 CCheckScriptStack(IScriptSystem* pSS, const char* file, int line)
574 m_pSS = pSS;
575 m_stackSize = pSS->GetStackSize();
576 m_file = file;
577 m_line = line;
580 ~CCheckScriptStack()
582 #if defined(_DEBUG)
583 int stackSize = m_pSS->GetStackSize();
584 assert(stackSize == m_stackSize);
585 #endif
588 private:
589 IScriptSystem* m_pSS;
590 int m_stackSize;
591 const char* m_file;
592 int m_line;
595 #define CHECK_SCRIPT_STACK_2(x, y) x ## y
596 #define CHECK_SCRIPT_STACK_1(x, y) CHECK_SCRIPT_STACK_2(x, y)
597 #define CHECK_SCRIPT_STACK CCheckScriptStack CHECK_SCRIPT_STACK_1(css_, __COUNTER__)(gEnv->pScriptSystem, __FILE__, __LINE__)
599 ////////////////////////////////////////////////////////////////////////////
600 ////////////////////////////////////////////////////////////////////////////
602 struct IScriptTableDumpSink
604 // <interfuscator:shuffle>
605 virtual ~IScriptTableDumpSink(){}
606 virtual void OnElementFound(const char* sName, ScriptVarType type) = 0;
607 virtual void OnElementFound(int nIdx, ScriptVarType type) = 0;
608 // </interfuscator:shuffle>
611 // Description:
612 // Interface to the iterator of values in script table.
613 // Notes:
614 // This is reference counted interface, when last reference to this interface
615 // is release, object is deleted.
616 // Used together with smart_ptr.
617 // See also:
618 // smart_ptr
619 //////////////////////////////////////////////////////////////////////////
620 struct IScriptTableIterator
622 // <interfuscator:shuffle>
623 virtual ~IScriptTableIterator(){}
624 virtual void AddRef();
625 // Summary:
626 // Decrements reference delete script table iterator.
627 virtual void Release();
629 //! Get next value in the table.
630 virtual bool Next(ScriptAnyValue& var);
631 // </interfuscator:shuffle>
634 ////////////////////////////////////////////////////////////////////////////
635 struct IScriptTable
637 typedef Functor1wRet<IFunctionHandler*, int> FunctionFunctor;
638 typedef int (* UserDataFunction)(IFunctionHandler* pH, void* pBuffer, int nSize);
640 //! Iteration over table parameters.
641 struct Iterator
643 const char* sKey; // This is now redundant.
644 int nKey; // This is now redundant.
645 ScriptAnyValue value;
646 ScriptAnyValue key;
647 struct
649 bool resolvePrototypeTableAsWell;
650 int nStackMarker1; //!< Used for traversing our own table (this is typically the table that overrides properties from prototype tables).
651 int nStackMarker2; //!< Used after our own table is traversed; we then try to traverse the prototype table (gets retrieved via a potential metatable).
652 } internal;
655 //! Structure that describe user data function.
656 struct SUserFunctionDesc
658 const char* sFunctionName; //!< Name of function.
659 const char* sFunctionParams; //!< List of parameters (ex "nSlot,vDirection").
660 const char* sGlobalName; //!< Name of global table (ex "System").
661 FunctionFunctor pFunctor; //!< Pointer to simple function.
662 int nParamIdOffset; //!< Offset of the parameter to accept as 1st function argument.
663 UserDataFunction pUserDataFunc; //!< Pointer to function with associated data buffer.
664 void* pDataBuffer; //!< Pointer to the data buffer associated to the user data function.
665 int nDataSize; //!< Size of data associated with user data function.
667 //! Constructor that initialize all data members to initial state.
668 SUserFunctionDesc() : sFunctionName(""), sFunctionParams(""), sGlobalName(""), nParamIdOffset(0), pUserDataFunc(0), pDataBuffer(0), nDataSize(0) {}
671 // <interfuscator:shuffle>
672 virtual ~IScriptTable(){}
674 //! Gets script system of this table.
675 virtual IScriptSystem* GetScriptSystem() const = 0;
677 //! Increments reference count to the script table.
678 virtual void AddRef() = 0;
680 //! Decrements reference count for script table.
681 //! \note When reference count reaches zero, table will be deleted.
682 virtual void Release() = 0;
684 virtual void Delegate(IScriptTable* pObj) = 0;
685 virtual void* GetUserDataValue() = 0;
687 //! Sets the value of a table member.
688 virtual void SetValueAny(const char* sKey, const ScriptAnyValue& any, bool bChain = false) = 0;
690 //! Gets the value of a table member.
691 virtual bool GetValueAny(const char* sKey, ScriptAnyValue& any, bool bChain = false) = 0;
693 //! Start a Set/Get chain.
694 //! \note This is faster than calling SetValue/GetValue a large number of times.
695 virtual bool BeginSetGetChain() = 0;
697 //! Completes a Set/Get chain.
698 //! \note This is faster than calling SetValue/GetValue a large number of times.
699 virtual void EndSetGetChain() = 0;
701 //! Gets the value type of a table member.
702 //! \param sKey Variable name.
703 //! \return The value type or svtNull if doesn't exist.
704 virtual ScriptVarType GetValueType(const char* sKey) = 0;
706 virtual ScriptVarType GetAtType(int nIdx) = 0;
708 //! Sets the value of a member variable at the specified index this means that you will use the object as vector into the script.
709 virtual void SetAtAny(int nIndex, const ScriptAnyValue& any) = 0;
711 //! Gets the value of a member variable at the specified index.
712 virtual bool GetAtAny(int nIndex, ScriptAnyValue& any) = 0;
714 virtual IScriptTable::Iterator BeginIteration(bool resolvePrototypeTableAsWell = false) = 0;
715 virtual bool MoveNext(Iterator& iter) = 0;
716 virtual void EndIteration(const Iterator& iter) = 0;
718 //! Clears the table,removes all the entries in the table.
719 virtual void Clear() = 0;
721 //! Gets the count of elements into the object.
722 virtual int Count() = 0;
724 //! Produces a copy of the src table.
725 //! \param pSrcTable Source table to clone from.
726 //! \param bDeepCopy Defines if source table is cloned recursively or not,
727 //! \note If bDeepCopy is false Only does shallow copy (no deep copy, table entries are not cloned hierarchically).
728 //! \note If bDeepCopy is true, all sub tables are also cloned recursively.
729 //! \note If bDeepCopy is true and bCopyByReference is true, the table structure is copied but the tables are left empty and the metatable is set to point at the original table.
730 virtual bool Clone(IScriptTable* pSrcTable, bool bDeepCopy = false, bool bCopyByReference = false) = 0;
732 //! Dumps all table entries to the IScriptTableDumpSink interface.
733 virtual void Dump(IScriptTableDumpSink* p) = 0;
735 //! Adds a C++ callback function to the table.
736 //! \note The function is a standard function that returns number of arguments and accept IFunctionHandler as argument.
737 //! \see IFunctionHandler
738 virtual bool AddFunction(const SUserFunctionDesc& fd) = 0;
739 // </interfuscator:shuffle>
741 //! Set value of a table member.
742 template<class T> void SetValue(const char* sKey, const T& value) { SetValueAny(sKey, value); }
744 //! Get value of a table member.
745 template<class T> bool GetValue(const char* sKey, T& value)
747 ScriptAnyValue any(value, 0);
748 return GetValueAny(sKey, any) && any.CopyTo(value);
750 bool HaveValue(const char* sKey)
752 ScriptAnyValue any;
753 GetValueAny(sKey, any);
755 switch (any.GetType())
757 case EScriptAnyType::Table:
758 if (any.GetScriptTable())
760 any.GetScriptTable()->Release();
761 any.SetScriptTable(nullptr);
763 return true;
764 case EScriptAnyType::Function:
765 if (any.GetScriptFunction())
767 gEnv->pScriptSystem->ReleaseFunc(any.GetScriptFunction());
768 any.SetScriptFunction(nullptr);
770 return true;
771 case EScriptAnyType::Nil:
772 return false;
773 default:
774 return true;
777 //! Set member value to nil.
778 void SetToNull(const char* sKey) { SetValueAny(sKey, ScriptAnyValue(EScriptAnyType::Nil)); }
780 //! Set value of a table member.
781 template<class T> void SetValueChain(const char* sKey, const T& value) { SetValueAny(sKey, value, true); }
783 //! Get value of a table member.
784 template<class T> bool GetValueChain(const char* sKey, T& value)
786 ScriptAnyValue any(value, 0);
787 return GetValueAny(sKey, any, true) && any.CopyTo(value);
789 void SetToNullChain(const char* sKey) { SetValueChain(sKey, ScriptAnyValue(EScriptAnyType::Nil)); }
791 //! Set the value of a member variable at the specified index.
792 template<class T> void SetAt(int nIndex, const T& value) { SetAtAny(nIndex, value); }
794 //! Get the value of a member variable at the specified index.
795 template<class T> bool GetAt(int nIndex, T& value)
797 ScriptAnyValue any(value, 0);
798 return GetAtAny(nIndex, any) && any.CopyTo(value);
800 bool HaveAt(int elem)
802 ScriptAnyValue any;
803 GetAtAny(elem, any);
804 return any.GetType() != EScriptAnyType::Nil;
806 //! Set the value of a member variable to nil at the specified index.
807 void SetNullAt(int nIndex) { SetAtAny(nIndex, ScriptAnyValue(EScriptAnyType::Nil)); }
809 //! Add value at next available index.
810 template<class T> void PushBack(const T& value)
812 int nNextPos = Count() + 1;
813 SetAtAny(nNextPos, value);
816 private:
817 //! Prevent using one of these as the output parameter will end up in a dangling pointer if it was set to NULL before the call.
818 //! Instead, use of GetValue<SmartScriptTable> and GetValueChain<SmartScriptTable> is encouraged.
819 //! @{
820 bool GetValue(const char* sKey, IScriptTable*& value);
821 bool GetValue(const char* sKey, const IScriptTable*& value);
822 bool GetValueChain(const char* sKey, IScriptTable*& value);
823 bool GetValueChain(const char* sKey, const IScriptTable*& value);
824 //! @}
827 //! This interface is used by the C++ function mapped to the script to retrieve the function parameters passed by the script and to return an optional result value to the script.
828 struct IFunctionHandler
830 // <interfuscator:shuffle>
831 virtual ~IFunctionHandler(){}
833 //! Returns pointer to the script system.
834 virtual IScriptSystem* GetIScriptSystem() = 0;
836 //! Gets this pointer of table which called C++ method.
837 //! This pointer is assigned to key "__this" in the table.
838 virtual void* GetThis() = 0;
840 //! Retrieves the value of the self passed when calling the table.
841 //! \note Always the 1st argument of the function.
842 virtual bool GetSelfAny(ScriptAnyValue& any) = 0;
844 //! Returns the function name of the currently called function.
845 //! \note Use this only used for error reporting.
846 virtual const char* GetFuncName() = 0;
848 //! Gets the number of parameter at specified index passed by the Lua.
849 virtual int GetParamCount() = 0;
851 //! Gets the type of the parameter at specified index passed by the Lua.
852 virtual ScriptVarType GetParamType(int nIdx) = 0;
854 //! Gets the nIdx param passed by the script.
855 //! \param nIdx 1-based index of the parameter.
856 //! \param val Reference to the C++ variable that will store the value.
857 virtual bool GetParamAny(int nIdx, ScriptAnyValue& any) = 0;
859 virtual int EndFunctionAny(const ScriptAnyValue& any) = 0;
860 virtual int EndFunctionAny(const ScriptAnyValue& any1, const ScriptAnyValue& any2) = 0;
861 virtual int EndFunctionAny(const ScriptAnyValue& any1, const ScriptAnyValue& any2, const ScriptAnyValue& any3) = 0;
862 virtual int EndFunction() = 0;
863 // </interfuscator:shuffle>
865 //! Retrieves the value of the self passed when calling the table.
866 //! \note Always the 1st argument of the function.
867 template<class T>
868 bool GetSelf(T& value)
870 ScriptAnyValue any(value, 0);
871 return GetSelfAny(any) && any.CopyTo(value);
874 //! Get the nIdx param passed by the script.
875 //! \param nIdx 1-based index of the parameter.
876 //! \param val Reference to the C++ variable that will store the value.
877 template<typename T>
878 bool GetParam(int nIdx, T& value)
880 ScriptAnyValue any(value, 0);
881 return GetParamAny(nIdx, any) && any.CopyTo(value);
884 template<class T>
885 int EndFunction(const T& value) { return EndFunctionAny(value); }
886 template<class T1, class T2>
887 int EndFunction(const T1& value1, const T2& value2) { return EndFunctionAny(value1, value2); }
888 template<class T1, class T2, class T3>
889 int EndFunction(const T1& value1, const T2& value2, const T3& value3) { return EndFunctionAny(value1, value2, value3); }
890 int EndFunctionNull() { return EndFunction(); }
892 //! Template methods to get multiple parameters.
893 template<class P1>
894 bool GetParams(P1& p1)
896 if (!GetParam(1, p1)) return false;
897 return true;
899 template<class P1, class P2>
900 bool GetParams(P1& p1, P2& p2)
902 if (!GetParam(1, p1) || !GetParam(2, p2)) return false;
903 return true;
905 template<class P1, class P2, class P3>
906 bool GetParams(P1& p1, P2& p2, P3& p3)
908 if (!GetParam(1, p1) || !GetParam(2, p2) || !GetParam(3, p3)) return false;
909 return true;
911 template<class P1, class P2, class P3, class P4>
912 bool GetParams(P1& p1, P2& p2, P3& p3, P4& p4)
914 if (!GetParam(1, p1) || !GetParam(2, p2) || !GetParam(3, p3) || !GetParam(4, p4)) return false;
915 return true;
917 template<class P1, class P2, class P3, class P4, class P5>
918 bool GetParams(P1& p1, P2& p2, P3& p3, P4& p4, P5& p5)
920 if (!GetParam(1, p1) || !GetParam(2, p2) || !GetParam(3, p3) || !GetParam(4, p4)) return false;
921 if (!GetParam(5, p5)) return false;
922 return true;
924 template<class P1, class P2, class P3, class P4, class P5, class P6>
925 bool GetParams(P1& p1, P2& p2, P3& p3, P4& p4, P5& p5, P6& p6)
927 if (!GetParam(1, p1) || !GetParam(2, p2) || !GetParam(3, p3) || !GetParam(4, p4)) return false;
928 if (!GetParam(5, p5) || !GetParam(6, p6)) return false;
929 return true;
931 template<class P1, class P2, class P3, class P4, class P5, class P6, class P7>
932 bool GetParams(P1& p1, P2& p2, P3& p3, P4& p4, P5& p5, P6& p6, P7& p7)
934 if (!GetParam(1, p1) || !GetParam(2, p2) || !GetParam(3, p3) || !GetParam(4, p4)) return false;
935 if (!GetParam(5, p5) || !GetParam(6, p6) || !GetParam(7, p7)) return false;
936 return true;
938 template<class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8>
939 bool GetParams(P1& p1, P2& p2, P3& p3, P4& p4, P5& p5, P6& p6, P7& p7, P8& p8)
941 if (!GetParam(1, p1) || !GetParam(2, p2) || !GetParam(3, p3) || !GetParam(4, p4)) return false;
942 if (!GetParam(5, p5) || !GetParam(6, p6) || !GetParam(7, p7) || !GetParam(8, p8)) return false;
943 return true;
945 template<class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class P9>
946 bool GetParams(P1& p1, P2& p2, P3& p3, P4& p4, P5& p5, P6& p6, P7& p7, P8& p8, P9& p9)
948 if (!GetParam(1, p1) || !GetParam(2, p2) || !GetParam(3, p3) || !GetParam(4, p4)) return false;
949 if (!GetParam(5, p5) || !GetParam(6, p6) || !GetParam(7, p7) || !GetParam(8, p8)) return false;
950 if (!GetParam(9, p9)) return false;
951 return true;
953 template<class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class P9, class P10>
954 bool GetParams(P1& p1, P2& p2, P3& p3, P4& p4, P5& p5, P6& p6, P7& p7, P8& p8, P9& p9, P10& p10)
956 if (!GetParam(1, p1) || !GetParam(2, p2) || !GetParam(3, p3) || !GetParam(4, p4)) return false;
957 if (!GetParam(5, p5) || !GetParam(6, p6) || !GetParam(7, p7) || !GetParam(8, p8)) return false;
958 if (!GetParam(9, p9) || !GetParam(10, p10)) return false;
959 return true;
962 //////////////////////////////////////////////////////////////////////////
963 // To be removed later (FC Compatibility).
964 //////////////////////////////////////////////////////////////////////////
966 bool GetParamUDVal(int nIdx,ULONG_PTR &nValue,int &nCookie)
968 ScriptUserData ud;
969 if (!GetParam( nIdx,ud ))
970 return false;
971 nValue = ud.nVal;
972 nCookie = ud.nCookie;
973 return true;
975 bool GetParamUDVal(int nIdx,INT_PTR &nValue,int &nCookie)
977 ScriptUserData ud;
978 if (!GetParam( nIdx,ud ))
979 return false;
980 nValue = ud.nVal;
981 nCookie = ud.nCookie;
982 return true;
987 // Under development.
988 struct ScriptDebugInfo
990 const char* sSourceName;
991 int nCurrentLine;
994 // Under development.
995 struct IScriptDebugSink
997 // <interfuscator:shuffle>
998 virtual ~IScriptDebugSink(){}
999 virtual void OnLoadSource(const char* sSourceName, unsigned char* sSource, long nSourceSize) = 0;
1000 virtual void OnExecuteLine(ScriptDebugInfo& sdiDebugInfo) = 0;
1001 // </interfuscator:shuffle>
1004 // Utility classes.
1006 //! Helper for faster Set/Gets on the table.
1007 class CScriptSetGetChain
1009 public:
1010 CScriptSetGetChain(IScriptTable* pTable)
1012 m_pTable = pTable;
1013 m_pTable->BeginSetGetChain();
1015 ~CScriptSetGetChain() { m_pTable->EndSetGetChain(); }
1017 void SetToNull(const char* sKey) { m_pTable->SetToNull(sKey); }
1018 template<class T> ILINE void SetValue(const char* sKey, const T& value) const { m_pTable->SetValueChain(sKey, value); }
1019 template<class T> ILINE bool GetValue(const char* sKey, T& value) const { return m_pTable->GetValueChain(sKey, value); }
1021 private:
1022 IScriptTable* m_pTable;
1025 #ifdef CRYSCRIPTSYSTEM_EXPORTS
1026 #define CRYSCRIPTSYSTEM_API DLL_EXPORT
1027 #else // CRYSCRIPTSYSTEM_EXPORTS
1028 #define CRYSCRIPTSYSTEM_API DLL_IMPORT
1029 #endif // CRYSCRIPTSYSTEM_EXPORTS
1031 extern "C"
1033 CRYSCRIPTSYSTEM_API IScriptSystem* CreateScriptSystem(ISystem* pSystem, bool bStdLibs);
1035 typedef IScriptSystem*(* CREATESCRIPTSYSTEM_FNCPTR)(ISystem* pSystem, bool bStdLibs);
1037 //! Helper template class.
1038 //! Handles dispatching of Lua to C script function callbacks to the specified
1039 //! member functions of the CScriptableBase.
1040 // See Also: CScriptableBase::RegisterTemplateFunction
1041 struct ScriptTemplateCallHelper
1043 template<typename Callee>
1044 static int Call(Callee* callee, int (Callee::* func)(IFunctionHandler*), IFunctionHandler* pH)
1046 return (callee->*func)(pH);
1048 template<typename Callee, typename P1>
1049 static int Call(Callee* callee, int (Callee::* func)(IFunctionHandler*, P1), IFunctionHandler* pH)
1051 P1 p1;
1052 if (!pH->GetParams(p1))
1053 return pH->EndFunction();
1054 return (callee->*func)(pH, p1);
1056 template<typename Callee, typename P1, typename P2>
1057 static int Call(Callee* callee, int (Callee::* func)(IFunctionHandler*, P1, P2), IFunctionHandler* pH)
1059 P1 p1;
1060 P2 p2;
1061 if (!pH->GetParams(p1, p2))
1062 return pH->EndFunction();
1063 return (callee->*func)(pH, p1, p2);
1065 template<typename Callee, typename P1, typename P2, typename P3>
1066 static int Call(Callee* callee, int (Callee::* func)(IFunctionHandler*, P1, P2, P3), IFunctionHandler* pH)
1068 P1 p1;
1069 P2 p2;
1070 P3 p3;
1071 if (!pH->GetParams(p1, p2, p3))
1072 return pH->EndFunction();
1073 return (callee->*func)(pH, p1, p2, p3);
1075 template<typename Callee, typename P1, typename P2, typename P3, typename P4>
1076 static int Call(Callee* callee, int (Callee::* func)(IFunctionHandler*, P1, P2, P3, P4), IFunctionHandler* pH)
1078 P1 p1;
1079 P2 p2;
1080 P3 p3;
1081 P4 p4;
1082 if (!pH->GetParams(p1, p2, p3, p4))
1083 return pH->EndFunction();
1084 return (callee->*func)(pH, p1, p2, p3, p4);
1086 template<typename Callee, typename P1, typename P2, typename P3, typename P4, typename P5>
1087 static int Call(Callee* callee, int (Callee::* func)(IFunctionHandler*, P1, P2, P3, P4, P5), IFunctionHandler* pH)
1089 P1 p1;
1090 P2 p2;
1091 P3 p3;
1092 P4 p4;
1093 P5 p5;
1094 if (!pH->GetParams(p1, p2, p3, p4, p5))
1095 return pH->EndFunction();
1096 return (callee->*func)(pH, p1, p2, p3, p4, p5);
1098 template<typename Callee, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6>
1099 static int Call(Callee* callee, int (Callee::* func)(IFunctionHandler*, P1, P2, P3, P4, P5, P6), IFunctionHandler* pH)
1101 P1 p1;
1102 P2 p2;
1103 P3 p3;
1104 P4 p4;
1105 P5 p5;
1106 P6 p6;
1107 if (!pH->GetParams(p1, p2, p3, p4, p5, p6))
1108 return pH->EndFunction();
1109 return (callee->*func)(pH, p1, p2, p3, p4, p5, p6);
1111 template<typename Callee, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7>
1112 static int Call(Callee* callee, int (Callee::* func)(IFunctionHandler*, P1, P2, P3, P4, P5, P6, P7), IFunctionHandler* pH)
1114 P1 p1;
1115 P2 p2;
1116 P3 p3;
1117 P4 p4;
1118 P5 p5;
1119 P6 p6;
1120 P7 p7;
1121 if (!pH->GetParams(p1, p2, p3, p4, p5, p6, p7))
1122 return pH->EndFunction();
1123 return (callee->*func)(pH, p1, p2, p3, p4, p5, p6, p7);
1125 template<typename Callee, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8>
1126 static int Call(Callee* callee, int (Callee::* func)(IFunctionHandler*, P1, P2, P3, P4, P5, P6, P7, P8), IFunctionHandler* pH)
1128 P1 p1;
1129 P2 p2;
1130 P3 p3;
1131 P4 p4;
1132 P5 p5;
1133 P6 p6;
1134 P7 p7;
1135 P8 p8;
1136 if (!pH->GetParams(p1, p2, p3, p4, p5, p6, p7, p8))
1137 return pH->EndFunction();
1138 return (callee->*func)(pH, p1, p2, p3, p4, p5, p6, p7, p8);
1140 template<typename Callee, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9>
1141 static int Call(Callee* callee, int (Callee::* func)(IFunctionHandler*, P1, P2, P3, P4, P5, P6, P7, P8, P9), IFunctionHandler* pH)
1143 P1 p1;
1144 P2 p2;
1145 P3 p3;
1146 P4 p4;
1147 P5 p5;
1148 P6 p6;
1149 P7 p7;
1150 P8 p8;
1151 P9 p9;
1152 if (!pH->GetParams(p1, p2, p3, p4, p5, p6, p7, p8, p9))
1153 return pH->EndFunction();
1154 return (callee->*func)(pH, p1, p2, p3, p4, p5, p6, p7, p8, p9);
1156 template<typename Callee, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9, typename P10>
1157 static int Call(Callee* callee, int (Callee::* func)(IFunctionHandler*, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10), IFunctionHandler* pH)
1159 P1 p1;
1160 P2 p2;
1161 P3 p3;
1162 P4 p4;
1163 P5 p5;
1164 P6 p6;
1165 P7 p7;
1166 P8 p8;
1167 P9 p9;
1168 P10 p10;
1169 if (!pH->GetParams(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10))
1170 return pH->EndFunction();
1171 return (callee->*func)(pH, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);
1174 template<typename Callee, typename Func>
1175 struct CallDispatcher
1177 static int Dispatch(IFunctionHandler* pH, void* pBuffer, int nSize)
1179 unsigned char* buffer = (unsigned char*)pBuffer;
1180 Callee* pCallee;
1181 Func func;
1182 LoadUnaligned(buffer, pCallee);
1183 LoadUnaligned(buffer + sizeof(Callee*), func);
1184 return ScriptTemplateCallHelper::Call(pCallee, func, pH);
1189 //! Classes that want to register functions to the script must derive from this interface.
1190 class CScriptableBase
1192 public:
1193 friend class CScriptBind_GameStatistics;
1195 virtual ~CScriptableBase() { Done(); }
1196 virtual void Init(IScriptSystem* pSS, ISystem* pSystem, int nParamIdOffset = 0)
1198 m_pSS = pSS;
1199 m_pMethodsTable = m_pSS->CreateTable();
1200 m_pMethodsTable->AddRef();
1201 m_nParamIdOffset = nParamIdOffset;
1203 void Done()
1205 if (*m_sGlobalName != 0 && m_pSS)
1206 m_pSS->SetGlobalToNull(m_sGlobalName);
1207 SAFE_RELEASE(m_pMethodsTable);
1209 virtual void GetMemoryStatistics(ICrySizer* pSizer) {}
1211 void SetGlobalName(const char* sGlobalName)
1213 assert(strlen(sGlobalName) < sizeof(m_sGlobalName));
1214 cry_strcpy(m_sGlobalName, sGlobalName);
1215 if (m_pMethodsTable)
1216 m_pSS->SetGlobalValue(sGlobalName, m_pMethodsTable);
1219 IScriptTable* GetMethodsTable() const { return m_pMethodsTable; }
1221 protected:
1222 CScriptableBase() { m_pSS = NULL; m_pMethodsTable = NULL; m_sGlobalName[0] = 0; }
1224 void RegisterFunction(const char* sFuncName, IScriptTable::FunctionFunctor function)
1226 if (m_pMethodsTable)
1228 IScriptTable::SUserFunctionDesc fd;
1229 fd.sGlobalName = m_sGlobalName;
1230 fd.sFunctionName = sFuncName;
1231 fd.pFunctor = function;
1232 fd.nParamIdOffset = m_nParamIdOffset;
1233 m_pMethodsTable->AddFunction(fd);
1236 template<typename Callee, typename Func>
1237 void RegisterTemplateFunction(const char* sFuncName, const char* sFuncParams, Callee& callee, const Func& func)
1239 typedef Callee* Callee_pointer;
1240 if (m_pMethodsTable)
1242 Callee_pointer pCalleePtr = &callee;
1243 unsigned char pBuffer[sizeof(Callee_pointer) + sizeof(func)];
1244 memcpy(pBuffer, &pCalleePtr, sizeof(Callee_pointer));
1245 memcpy(pBuffer + sizeof(Callee_pointer), &func, sizeof(func));
1247 IScriptTable::SUserFunctionDesc fd;
1248 fd.sGlobalName = m_sGlobalName;
1249 fd.sFunctionName = sFuncName;
1250 fd.sFunctionParams = sFuncParams;
1251 fd.pUserDataFunc = ScriptTemplateCallHelper::CallDispatcher<Callee, Func>::Dispatch;
1252 fd.nDataSize = sizeof(Callee_pointer) + sizeof(func);
1253 fd.pDataBuffer = pBuffer;
1254 fd.nParamIdOffset = m_nParamIdOffset;
1256 m_pMethodsTable->AddFunction(fd);
1260 protected:
1261 //////////////////////////////////////////////////////////////////////////
1262 char m_sGlobalName[64];
1263 IScriptTable* m_pMethodsTable;
1264 IScriptSystem* m_pSS;
1265 int m_nParamIdOffset;
1266 //////////////////////////////////////////////////////////////////////////
1269 #define SCRIPT_REG_CLASSNAME
1270 #define SCRIPT_REG_FUNC(func) RegisterFunction( # func, functor_ret(*this, SCRIPT_REG_CLASSNAME func));
1271 #define SCRIPT_REG_GLOBAL(var) gEnv->pScriptSystem->SetGlobalValue( # var, var);
1272 #define SCRIPT_REG_TEMPLFUNC(func, sFuncParams) RegisterTemplateFunction( # func, sFuncParams, *this, SCRIPT_REG_CLASSNAME func);
1274 #define SCRIPT_CHECK_PARAMETERS(_n) \
1275 if (pH->GetParamCount() != _n) \
1276 { CryWarning(VALIDATOR_MODULE_SCRIPTSYSTEM, VALIDATOR_WARNING, "[%s] %d arguments passed, " # _n " expected)", __FUNCTION__, pH->GetParamCount()); \
1277 return pH->EndFunction(); }
1279 #define SCRIPT_CHECK_PARAMETERS_MIN(_n) \
1280 if (pH->GetParamCount() < _n) \
1281 { CryWarning(VALIDATOR_MODULE_SCRIPTSYSTEM, VALIDATOR_WARNING, "[%s] %d arguments passed, at least " # _n " expected)", __FUNCTION__, pH->GetParamCount()); \
1282 return pH->EndFunction(); }
1284 #define SCRIPT_CHECK_PARAMETERS2(_n, _n2) \
1285 if ((pH->GetParamCount() != _n) && (pH->GetParamCount() != _n2)) \
1286 { CryWarning(VALIDATOR_MODULE_SCRIPTSYSTEM, VALIDATOR_WARNING, "[%s] %d arguments passed, " # _n " or " # _n2 " expected)", __FUNCTION__, pH->GetParamCount()); \
1287 return pH->EndFunction(); }
1289 #define SCRIPT_CHECK_PARAMETERS3(_n, _n2, _n3) \
1290 if ((pH->GetParamCount() != _n) && (pH->GetParamCount() != _n2) && (pH->GetParamCount() != _n3)) \
1291 { CryWarning(VALIDATOR_MODULE_SCRIPTSYSTEM, VALIDATOR_WARNING, "[%s] %d arguments passed, " # _n ", " # _n2 " or " # _n3 " expected)", __FUNCTION__, pH->GetParamCount()); \
1292 return pH->EndFunction(); }
1294 //! Auto Wrapper on IScriptTable interface, will destroy table when exiting scope.
1295 class SmartScriptTable
1297 public:
1298 SmartScriptTable() : p(NULL) {}
1299 SmartScriptTable(const SmartScriptTable& st)
1301 p = st.p;
1302 if (p) p->AddRef();
1304 SmartScriptTable(IScriptTable* newp)
1306 if (newp) newp->AddRef();
1307 p = newp;
1310 //! Copy operator.
1311 SmartScriptTable& operator=(IScriptTable* newp)
1313 if (newp) newp->AddRef();
1314 if (p) p->Release();
1315 p = newp;
1316 return *this;
1318 //! Copy operator.
1319 SmartScriptTable& operator=(const SmartScriptTable& st)
1321 if (st.p) st.p->AddRef();
1322 if (p) p->Release();
1323 p = st.p;
1324 return *this;
1327 explicit SmartScriptTable(IScriptSystem* pSS, bool bCreateEmpty = false)
1329 p = pSS->CreateTable(bCreateEmpty);
1330 p->AddRef();
1332 ~SmartScriptTable() { if (p) p->Release(); }
1334 // Casts
1335 IScriptTable* operator->() const { return p; }
1336 IScriptTable* operator*() const { return p; }
1337 operator const IScriptTable*() const { return p; }
1338 operator IScriptTable*() const { return p; }
1339 operator bool() const { return (p != NULL); }
1341 // Boolean comparisons.
1342 bool operator!() const { return p == NULL; }
1343 bool operator==(const IScriptTable* p2) const { return p == p2; }
1344 bool operator==(IScriptTable* p2) const { return p == p2; }
1345 bool operator!=(const IScriptTable* p2) const { return p != p2; }
1346 bool operator!=(IScriptTable* p2) const { return p != p2; }
1347 bool operator<(const IScriptTable* p2) const { return p < p2; }
1348 bool operator>(const IScriptTable* p2) const { return p > p2; }
1350 //////////////////////////////////////////////////////////////////////////
1351 IScriptTable* GetPtr() const { return p; }
1352 //////////////////////////////////////////////////////////////////////////
1354 bool Create(IScriptSystem* pSS, bool bCreateEmpty = false)
1356 SAFE_RELEASE(p);
1357 p = pSS->CreateTable(bCreateEmpty);
1358 if (p == NULL)
1359 return false;
1361 p->AddRef();
1362 return true;
1365 private:
1366 IScriptTable* p;
1369 // Smart wrapper on top of script function handle.
1370 class SmartScriptFunction
1372 public:
1373 SmartScriptFunction()
1374 : m_func(0)
1375 , m_pSS(0)
1379 SmartScriptFunction(IScriptSystem* pSS, HSCRIPTFUNCTION func)
1380 : m_func(func)
1381 , m_pSS(pSS)
1385 SmartScriptFunction(const SmartScriptFunction& other)
1386 : m_func(0)
1387 , m_pSS(0)
1389 if (other.m_func)
1391 ScriptAnyValue func(
1392 other.m_pSS->CloneAny(ScriptAnyValue((HSCRIPTFUNCTION)other.m_func)));
1393 func.CopyTo(m_func);
1394 m_pSS = other.m_pSS;
1398 ~SmartScriptFunction()
1400 if (m_func)
1401 m_pSS->ReleaseFunc(m_func);
1403 m_func = 0;
1404 m_pSS = 0;
1407 SmartScriptFunction& operator=(const SmartScriptFunction& other)
1409 SmartScriptFunction(other).swap(*this);
1411 return *this;
1414 operator HSCRIPTFUNCTION() const
1416 return m_func;
1419 HSCRIPTFUNCTION get() const
1421 return m_func;
1424 void swap(SmartScriptFunction& other)
1426 HSCRIPTFUNCTION otherFunc = other.m_func;
1427 IScriptSystem* otherSS = other.m_pSS;
1428 other.m_func = m_func;
1429 other.m_pSS = m_pSS;
1430 m_func = otherFunc;
1431 m_pSS = otherSS;
1434 void reset()
1436 SmartScriptFunction().swap(*this);
1439 void reset(IScriptSystem* pSS, HSCRIPTFUNCTION func)
1441 SmartScriptFunction(pSS, func).swap(*this);
1444 private:
1445 HSCRIPTFUNCTION m_func;
1446 IScriptSystem* m_pSS;
1449 // Description:
1450 // This class map an 3d vector to a LUA table with x,y,z members.
1451 class CScriptVector : public SmartScriptTable
1453 public:
1454 CScriptVector() {}
1455 CScriptVector(IScriptSystem* pSS, bool bCreateEmpty = false) : SmartScriptTable(pSS, bCreateEmpty) {}
1456 void Set(const Vec3& v)
1458 CScriptSetGetChain chain(*this);
1459 chain.SetValue("x", v.x);
1460 chain.SetValue("y", v.y);
1461 chain.SetValue("z", v.z);
1463 Vec3 Get()
1465 Vec3 v(0, 0, 0);
1466 CScriptSetGetChain chain(*this);
1467 chain.GetValue("x", v.x);
1468 chain.GetValue("y", v.y);
1469 chain.GetValue("z", v.z);
1470 return v;
1472 CScriptVector& operator=(const Vec3& v3) { Set(v3); return *this; }
1475 //! This class map an "color" to a LUA table with indexed 3 numbers [1],[2],[3] members.
1476 class CScriptColor : public SmartScriptTable
1478 public:
1479 CScriptColor() {}
1480 CScriptColor(IScriptSystem* pSS, bool bCreateEmpty = false) : SmartScriptTable(pSS, bCreateEmpty) {}
1481 void Set(const Vec3& v)
1483 IScriptTable* pTable = *this;
1484 pTable->SetAt(1, v.x);
1485 pTable->SetAt(2, v.y);
1486 pTable->SetAt(3, v.z);
1488 Vec3 Get()
1490 IScriptTable* pTable = *this;
1491 Vec3 v(0, 0, 0);
1492 pTable->GetAt(1, v.x);
1493 pTable->GetAt(2, v.y);
1494 pTable->GetAt(3, v.z);
1495 return v;
1497 CScriptColor& operator=(const Vec3& v3) { Set(v3); return *this; }
1500 //! Script call helper.
1501 struct Script
1503 static SmartScriptTable GetCachedTable(IFunctionHandler* pH, int funcParam)
1505 SmartScriptTable out;
1506 if (pH->GetParamCount() >= funcParam && pH->GetParamType(funcParam) == svtObject)
1507 pH->GetParam(funcParam, out);
1508 if (!out.GetPtr())
1509 out = SmartScriptTable(gEnv->pScriptSystem);
1510 return out;
1513 static SmartScriptTable SetCachedVector(const Vec3& value, IFunctionHandler* pH, int funcParam)
1515 SmartScriptTable out = GetCachedTable(pH, funcParam);
1517 CScriptSetGetChain chain(out);
1518 chain.SetValue("x", value.x);
1519 chain.SetValue("y", value.y);
1520 chain.SetValue("z", value.z);
1522 return out;
1525 static SmartScriptTable GetCachedTable(SmartScriptTable& table, const char* fieldName)
1527 SmartScriptTable out;
1529 if (table->GetValue(fieldName, out))
1530 return out;
1532 out = SmartScriptTable(gEnv->pScriptSystem);
1533 table->SetValue(fieldName, out);
1534 return out;
1537 static SmartScriptTable SetCachedVector(const Vec3& value, SmartScriptTable& table, const char* fieldName)
1539 SmartScriptTable out = GetCachedTable(table, fieldName);
1541 CScriptSetGetChain chain(out);
1542 chain.SetValue("x", value.x);
1543 chain.SetValue("y", value.y);
1544 chain.SetValue("z", value.z);
1546 return out;
1549 static SmartScriptTable GetCachedTable(CScriptSetGetChain& chain, const char* fieldName)
1551 SmartScriptTable out;
1553 if (chain.GetValue(fieldName, out))
1554 return out;
1556 out = SmartScriptTable(gEnv->pScriptSystem);
1557 chain.SetValue(fieldName, out);
1559 return out;
1562 static SmartScriptTable SetCachedVector(const Vec3& value, CScriptSetGetChain& chain, const char* fieldName)
1564 SmartScriptTable out = GetCachedTable(chain, fieldName);
1566 CScriptSetGetChain vecChain(out);
1567 vecChain.SetValue("x", value.x);
1568 vecChain.SetValue("y", value.y);
1569 vecChain.SetValue("z", value.z);
1571 return out;
1574 //////////////////////////////////////////////////////////////////////////
1575 static bool Call(IScriptSystem* pSS, HSCRIPTFUNCTION func)
1577 if (!pSS->BeginCall(func)) return false;
1578 return pSS->EndCall();
1580 //////////////////////////////////////////////////////////////////////////
1581 static bool Call(IScriptSystem* pSS, const char* funcName)
1583 if (!pSS->BeginCall(funcName)) return false;
1584 return pSS->EndCall();
1586 //////////////////////////////////////////////////////////////////////////
1587 template<class P1>
1588 static bool Call(IScriptSystem* pSS, HSCRIPTFUNCTION func, const P1& p1)
1590 if (!pSS->BeginCall(func)) return false;
1591 PushParams(pSS, p1);
1592 return pSS->EndCall();
1594 //////////////////////////////////////////////////////////////////////////
1595 template<class P1, class P2>
1596 static bool Call(IScriptSystem* pSS, HSCRIPTFUNCTION func, const P1& p1, const P2& p2)
1598 if (!pSS->BeginCall(func)) return false;
1599 PushParams(pSS, p1, p2);
1600 return pSS->EndCall();
1602 //////////////////////////////////////////////////////////////////////////
1603 template<class P1, class P2, class P3>
1604 static bool Call(IScriptSystem* pSS, HSCRIPTFUNCTION func, const P1& p1, const P2& p2, const P3& p3)
1606 if (!pSS->BeginCall(func)) return false;
1607 PushParams(pSS, p1, p2, p3);
1608 return pSS->EndCall();
1610 //////////////////////////////////////////////////////////////////////////
1611 template<class P1, class P2, class P3, class P4>
1612 static bool Call(IScriptSystem* pSS, HSCRIPTFUNCTION func, const P1& p1, const P2& p2, const P3& p3, const P4& p4)
1614 if (!pSS->BeginCall(func)) return false;
1615 PushParams(pSS, p1, p2, p3, p4);
1616 return pSS->EndCall();
1619 template<class P1, class P2, class P3, class P4, class P5>
1620 static bool Call(IScriptSystem* pSS, HSCRIPTFUNCTION func, const P1& p1, const P2& p2, const P3& p3, const P4& p4, const P5& p5)
1622 if (!pSS->BeginCall(func)) return false;
1623 PushParams(pSS, p1, p2, p3, p4, p5);
1624 return pSS->EndCall();
1627 template<class P1, class P2, class P3, class P4, class P5, class P6>
1628 static bool Call(IScriptSystem* pSS, HSCRIPTFUNCTION func, const P1& p1, const P2& p2, const P3& p3, const P4& p4, const P5& p5, const P6& p6)
1630 if (!pSS->BeginCall(func)) return false;
1631 PushParams(pSS, p1, p2, p3, p4, p5, p6);
1632 return pSS->EndCall();
1635 //! Call to table.
1636 //! \param pTable Must not be 0.
1637 static bool CallMethod(IScriptTable* pTable, const char* sMethod)
1639 MEMSTAT_CONTEXT_FMT(EMemStatContextTypes::MSC_ScriptCall, 0, "LUA call (%s)", sMethod);
1641 assert(pTable);
1642 IScriptSystem* pSS = pTable->GetScriptSystem();
1643 if (!pSS->BeginCall(pTable, sMethod)) return false;
1644 PushParams(pSS, pTable);
1645 return pSS->EndCall();
1647 //! \param pTable Must not be 0.
1648 template<class P1>
1649 static bool CallMethod(IScriptTable* pTable, const char* sMethod, const P1& p1)
1651 MEMSTAT_CONTEXT_FMT(EMemStatContextTypes::MSC_ScriptCall, 0, "LUA call (%s)", sMethod);
1653 assert(pTable);
1654 IScriptSystem* pSS = pTable->GetScriptSystem();
1655 if (!pSS->BeginCall(pTable, sMethod)) return false;
1656 PushParams(pSS, pTable, p1);
1657 return pSS->EndCall();
1659 //////////////////////////////////////////////////////////////////////////
1660 template<class P1, class P2>
1661 static bool CallMethod(IScriptTable* pTable, const char* sMethod, const P1& p1, const P2& p2)
1663 MEMSTAT_CONTEXT_FMT(EMemStatContextTypes::MSC_ScriptCall, 0, "LUA call (%s)", sMethod);
1665 IScriptSystem* pSS = pTable->GetScriptSystem();
1666 if (!pSS->BeginCall(pTable, sMethod)) return false;
1667 PushParams(pSS, pTable, p1, p2);
1668 return pSS->EndCall();
1670 //////////////////////////////////////////////////////////////////////////
1671 template<class P1, class P2, class P3>
1672 static bool CallMethod(IScriptTable* pTable, const char* sMethod, const P1& p1, const P2& p2, const P3& p3)
1674 MEMSTAT_CONTEXT_FMT(EMemStatContextTypes::MSC_ScriptCall, 0, "LUA call (%s)", sMethod);
1676 IScriptSystem* pSS = pTable->GetScriptSystem();
1677 if (!pSS->BeginCall(pTable, sMethod)) return false;
1678 PushParams(pSS, pTable, p1, p2, p3);
1679 return pSS->EndCall();
1681 //////////////////////////////////////////////////////////////////////////
1682 template<class P1, class P2, class P3, class P4>
1683 static bool CallMethod(IScriptTable* pTable, const char* sMethod, const P1& p1, const P2& p2, const P3& p3, const P4& p4)
1685 MEMSTAT_CONTEXT_FMT(EMemStatContextTypes::MSC_ScriptCall, 0, "LUA call (%s)", sMethod);
1687 IScriptSystem* pSS = pTable->GetScriptSystem();
1688 if (!pSS->BeginCall(pTable, sMethod)) return false;
1689 PushParams(pSS, pTable, p1, p2, p3, p4);
1690 return pSS->EndCall();
1692 //////////////////////////////////////////////////////////////////////////
1693 template<class P1, class P2, class P3, class P4, class P5>
1694 static bool CallMethod(IScriptTable* pTable, const char* sMethod, const P1& p1, const P2& p2, const P3& p3, const P4& p4,
1695 const P5& p5)
1697 MEMSTAT_CONTEXT_FMT(EMemStatContextTypes::MSC_ScriptCall, 0, "LUA call (%s)", sMethod);
1699 IScriptSystem* pSS = pTable->GetScriptSystem();
1700 if (!pSS->BeginCall(pTable, sMethod)) return false;
1701 PushParams(pSS, pTable, p1, p2, p3, p4, p5);
1702 return pSS->EndCall();
1705 //! Call to table.
1706 static bool CallMethod(IScriptTable* pTable, HSCRIPTFUNCTION func)
1708 IScriptSystem* pSS = pTable->GetScriptSystem();
1709 if (!pSS->BeginCall(func)) return false;
1710 PushParams(pSS, pTable);
1711 return pSS->EndCall();
1713 //////////////////////////////////////////////////////////////////////////
1714 template<class P1>
1715 static bool CallMethod(IScriptTable* pTable, HSCRIPTFUNCTION func, const P1& p1)
1717 IScriptSystem* pSS = pTable->GetScriptSystem();
1718 if (!pSS->BeginCall(func)) return false;
1719 PushParams(pSS, pTable, p1);
1720 return pSS->EndCall();
1722 //////////////////////////////////////////////////////////////////////////
1723 template<class P1, class P2>
1724 static bool CallMethod(IScriptTable* pTable, HSCRIPTFUNCTION func, const P1& p1, const P2& p2)
1726 IScriptSystem* pSS = pTable->GetScriptSystem();
1727 if (!pSS->BeginCall(func)) return false;
1728 PushParams(pSS, pTable, p1, p2);
1729 return pSS->EndCall();
1731 //////////////////////////////////////////////////////////////////////////
1732 template<class P1, class P2, class P3>
1733 static bool CallMethod(IScriptTable* pTable, HSCRIPTFUNCTION func, const P1& p1, const P2& p2, const P3& p3)
1735 IScriptSystem* pSS = pTable->GetScriptSystem();
1736 if (!pSS->BeginCall(func)) return false;
1737 PushParams(pSS, pTable, p1, p2, p3);
1738 return pSS->EndCall();
1740 //////////////////////////////////////////////////////////////////////////
1741 template<class P1, class P2, class P3, class P4>
1742 static bool CallMethod(IScriptTable* pTable, HSCRIPTFUNCTION func, const P1& p1, const P2& p2, const P3& p3, const P4& p4)
1744 IScriptSystem* pSS = pTable->GetScriptSystem();
1745 if (!pSS->BeginCall(func)) return false;
1746 PushParams(pSS, pTable, p1, p2, p3, p4);
1747 return pSS->EndCall();
1749 //////////////////////////////////////////////////////////////////////////
1750 template<class P1, class P2, class P3, class P4, class P5>
1751 static bool CallMethod(IScriptTable* pTable, HSCRIPTFUNCTION func, const P1& p1, const P2& p2, const P3& p3, const P4& p4,
1752 const P5& p5)
1754 IScriptSystem* pSS = pTable->GetScriptSystem();
1755 if (!pSS->BeginCall(func)) return false;
1756 PushParams(pSS, pTable, p1, p2, p3, p4, p5);
1757 return pSS->EndCall();
1760 //////////////////////////////////////////////////////////////////////////
1761 template<class Ret>
1762 static bool CallReturn(IScriptSystem* pSS, HSCRIPTFUNCTION func, Ret& ret)
1764 if (!pSS->BeginCall(func)) return false;
1765 return pSS->EndCall(ret);
1767 //////////////////////////////////////////////////////////////////////////
1768 template<class P1, class Ret>
1769 static bool CallReturn(IScriptSystem* pSS, HSCRIPTFUNCTION func, const P1& p1, Ret& ret)
1771 if (!pSS->BeginCall(func)) return false;
1772 PushParams(pSS, p1);
1773 return pSS->EndCall(ret);
1775 //////////////////////////////////////////////////////////////////////////
1776 template<class P1, class P2, class Ret>
1777 static bool CallReturn(IScriptSystem* pSS, HSCRIPTFUNCTION func, const P1& p1, const P2& p2, Ret& ret)
1779 if (!pSS->BeginCall(func)) return false;
1780 PushParams(pSS, p1, p2);
1781 return pSS->EndCall(ret);
1783 //////////////////////////////////////////////////////////////////////////
1784 template<class P1, class P2, class P3, class Ret>
1785 static bool CallReturn(IScriptSystem* pSS, HSCRIPTFUNCTION func, const P1& p1, const P2& p2, const P3& p3, Ret& ret)
1787 if (!pSS->BeginCall(func)) return false;
1788 PushParams(pSS, p1, p2, p3);
1789 return pSS->EndCall(ret);
1791 //////////////////////////////////////////////////////////////////////////
1792 template<class P1, class P2, class P3, class P4, class Ret>
1793 static bool CallReturn(IScriptSystem* pSS, HSCRIPTFUNCTION func, const P1& p1, const P2& p2, const P3& p3, const P4& p4, Ret& ret)
1795 if (!pSS->BeginCall(func)) return false;
1796 PushParams(pSS, p1, p2, p3, p4);
1797 return pSS->EndCall(ret);
1799 template<class P1, class P2, class P3, class P4, class P5, class Ret>
1800 static bool CallReturn(IScriptSystem* pSS, HSCRIPTFUNCTION func, const P1& p1, const P2& p2, const P3& p3, const P4& p4, const P5& p5, Ret& ret)
1802 if (!pSS->BeginCall(func)) return false;
1803 PushParams(pSS, p1, p2, p3, p4, p5);
1804 return pSS->EndCall(ret);
1807 //////////////////////////////////////////////////////////////////////////
1808 private:
1809 template<class P1>
1810 static void PushParams(IScriptSystem* pSS, const P1& p1)
1812 pSS->PushFuncParam(p1);
1814 template<class P1, class P2>
1815 static void PushParams(IScriptSystem* pSS, const P1& p1, const P2& p2)
1817 pSS->PushFuncParam(p1);
1818 pSS->PushFuncParam(p2);
1820 template<class P1, class P2, class P3>
1821 static void PushParams(IScriptSystem* pSS, const P1& p1, const P2& p2, const P3& p3)
1823 pSS->PushFuncParam(p1);
1824 pSS->PushFuncParam(p2);
1825 pSS->PushFuncParam(p3);
1827 template<class P1, class P2, class P3, class P4>
1828 static void PushParams(IScriptSystem* pSS, const P1& p1, const P2& p2, const P3& p3, const P4& p4)
1830 pSS->PushFuncParam(p1);
1831 pSS->PushFuncParam(p2);
1832 pSS->PushFuncParam(p3);
1833 pSS->PushFuncParam(p4);
1835 template<class P1, class P2, class P3, class P4, class P5>
1836 static void PushParams(IScriptSystem* pSS, const P1& p1, const P2& p2, const P3& p3, const P4& p4, const P5& p5)
1838 pSS->PushFuncParam(p1);
1839 pSS->PushFuncParam(p2);
1840 pSS->PushFuncParam(p3);
1841 pSS->PushFuncParam(p4);
1842 pSS->PushFuncParam(p5);
1844 template<class P1, class P2, class P3, class P4, class P5, class P6>
1845 static void PushParams(IScriptSystem* pSS, const P1& p1, const P2& p2, const P3& p3, const P4& p4, const P5& p5, const P6& p6)
1847 pSS->PushFuncParam(p1);
1848 pSS->PushFuncParam(p2);
1849 pSS->PushFuncParam(p3);
1850 pSS->PushFuncParam(p4);
1851 pSS->PushFuncParam(p5);
1852 pSS->PushFuncParam(p6);
1856 inline ScriptAnyValue::ScriptAnyValue(EScriptAnyType type)
1858 switch (type)
1860 case EScriptAnyType::Any:
1861 SetAny();
1862 break;
1863 case EScriptAnyType::Nil:
1864 SetNil();
1865 break;
1866 case EScriptAnyType::Boolean:
1867 m_data.emplace<bool>();
1868 break;
1869 case EScriptAnyType::Handle:
1870 m_data.emplace<ScriptHandle>();
1871 break;
1872 case EScriptAnyType::Number:
1873 m_data.emplace<float>();
1874 break;
1875 case EScriptAnyType::String:
1876 m_data.emplace<const char*>();
1877 break;
1878 case EScriptAnyType::Table:
1879 m_data.emplace<IScriptTable*>();
1880 break;
1881 case EScriptAnyType::Function:
1882 m_data.emplace<HSCRIPTFUNCTION>();
1883 break;
1884 case EScriptAnyType::UserData:
1885 m_data.emplace<ScriptUserData>();
1886 break;
1887 case EScriptAnyType::Vector:
1888 m_data.emplace<Vec3>();
1889 break;
1890 default:
1891 CRY_ASSERT(false);
1892 break;
1896 //! After SmartScriptTable defined, now implement ScriptAnyValue constructor for it.
1897 inline ScriptAnyValue::ScriptAnyValue(IScriptTable* value)
1899 if (value)
1900 value->AddRef();
1901 SetScriptTable(value);
1904 inline ScriptAnyValue::ScriptAnyValue(const SmartScriptTable& value)
1906 if (value)
1907 value->AddRef();
1908 SetScriptTable(value);
1911 inline ScriptAnyValue::ScriptAnyValue(IScriptTable* _table, int)
1913 if (_table)
1914 _table->AddRef();
1915 SetScriptTable(_table);
1918 inline ScriptAnyValue::ScriptAnyValue(const SmartScriptTable& value, int)
1920 if (value)
1921 value->AddRef();
1922 SetScriptTable(value);
1925 inline bool ScriptAnyValue::CopyTo(IScriptTable*& value) const
1927 if (GetType() == EScriptAnyType::Table)
1929 value = GetScriptTable();
1930 return true;
1932 return false;
1935 inline bool ScriptAnyValue::CopyTo(SmartScriptTable& value) const
1937 if (GetType() == EScriptAnyType::Table)
1939 value = GetScriptTable();
1940 return true;
1942 return false;
1945 inline bool ScriptAnyValue::CopyFromTableToXYZ(float& x, float& y, float& z) const
1947 if (GetType() == EScriptAnyType::Table)
1949 const char* const coords[3] = { "x", "y", "z" };
1950 float xyz[3];
1951 ScriptAnyValue anyValue;
1953 for (size_t i = 0; i < 3; ++i)
1955 if (GetScriptTable()->GetValueAny(coords[i], anyValue) && anyValue.GetType() == EScriptAnyType::Number)
1957 anyValue.CopyTo(xyz[i]);
1959 else
1961 return false;
1964 x = xyz[0];
1965 y = xyz[1];
1966 z = xyz[2];
1967 return true;
1969 return false;
1972 inline void ScriptAnyValue::Clear()
1974 if (GetType() == EScriptAnyType::Table && GetScriptTable())
1976 GetScriptTable()->Release();
1978 else if (GetType() == EScriptAnyType::Function && GetScriptFunction())
1980 gEnv->pScriptSystem->ReleaseFunc(GetScriptFunction());
1982 SetAny();
1985 inline ScriptAnyValue::~ScriptAnyValue()
1987 Clear();
1990 inline ScriptAnyValue::ScriptAnyValue(const ScriptAnyValue& rhs)
1992 switch (rhs.GetType())
1994 case EScriptAnyType::Any:
1995 break;
1996 case EScriptAnyType::Boolean:
1997 SetBool(rhs.GetBool());
1998 break;
1999 case EScriptAnyType::Function:
2000 SetScriptFunction(gEnv->pScriptSystem->AddFuncRef(rhs.GetScriptFunction()));
2001 break;
2002 case EScriptAnyType::Handle:
2003 SetScriptHandle(rhs.GetScriptHandle());
2004 break;
2005 case EScriptAnyType::Nil:
2006 SetNil();
2007 break;
2008 case EScriptAnyType::Number:
2009 SetNumber(rhs.GetNumber());
2010 break;
2011 case EScriptAnyType::String:
2012 SetString(rhs.GetString());
2013 break;
2014 case EScriptAnyType::Table:
2015 SetScriptTable(rhs.GetScriptTable());
2016 if (GetScriptTable())
2017 GetScriptTable()->AddRef();
2018 break;
2019 case EScriptAnyType::UserData:
2020 break;
2021 case EScriptAnyType::Vector:
2022 SetVector(rhs.GetVector());
2023 break;
2026 inline void ScriptAnyValue::Swap(ScriptAnyValue& value)
2028 char temp[sizeof(ScriptAnyValue)];
2029 memcpy(temp, this, sizeof(ScriptAnyValue));
2030 memcpy(this, &value, sizeof(ScriptAnyValue));
2031 memcpy(&value, temp, sizeof(ScriptAnyValue));
2034 inline ScriptAnyValue::ScriptAnyValue(HSCRIPTFUNCTION value)
2036 SetScriptFunction(gEnv->pScriptSystem->AddFuncRef(value));
2039 inline bool ScriptAnyValue::CopyTo(HSCRIPTFUNCTION& value) const
2041 if (GetType() == EScriptAnyType::Function)
2043 value = gEnv->pScriptSystem->AddFuncRef(GetScriptFunction());
2044 return true;
2047 return false;
2050 inline bool ScriptAnyValue::operator==(const ScriptAnyValue& rhs) const
2052 // Comparing memory of union is a bad idea.
2053 bool result = GetType() == rhs.GetType();
2054 if (result)
2056 switch (GetType())
2058 case EScriptAnyType::Boolean:
2059 case EScriptAnyType::Number:
2060 case EScriptAnyType::String:
2061 case EScriptAnyType::Vector:
2062 case EScriptAnyType::Handle:
2063 case EScriptAnyType::Table:
2064 case EScriptAnyType::UserData:
2065 result = (m_data == rhs.m_data);
2066 break;
2068 case EScriptAnyType::Function:
2069 result = gEnv->pScriptSystem->CompareFuncRef(GetScriptFunction(), rhs.GetScriptFunction());
2070 break;
2072 default:
2073 CRY_ASSERT(false);
2074 break;
2077 return result;
2080 //! \endcond