1 // Copyright 2001-2018 Crytek GmbH / Crytek Group. All rights reserved.
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>
14 class SmartScriptTable
;
16 struct IFunctionHandler
;
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.
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
); }
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
;
77 ////////////////////////////////////////////////////////////////////////////
91 enum class EScriptAnyType
105 struct ScriptAnyValue
107 ~ScriptAnyValue(); // Implemented at the end of header.
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
);
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.
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
178 case EScriptAnyType::Any
:
180 case EScriptAnyType::Nil
:
182 case EScriptAnyType::Boolean
:
184 case EScriptAnyType::Handle
:
186 case EScriptAnyType::Number
:
188 case EScriptAnyType::String
:
190 case EScriptAnyType::Table
:
192 case EScriptAnyType::Function
:
194 case EScriptAnyType::UserData
:
196 case EScriptAnyType::Vector
:
203 void GetMemoryUsage(ICrySizer
* pSizer
) const {}
205 EScriptAnyType
GetType() const
207 return static_cast<EScriptAnyType
>(m_data
.index());;
212 m_data
.emplace
<static_cast<size_t>(EScriptAnyType::Any
)>(nullptr);
217 m_data
.emplace
<static_cast<size_t>(EScriptAnyType::Nil
)>(nullptr);
222 CRY_ASSERT(GetType() == EScriptAnyType::Boolean
&& stl::holds_alternative
<bool>(m_data
));
223 return stl::get
<bool>(m_data
);
225 void SetBool(bool 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
)
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
)
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
)
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
)
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
)
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
)
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
)
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'.
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.
412 //! m_ScriptSystem->BeginCall("Player","OnInit");.
413 //! m_ScriptSystem->PushParam(pObj);.
414 //! m_ScriptSystem->PushParam(nTime);.
415 //! m_ScriptSystem->EndCall();.
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()
441 virtual HSCRIPTFUNCTION
GetFunctionPtr(const char* sFuncName
) = 0;
442 virtual HSCRIPTFUNCTION
GetFunctionPtr(const char* sTableName
, const char* sFuncName
) = 0;
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.
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.
497 //! Description="function bau()",.
499 //! Sourcefile="/scripts/bla/bla/bla.lua".
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;
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>
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
572 CCheckScriptStack(IScriptSystem
* pSS
, const char* file
, int line
)
575 m_stackSize
= pSS
->GetStackSize();
583 int stackSize
= m_pSS
->GetStackSize();
584 assert(stackSize
== m_stackSize
);
589 IScriptSystem
* m_pSS
;
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>
612 // Interface to the iterator of values in script table.
614 // This is reference counted interface, when last reference to this interface
615 // is release, object is deleted.
616 // Used together with smart_ptr.
619 //////////////////////////////////////////////////////////////////////////
620 struct IScriptTableIterator
622 // <interfuscator:shuffle>
623 virtual ~IScriptTableIterator(){}
624 virtual void AddRef();
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 ////////////////////////////////////////////////////////////////////////////
637 typedef Functor1wRet
<IFunctionHandler
*, int> FunctionFunctor
;
638 typedef int (* UserDataFunction
)(IFunctionHandler
* pH
, void* pBuffer
, int nSize
);
640 //! Iteration over table parameters.
643 const char* sKey
; // This is now redundant.
644 int nKey
; // This is now redundant.
645 ScriptAnyValue value
;
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).
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
)
753 GetValueAny(sKey
, any
);
755 switch (any
.GetType())
757 case EScriptAnyType::Table
:
758 if (any
.GetScriptTable())
760 any
.GetScriptTable()->Release();
761 any
.SetScriptTable(nullptr);
764 case EScriptAnyType::Function
:
765 if (any
.GetScriptFunction())
767 gEnv
->pScriptSystem
->ReleaseFunc(any
.GetScriptFunction());
768 any
.SetScriptFunction(nullptr);
771 case EScriptAnyType::Nil
:
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
)
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
);
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.
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
);
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.
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.
878 bool GetParam(int nIdx
, T
& value
)
880 ScriptAnyValue
any(value
, 0);
881 return GetParamAny(nIdx
, any
) && any
.CopyTo(value
);
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.
894 bool GetParams(P1
& p1
)
896 if (!GetParam(1, p1
)) return false;
899 template<class P1
, class P2
>
900 bool GetParams(P1
& p1
, P2
& p2
)
902 if (!GetParam(1, p1
) || !GetParam(2, p2
)) return false;
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;
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;
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;
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;
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;
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;
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;
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;
962 //////////////////////////////////////////////////////////////////////////
963 // To be removed later (FC Compatibility).
964 //////////////////////////////////////////////////////////////////////////
966 bool GetParamUDVal(int nIdx,ULONG_PTR &nValue,int &nCookie)
969 if (!GetParam( nIdx,ud ))
972 nCookie = ud.nCookie;
975 bool GetParamUDVal(int nIdx,INT_PTR &nValue,int &nCookie)
978 if (!GetParam( nIdx,ud ))
981 nCookie = ud.nCookie;
987 // Under development.
988 struct ScriptDebugInfo
990 const char* sSourceName
;
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>
1006 //! Helper for faster Set/Gets on the table.
1007 class CScriptSetGetChain
1010 CScriptSetGetChain(IScriptTable
* 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
); }
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
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
)
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
)
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
)
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
)
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
)
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
)
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
)
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
)
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
)
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
)
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
;
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
1193 friend class CScriptBind_GameStatistics
;
1195 virtual ~CScriptableBase() { Done(); }
1196 virtual void Init(IScriptSystem
* pSS
, ISystem
* pSystem
, int nParamIdOffset
= 0)
1199 m_pMethodsTable
= m_pSS
->CreateTable();
1200 m_pMethodsTable
->AddRef();
1201 m_nParamIdOffset
= nParamIdOffset
;
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
; }
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
);
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
1298 SmartScriptTable() : p(NULL
) {}
1299 SmartScriptTable(const SmartScriptTable
& st
)
1304 SmartScriptTable(IScriptTable
* newp
)
1306 if (newp
) newp
->AddRef();
1311 SmartScriptTable
& operator=(IScriptTable
* newp
)
1313 if (newp
) newp
->AddRef();
1314 if (p
) p
->Release();
1319 SmartScriptTable
& operator=(const SmartScriptTable
& st
)
1321 if (st
.p
) st
.p
->AddRef();
1322 if (p
) p
->Release();
1327 explicit SmartScriptTable(IScriptSystem
* pSS
, bool bCreateEmpty
= false)
1329 p
= pSS
->CreateTable(bCreateEmpty
);
1332 ~SmartScriptTable() { if (p
) p
->Release(); }
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)
1357 p
= pSS
->CreateTable(bCreateEmpty
);
1369 // Smart wrapper on top of script function handle.
1370 class SmartScriptFunction
1373 SmartScriptFunction()
1379 SmartScriptFunction(IScriptSystem
* pSS
, HSCRIPTFUNCTION func
)
1385 SmartScriptFunction(const SmartScriptFunction
& other
)
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()
1401 m_pSS
->ReleaseFunc(m_func
);
1407 SmartScriptFunction
& operator=(const SmartScriptFunction
& other
)
1409 SmartScriptFunction(other
).swap(*this);
1414 operator HSCRIPTFUNCTION() const
1419 HSCRIPTFUNCTION
get() const
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
;
1436 SmartScriptFunction().swap(*this);
1439 void reset(IScriptSystem
* pSS
, HSCRIPTFUNCTION func
)
1441 SmartScriptFunction(pSS
, func
).swap(*this);
1445 HSCRIPTFUNCTION m_func
;
1446 IScriptSystem
* m_pSS
;
1450 // This class map an 3d vector to a LUA table with x,y,z members.
1451 class CScriptVector
: public SmartScriptTable
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
);
1466 CScriptSetGetChain
chain(*this);
1467 chain
.GetValue("x", v
.x
);
1468 chain
.GetValue("y", v
.y
);
1469 chain
.GetValue("z", v
.z
);
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
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
);
1490 IScriptTable
* pTable
= *this;
1492 pTable
->GetAt(1, v
.x
);
1493 pTable
->GetAt(2, v
.y
);
1494 pTable
->GetAt(3, v
.z
);
1497 CScriptColor
& operator=(const Vec3
& v3
) { Set(v3
); return *this; }
1500 //! Script call helper.
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
);
1509 out
= SmartScriptTable(gEnv
->pScriptSystem
);
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
);
1525 static SmartScriptTable
GetCachedTable(SmartScriptTable
& table
, const char* fieldName
)
1527 SmartScriptTable out
;
1529 if (table
->GetValue(fieldName
, out
))
1532 out
= SmartScriptTable(gEnv
->pScriptSystem
);
1533 table
->SetValue(fieldName
, 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
);
1549 static SmartScriptTable
GetCachedTable(CScriptSetGetChain
& chain
, const char* fieldName
)
1551 SmartScriptTable out
;
1553 if (chain
.GetValue(fieldName
, out
))
1556 out
= SmartScriptTable(gEnv
->pScriptSystem
);
1557 chain
.SetValue(fieldName
, 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
);
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 //////////////////////////////////////////////////////////////////////////
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();
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
);
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.
1649 static bool CallMethod(IScriptTable
* pTable
, const char* sMethod
, const P1
& p1
)
1651 MEMSTAT_CONTEXT_FMT(EMemStatContextTypes::MSC_ScriptCall
, 0, "LUA call (%s)", sMethod
);
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
,
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();
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 //////////////////////////////////////////////////////////////////////////
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
,
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 //////////////////////////////////////////////////////////////////////////
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 //////////////////////////////////////////////////////////////////////////
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
)
1860 case EScriptAnyType::Any
:
1863 case EScriptAnyType::Nil
:
1866 case EScriptAnyType::Boolean
:
1867 m_data
.emplace
<bool>();
1869 case EScriptAnyType::Handle
:
1870 m_data
.emplace
<ScriptHandle
>();
1872 case EScriptAnyType::Number
:
1873 m_data
.emplace
<float>();
1875 case EScriptAnyType::String
:
1876 m_data
.emplace
<const char*>();
1878 case EScriptAnyType::Table
:
1879 m_data
.emplace
<IScriptTable
*>();
1881 case EScriptAnyType::Function
:
1882 m_data
.emplace
<HSCRIPTFUNCTION
>();
1884 case EScriptAnyType::UserData
:
1885 m_data
.emplace
<ScriptUserData
>();
1887 case EScriptAnyType::Vector
:
1888 m_data
.emplace
<Vec3
>();
1896 //! After SmartScriptTable defined, now implement ScriptAnyValue constructor for it.
1897 inline ScriptAnyValue::ScriptAnyValue(IScriptTable
* value
)
1901 SetScriptTable(value
);
1904 inline ScriptAnyValue::ScriptAnyValue(const SmartScriptTable
& value
)
1908 SetScriptTable(value
);
1911 inline ScriptAnyValue::ScriptAnyValue(IScriptTable
* _table
, int)
1915 SetScriptTable(_table
);
1918 inline ScriptAnyValue::ScriptAnyValue(const SmartScriptTable
& value
, int)
1922 SetScriptTable(value
);
1925 inline bool ScriptAnyValue::CopyTo(IScriptTable
*& value
) const
1927 if (GetType() == EScriptAnyType::Table
)
1929 value
= GetScriptTable();
1935 inline bool ScriptAnyValue::CopyTo(SmartScriptTable
& value
) const
1937 if (GetType() == EScriptAnyType::Table
)
1939 value
= GetScriptTable();
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" };
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
]);
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());
1985 inline ScriptAnyValue::~ScriptAnyValue()
1990 inline ScriptAnyValue::ScriptAnyValue(const ScriptAnyValue
& rhs
)
1992 switch (rhs
.GetType())
1994 case EScriptAnyType::Any
:
1996 case EScriptAnyType::Boolean
:
1997 SetBool(rhs
.GetBool());
1999 case EScriptAnyType::Function
:
2000 SetScriptFunction(gEnv
->pScriptSystem
->AddFuncRef(rhs
.GetScriptFunction()));
2002 case EScriptAnyType::Handle
:
2003 SetScriptHandle(rhs
.GetScriptHandle());
2005 case EScriptAnyType::Nil
:
2008 case EScriptAnyType::Number
:
2009 SetNumber(rhs
.GetNumber());
2011 case EScriptAnyType::String
:
2012 SetString(rhs
.GetString());
2014 case EScriptAnyType::Table
:
2015 SetScriptTable(rhs
.GetScriptTable());
2016 if (GetScriptTable())
2017 GetScriptTable()->AddRef();
2019 case EScriptAnyType::UserData
:
2021 case EScriptAnyType::Vector
:
2022 SetVector(rhs
.GetVector());
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());
2050 inline bool ScriptAnyValue::operator==(const ScriptAnyValue
& rhs
) const
2052 // Comparing memory of union is a bad idea.
2053 bool result
= GetType() == rhs
.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
);
2068 case EScriptAnyType::Function
:
2069 result
= gEnv
->pScriptSystem
->CompareFuncRef(GetScriptFunction(), rhs
.GetScriptFunction());