-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathIScriptSys.h
More file actions
573 lines (458 loc) · 18 KB
/
IScriptSys.h
File metadata and controls
573 lines (458 loc) · 18 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
#pragma once
#ifndef _X_SCRIPT_SYS_I_H_
#define _X_SCRIPT_SYS_I_H_
#include <IAsyncLoad.h>
#include <Assets\AssetBase.h>
#include <Util\Delegate.h>
#include <String\StringRange.h>
X_NAMESPACE_BEGIN(script)
static const char* SCRIPT_FILE_EXTENSION = "lua";
static const uint32_t SCRIPT_MAX_LOADED = 256;
X_DECLARE_ENUM(Moudles)
(
Global,
Core,
Script,
Sound,
Game,
Physics,
Network,
Video,
Io);
X_DECLARE_ENUM(Type)
(
Nil,
Boolean,
Pointer,
Number,
String,
Table,
Function,
Userdata,
Handle,
Vector,
None);
class SmartScriptTable;
struct IScriptTableDumpSink;
struct IScriptTableIterator;
struct IScriptTable;
struct IScriptBinds;
// the only reason this is a custom type instead of a 32bit int.
// if for type resolution in tempaltes / overloads. if we had strong types could use that.
struct ScriptFunctionHandleType
{
};
typedef ScriptFunctionHandleType* ScriptFunctionHandle;
static const ScriptFunctionHandle INVALID_HANLDE = 0;
// note this is a union not a struct
// Used for storing full range int's in lua.
union Handle
{
Handle() :
pPtr(0)
{
}
Handle(size_t i) :
id(i)
{
}
Handle(void* p) :
pPtr(p)
{
}
size_t id;
void* pPtr;
};
template<typename T>
struct ValueType
{
};
template<>
struct ValueType<bool>
{
static const Type::Enum Type = Type::Boolean;
};
template<>
struct ValueType<int32_t>
{
static const Type::Enum Type = Type::Number;
};
template<>
struct ValueType<uint32_t>
{
static const Type::Enum Type = Type::Number;
};
template<>
struct ValueType<float>
{
static const Type::Enum Type = Type::Number;
};
template<>
struct ValueType<double>
{
static const Type::Enum Type = Type::Number;
};
template<>
struct ValueType<const char*>
{
static const Type::Enum Type = Type::String;
};
template<>
struct ValueType<core::StringRange<char>>
{
static const Type::Enum Type = Type::String;
};
template<>
struct ValueType<ScriptFunctionHandle>
{
static const Type::Enum Type = Type::Function;
};
template<>
struct ValueType<Handle>
{
static const Type::Enum Type = Type::Handle;
};
template<>
struct ValueType<Vec3f>
{
static const Type::Enum Type = Type::Vector;
};
template<>
struct ValueType<IScriptTable*>
{
static const Type::Enum Type = Type::Table;
};
template<>
struct ValueType<SmartScriptTable>
{
static const Type::Enum Type = Type::Table;
};
struct ScriptValue
{
X_INLINE ScriptValue(bool value);
X_INLINE ScriptValue(int32_t value);
X_INLINE ScriptValue(uint32_t value);
X_INLINE ScriptValue(float value);
X_INLINE ScriptValue(double value);
X_INLINE ScriptValue(const char* pValue);
X_INLINE ScriptValue(core::StringRange<char>& value);
X_INLINE ScriptValue(IScriptTable* pTable_);
X_INLINE ScriptValue(ScriptFunctionHandle function);
X_INLINE ScriptValue(Handle value);
X_INLINE ScriptValue(const Vec3f& vec);
X_INLINE ScriptValue(const SmartScriptTable& value);
X_INLINE ScriptValue(Type::Enum type);
X_INLINE ScriptValue();
X_INLINE ~ScriptValue();
X_INLINE void clear();
X_INLINE Type::Enum getType(void) const;
X_INLINE ScriptValue& operator=(const ScriptValue& rhs);
X_INLINE bool operator==(const ScriptValue& rhs) const;
X_INLINE bool operator!=(const ScriptValue& rhs) const;
X_INLINE void swap(ScriptValue& value);
X_INLINE bool copyTo(bool& value) const;
X_INLINE bool copyTo(int32_t& value) const;
X_INLINE bool copyTo(uint32_t& value) const;
X_INLINE bool copyTo(float& value) const;
X_INLINE bool copyTo(const char*& value) const;
X_INLINE bool copyTo(char*& value) const;
X_INLINE bool copyTo(core::StringRange<char>& value) const;
X_INLINE bool copyTo(Handle& value) const;
X_INLINE bool copyTo(ScriptFunctionHandle& value) const;
X_INLINE bool copyTo(Vec3f& value) const;
X_INLINE bool copyTo(IScriptTable*& value) const;
X_INLINE bool copyTo(SmartScriptTable& value) const;
public:
Type::Enum type_;
union
{
bool bool_;
double number_;
const void* pPtr_;
IScriptTable* pTable_;
ScriptFunctionHandle pFunction_;
// const char* pStr_;
struct
{
const char* pStr;
int32_t len;
} str_;
struct
{
float x, y, z;
} vec3_;
struct
{
void* pPtr;
int32_t ref;
} ud_;
};
};
X_ENSURE_SIZE(ScriptValue, 24);
struct IScript
{
virtual ~IScript() = default;
};
struct IScriptSys : public core::IEngineSysBase
, public core::IAssetLoader
{
using core::IAssetLoader::waitForLoad;
virtual ~IScriptSys() = default;
virtual bool asyncInitFinalize(void) X_ABSTRACT;
virtual void update(const core::FrameData& frame) X_ABSTRACT;
virtual bool runScriptInSandbox(const char* pBegin, const char* pEnd) const X_ABSTRACT;
virtual bool loadBufferToTable(const char* pBegin, const char* pEnd, const char* pDesc, IScriptTable* pTable) X_ABSTRACT;
virtual IScript* findScript(core::string_view name) X_ABSTRACT;
virtual IScript* loadScript(core::string_view name) X_ABSTRACT;
virtual bool waitForLoad(IScript* pScript) X_ABSTRACT; // returns true if load succeed.
// you must release function handles.
virtual ScriptFunctionHandle getFunctionPtr(const char* pFuncName) X_ABSTRACT;
virtual ScriptFunctionHandle getFunctionPtr(const char* pTableName, const char* pFuncName) X_ABSTRACT;
virtual bool compareFuncRef(ScriptFunctionHandle f1, ScriptFunctionHandle f2) X_ABSTRACT;
virtual void releaseFunc(ScriptFunctionHandle f) X_ABSTRACT;
virtual IScriptTable* createTable(bool empty) X_ABSTRACT;
virtual IScriptBinds* createScriptBind(void) X_ABSTRACT;
// set values.
virtual void setGlobalValue(const char* pKey, const ScriptValue& any) X_ABSTRACT;
virtual bool getGlobalValue(const char* pKey, ScriptValue& value) X_ABSTRACT;
template<class T>
X_INLINE void setGlobalValue(const char* pKey, const T& value);
X_INLINE void setGlobalToNull(const char* pKey);
// Get Global value.
template<class T>
X_INLINE bool getGlobalValue(const char* pKey, T& value);
// Call api
//
// beginCall(...);
// pushFuncArg("meow");
// pushFuncArg(2);
// endCall();
virtual bool call(ScriptFunctionHandle f) X_ABSTRACT;
virtual bool call(ScriptFunctionHandle f, const ScriptValue& value) X_ABSTRACT;
virtual bool beginCall(ScriptFunctionHandle f) X_ABSTRACT;
virtual bool beginCall(const char* pFunName) X_ABSTRACT;
virtual bool beginCall(const char* pTableName, const char* pFunName) X_ABSTRACT;
virtual bool beginCall(IScriptTable* pTable, const char* pFunName) X_ABSTRACT;
virtual void pushCallArg(const ScriptValue& any) X_ABSTRACT;
virtual bool endCall(void) X_ABSTRACT;
virtual bool endCall(ScriptValue& value) X_ABSTRACT;
virtual IScriptTable* createUserData(void* ptr, size_t size) X_ABSTRACT;
virtual void onScriptError(const char* fmt, ...) X_ABSTRACT;
virtual void logCallStack(void) X_ABSTRACT;
};
struct IFunctionHandler
{
virtual ~IFunctionHandler() = default;
virtual IScriptSys* getIScriptSystem(void) X_ABSTRACT;
virtual void* getThis(void) X_ABSTRACT;
virtual const char* getFuncName(void) X_ABSTRACT;
virtual int32_t getParamCount(void) X_ABSTRACT;
virtual Type::Enum getParamType(int32_t idx) X_ABSTRACT;
virtual bool getSelfAny(ScriptValue& any) X_ABSTRACT;
virtual bool getParamAny(int32_t idx, ScriptValue& any) X_ABSTRACT;
virtual int32_t endFunctionAny(const ScriptValue& any) X_ABSTRACT;
virtual int32_t endFunctionAny(const ScriptValue& any1, const ScriptValue& any2) X_ABSTRACT;
virtual int32_t endFunctionAny(const ScriptValue& any1, const ScriptValue& any2, const ScriptValue& any3) X_ABSTRACT;
template<class T>
X_INLINE bool getSelf(T& value);
template<typename T>
X_INLINE bool getParam(int32_t idx, T& value);
template<typename T>
X_INLINE bool getParam(T& value);
template<typename T, typename T2>
X_INLINE bool getParam(T& value1, T2& value2);
template<typename T, typename T2, typename T3>
X_INLINE bool getParam(T& value1, T2& value2, T3& value3);
template<typename T, typename T2, typename T3, typename T4>
X_INLINE bool getParam(T& value1, T2& value2, T3& value3, T4& value4);
X_INLINE int32_t endFunction(void) const;
X_INLINE int32_t endFunctionNull(void) const;
template<class T>
X_INLINE int endFunction(const T& value);
template<class T1, class T2>
X_INLINE int endFunction(const T1& value1, const T2& value2);
template<class T1, class T2, class T3>
X_INLINE int endFunction(const T1& value1, const T2& value2, const T3& value3);
};
struct IScriptTableDumpSink
{
virtual ~IScriptTableDumpSink() = default;
virtual void onElementFound(const char* pName, Type::Enum type) X_ABSTRACT;
virtual void onElementFound(int idx, Type::Enum type) X_ABSTRACT;
};
struct ScriptFunctionDesc
{
typedef core::Delegate<int(IFunctionHandler*)> ScriptFunction;
typedef core::traits::Function<int(IFunctionHandler* pH, void* pBuffer, int32_t size)> UserDataFunction;
X_INLINE ScriptFunctionDesc();
const char* pFunctionName; // Name of function.
const char* pFunctionParams; // List of parameters (ex "nSlot,vDirection" ).
const char* pGlobalName; // Name of global table (ex "Core")
ScriptFunction function; // Pointer to simple function.
int paramIdOffset; // Offset of the parameter to accept as 1st function argument.
int userDataSize;
void* pDataBuffer;
UserDataFunction::Pointer pUserDataFunc;
};
struct IScriptTable
{
typedef ScriptFunctionDesc::ScriptFunction ScriptFunction;
typedef ScriptFunctionDesc::UserDataFunction UserDataFunction;
struct Iterator
{
ScriptValue value;
ScriptValue key;
int internal;
};
public:
virtual ~IScriptTable() = default;
virtual IScriptSys* getIScriptSystem(void) const X_ABSTRACT;
virtual void addRef(void) X_ABSTRACT;
virtual void release(void) X_ABSTRACT;
virtual void* getUserData(void) X_ABSTRACT;
virtual void setValueAny(const char* pKey, const ScriptValue& any, bool bChain = false) X_ABSTRACT;
virtual bool getValueAny(const char* pKey, ScriptValue& any, bool bChain = false) X_ABSTRACT;
virtual void setValueAny(int32_t idx, const ScriptValue& any) X_ABSTRACT;
virtual bool getValueAny(int32_t idx, ScriptValue& any) X_ABSTRACT;
virtual Type::Enum getValueType(const char* pKey) X_ABSTRACT;
virtual Type::Enum getValueType(int32_t idx) X_ABSTRACT;
virtual bool beginChain(void) X_ABSTRACT;
virtual void endChain(void) X_ABSTRACT;
virtual void clear(void) X_ABSTRACT; // clears the table, removes all the entries in the table.
virtual size_t count(void) X_ABSTRACT; // gets the count of elements into the object.
virtual void* getThis(void) X_ABSTRACT;
virtual void setMetatable(IScriptTable* pMetatable) X_ABSTRACT; // Assign a metatable to a table.
// member iteration.
virtual IScriptTable::Iterator begin(void) X_ABSTRACT;
virtual bool next(Iterator& iter) X_ABSTRACT;
virtual void end(const Iterator& iter) X_ABSTRACT;
// Description:
// Produces a copy of the src table.
// Arguments
// bDeepCopy - Defines if source table is cloned recursively or not,
// if bDeepCopy is false Only does shallow copy (no deep copy, table entries are not cloned hierarchically).
// If bDeepCopy is true, all sub tables are also cloned recursively.
// 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.
virtual bool clone(IScriptTable* pSrcTable, bool bDeepCopy = false, bool bCopyByReference = false) X_ABSTRACT;
virtual void dump(IScriptTableDumpSink* pSink) X_ABSTRACT;
virtual bool addFunction(const ScriptFunctionDesc& fd) X_ABSTRACT;
// -------------- helpers --------------
// push to next available index.
template<class T>
X_INLINE void pushBack(const T& value);
template<class T>
X_INLINE void setValue(const char* pKey, const T& value);
template<class T>
X_INLINE void setValue(int idx, const T& value);
template<class T>
X_INLINE void setValueChain(const char* pKey, const T& value);
// Gets value of a table member.
template<class T>
X_INLINE bool getValue(const char* pKey, T& value);
template<class T>
X_INLINE bool getValue(int idx, T& value);
template<class T>
X_INLINE bool getValueChain(const char* pKey, T& value);
X_INLINE bool haveValue(const char* pKey);
X_INLINE bool haveValue(int idx);
X_INLINE void setToNull(const char* pKey);
X_INLINE void setToNull(int idx);
X_INLINE void setToNullChain(const char* pKey);
};
struct IScriptBinds
{
typedef IScriptTable::ScriptFunction ScriptFunction;
virtual ~IScriptBinds() = default;
virtual void setGlobalName(const char* pGlobalName) X_ABSTRACT;
virtual void setParamOffset(int paramIdOffset) X_ABSTRACT;
virtual IScriptTable* getMethodsTable(void) X_ABSTRACT;
virtual void registerFunction(const char* pFuncName, const IScriptTable::ScriptFunction& function) X_ABSTRACT;
};
struct IScriptBindsBase
{
public:
X_INLINE IScriptBindsBase(IScriptSys* pScriptSys);
X_INLINE IScriptTable* getMethodsTable(void);
X_INLINE void createBindTable(void);
X_INLINE void setGlobalName(const char* pGlobalName);
protected:
IScriptSys* pScriptSys_;
IScriptBinds* pBindTable_;
};
#define X_SCRIPT_BIND(classname, func) \
\
{ \
script::IScriptBinds::ScriptFunction Delegate; \
Delegate.Bind<classname, &classname::func>(this); \
pBindTable_->registerFunction(#func, Delegate); \
}
#define SCRIPT_CHECK_PARAMETERS(_n) \
\
if (pH->getParamCount() != _n) \
\
{ \
pH->getIScriptSystem()->onScriptError("[%s] %d arguments passed, " #_n " expected)", __FUNCTION__, pH->getParamCount()); \
return pH->endFunction(); \
}
#define SCRIPT_CHECK_PARAMETERS_MIN(_n) \
\
if (pH->getParamCount() < _n) \
\
{ \
pH->getIScriptSystem()->onScriptError("[%s] %d arguments passed, at least " #_n " expected)", __FUNCTION__, pH->getParamCount()); \
return pH->endFunction(); \
}
// ===========================================================
class SmartScriptTable
{
public:
X_INLINE SmartScriptTable();
X_INLINE SmartScriptTable(const SmartScriptTable& st);
X_INLINE SmartScriptTable(SmartScriptTable&& st);
X_INLINE SmartScriptTable(IScriptTable* pNew);
X_INLINE explicit SmartScriptTable(IScriptSys* pSS, bool createEmpty);
X_INLINE ~SmartScriptTable();
X_INLINE SmartScriptTable& operator=(IScriptTable* pNew);
X_INLINE SmartScriptTable& operator=(const SmartScriptTable& st);
X_INLINE SmartScriptTable& operator=(SmartScriptTable&& st);
// Casts
X_INLINE IScriptTable* operator->() const;
X_INLINE IScriptTable* operator*() const;
X_INLINE operator const IScriptTable*() const;
X_INLINE operator IScriptTable*() const;
X_INLINE operator bool() const;
// Boolean comparisons.
X_INLINE bool operator!() const;
X_INLINE bool operator==(const IScriptTable* p2) const;
X_INLINE bool operator==(IScriptTable* p2) const;
X_INLINE bool operator!=(const IScriptTable* p2) const;
X_INLINE bool operator!=(IScriptTable* p2) const;
X_INLINE bool operator<(const IScriptTable* p2) const;
X_INLINE bool operator>(const IScriptTable* p2) const;
X_INLINE IScriptTable* getPtr(void) const;
X_INLINE bool create(IScriptSys* pSS, bool createEmpty);
private:
IScriptTable* pTable_;
};
class SmartScriptFunction
{
X_NO_COPY(SmartScriptFunction);
X_NO_ASSIGN(SmartScriptFunction);
public:
X_INLINE SmartScriptFunction();
X_INLINE SmartScriptFunction(IScriptSys* pSS, ScriptFunctionHandle func);
X_INLINE SmartScriptFunction(SmartScriptFunction&& other);
X_INLINE ~SmartScriptFunction();
X_INLINE SmartScriptFunction& operator=(SmartScriptFunction&& other);
X_INLINE operator ScriptFunctionHandle() const;
X_INLINE ScriptFunctionHandle get(void) const;
X_INLINE void swap(SmartScriptFunction& other);
X_INLINE void reset(void);
X_INLINE void reset(IScriptSys* pSS, ScriptFunctionHandle func);
private:
ScriptFunctionHandle func_;
IScriptSys* pSS_;
};
X_NAMESPACE_END
#include "IScriptSys.inl"
#endif // _X_SCRIPT_SYS_I_H_