Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

804 lines
28 KiB

  1. // testSqPlus.cpp
  2. // Created by John Schultz 9/5/2005
  3. // Free for any use.
  4. #include <stdarg.h>
  5. #include <stdio.h>
  6. #include "sqplus.h"
  7. using namespace SqPlus;
  8. struct CTestObj {
  9. float x;
  10. float y;
  11. float z;
  12. CTestObj() {
  13. x = y = z = 0.f;
  14. }
  15. void update(float t) {
  16. x += t;
  17. } // update
  18. void print(void) {
  19. SQChar buff[256];
  20. scsprintf(buff,_T("x: %f\n"),x);
  21. // OutputDebugString(buff);
  22. SCPUTS(buff);
  23. } // print
  24. };
  25. _DECL_CLASS(TestObj);
  26. _IMPL_NATIVE_CONSTRUCTION(TestObj,CTestObj);
  27. _MEMBER_FUNCTION_IMPL(TestObj,constructor) {
  28. CTestObj * newv = NULL;
  29. StackHandler sa(v);
  30. int nparams = sa.GetParamCount();
  31. newv = new CTestObj();
  32. return construct_TestObj(newv);
  33. }
  34. _MEMBER_FUNCTION_IMPL(TestObj,_set) {
  35. StackHandler sa(v);
  36. _CHECK_SELF(CTestObj,TestObj);
  37. const SQChar *s = sa.GetString(2);
  38. int index = s?s[0]:sa.GetInt(2);
  39. switch(index) {
  40. case 0: case 'x': case 'r':
  41. return sa.Return(self->x = sa.GetFloat(3));
  42. break;
  43. case 1: case 'y': case 'g':
  44. return sa.Return(self->y = sa.GetFloat(3));
  45. break;
  46. case 2: case 'z': case 'b':
  47. return sa.Return(self->z = sa.GetFloat(3));
  48. break;
  49. } // switch
  50. return SQ_ERROR;
  51. }
  52. _MEMBER_FUNCTION_IMPL(TestObj,_get) {
  53. StackHandler sa(v);
  54. _CHECK_SELF(CTestObj,TestObj);
  55. const SQChar *s = sa.GetString(2);
  56. if(s && (s[1] != 0)) return SQ_ERROR;
  57. int index = s && (s[1] == 0)?s[0]:sa.GetInt(2);
  58. switch(index) {
  59. case 0: case 'x': case 'r': return sa.Return(self->x); break;
  60. case 1: case 'y': case 'g': return sa.Return(self->y); break;
  61. case 2: case 'z': case 'b': return sa.Return(self->z); break;
  62. } // switch
  63. return SQ_ERROR;
  64. }
  65. _MEMBER_FUNCTION_IMPL(TestObj,update) {
  66. StackHandler sa(v);
  67. _CHECK_SELF(CTestObj,TestObj);
  68. SQObjectType type = (SQObjectType)sa.GetType(2);
  69. if (type == OT_FLOAT || type == OT_INTEGER) {
  70. float t = sa.GetFloat(2);
  71. self->update(t);
  72. } else {
  73. SQChar buff[256];
  74. scsprintf(buff,_T("Invalid type for CTestObj::update(float): type %d\n"),type);
  75. // OutputDebugString(buff);
  76. SCPUTS(buff);
  77. } // if
  78. return SQ_OK;;
  79. }
  80. _MEMBER_FUNCTION_IMPL(TestObj,print) {
  81. StackHandler sa(v);
  82. _CHECK_SELF(CTestObj,TestObj);
  83. SQChar buff[256];
  84. scsprintf(buff,_T("x: %f y: %f z: %f\n"),self->x,self->y,self->z);
  85. // OutputDebugString(buff);
  86. SCPUTS(buff);
  87. // return sa.ThrowError(_SC("Error initializing the device"));
  88. return SQ_OK;;
  89. }
  90. _MEMBER_FUNCTION_IMPL(TestObj,_print) {
  91. _CHECK_SELF(CTestObj,TestObj);
  92. SCPUTS(_T("_print: "));
  93. return __TestObj_print(v);
  94. }
  95. _BEGIN_CLASS(TestObj)
  96. _MEMBER_FUNCTION(TestObj,constructor,1,_T("x")) // x = instance ('self/this' not yet created), no arguments.
  97. _MEMBER_FUNCTION(TestObj,_set,3,_T("xs|n")) // x = instance, string, or int/float, as .x, .y, .z, or [0], [1], [2].
  98. _MEMBER_FUNCTION(TestObj,_get,2,_T("xs|n")) // x = instance, string, or int/float, as .x, .y, .z, or [0], [1], [2].
  99. _MEMBER_FUNCTION(TestObj,update,2,_T("xn")) // x = instance (this), n = int or float.
  100. _MEMBER_FUNCTION(TestObj,print,1,_T("x")) // x = instance (this).
  101. _MEMBER_FUNCTION(TestObj,_print,1,_T("x")) // x = instance (this).
  102. _END_CLASS(TestObj)
  103. #ifdef SQUNICODE
  104. #define scvprintf vwprintf
  105. #else
  106. #define scvprintf vprintf
  107. #endif
  108. void printfunc(HSQUIRRELVM v,const SQChar *s,...) {
  109. va_list arglist;
  110. va_start(arglist, s);
  111. scvprintf(s, arglist);
  112. va_end(arglist);
  113. }
  114. int testFunc(HSQUIRRELVM v) {
  115. StackHandler sa(v);
  116. int paramCount = sa.GetParamCount();
  117. scprintf(_T("testFunc: numParams[%d]\n"),paramCount);
  118. for (int i=1; i <= paramCount; i++) {
  119. scprintf(_T("param[%d]: "),i);
  120. switch(sa.GetType(i)) {
  121. case OT_TABLE: scprintf(_T("OT_TABLE[0x%x]\n"),sa.GetObjectHandle(i)); break;
  122. case OT_INTEGER: scprintf(_T("OT_INTEGER[%d]\n"),sa.GetInt(i)); break;
  123. case OT_FLOAT: scprintf(_T("OT_FLOAT[%f]\n"),sa.GetFloat(i)); break;
  124. case OT_STRING: scprintf(_T("OT_STRING[%s]\n"),sa.GetString(i)); break;
  125. default:
  126. scprintf(_T("TYPEID[%d]\n"),sa.GetType(i));
  127. } // switch
  128. } // for
  129. return SQ_OK;
  130. } // testFunc
  131. // === BEGIN User Pointer version ===
  132. #if 0
  133. int setVarFunc2(HSQUIRRELVM v) {
  134. StackHandler sa(v);
  135. if (sa.GetType(1) == OT_TABLE) {
  136. HSQOBJECT htable = sa.GetObjectHandle(1);
  137. SquirrelObject table(htable);
  138. const SQChar * el = sa.GetString(2);
  139. SquirrelObject upValMapPtr = table.GetValue(_T("_uvp"));
  140. SquirrelObject upValMapType = table.GetValue(_T("_uvt"));
  141. if (!upValMapType.Exists(el)) {
  142. return SQ_ERROR;
  143. } // if
  144. int vType = upValMapType.GetInt(el);
  145. switch (vType) {
  146. case TypeInfo<int>::TypeID: {
  147. int * val = (int *)upValMapPtr.GetUserPointer(el);
  148. if (val) {
  149. *val = sa.GetInt(3);
  150. return sa.Return(*val);
  151. } else {
  152. return sa.Return(-1);
  153. } // if
  154. } // case
  155. case TypeInfo<float>::TypeID: {
  156. float * val = (float *)upValMapPtr.GetUserPointer(el);
  157. if (val) {
  158. *val = sa.GetFloat(3);
  159. return sa.Return(*val);
  160. } else {
  161. return sa.Return(-1);
  162. } // if
  163. } // case
  164. case TypeInfo<bool>::TypeID: {
  165. bool * val = (bool *)upValMapPtr.GetUserPointer(el);
  166. if (val) {
  167. *val = sa.GetBool(3) ? true : false;
  168. return sa.Return(*val);
  169. } else {
  170. return sa.Return(-1);
  171. } // if
  172. } // case
  173. } // switch
  174. } // if
  175. return SQ_ERROR;
  176. } // setVarFunc2
  177. int getVarFunc2(HSQUIRRELVM v) {
  178. StackHandler sa(v);
  179. if (sa.GetType(1) == OT_TABLE) {
  180. HSQOBJECT htable = sa.GetObjectHandle(1);
  181. SquirrelObject table(htable);
  182. int type = sa.GetType(2);
  183. const SQChar * el = sa.GetString(2);
  184. SquirrelObject upValMap = table.GetValue(_T("_uvp"));
  185. SquirrelObject upValMapType = table.GetValue(_T("_uvt"));
  186. if (!upValMapType.Exists(el)) {
  187. return SQ_ERROR;
  188. } // if
  189. int vType = upValMapType.GetInt(el);
  190. switch (vType) {
  191. case TypeInfo<int>::TypeID: {
  192. int * val = (int *)upValMap.GetUserPointer(el);
  193. if (val) {
  194. return sa.Return(*val);
  195. } else {
  196. return sa.Return(-1);
  197. } // if
  198. } // case
  199. case TypeInfo<float>::TypeID: {
  200. float * val = (float *)upValMap.GetUserPointer(el);
  201. if (val) {
  202. return sa.Return(*val);
  203. } else {
  204. return sa.Return(-1);
  205. } // if
  206. } // case
  207. case TypeInfo<bool>::TypeID: {
  208. bool * val = (bool *)upValMap.GetUserPointer(el);
  209. if (val) {
  210. return sa.Return(*val);
  211. } else {
  212. return sa.Return(-1);
  213. } // if
  214. } // case
  215. } // switch
  216. } // if
  217. return SQ_ERROR;
  218. } // getVarFunc2
  219. template<typename T>
  220. void bindVariable2(SquirrelObject & so,T & var,const SQChar * scriptVarName) {
  221. SquirrelObject __upValMapPtr;
  222. SquirrelObject __upValMapType;
  223. if (so.Exists(_T("_uvp"))) {
  224. __upValMapPtr = so.GetValue(_T("_uvp"));
  225. __upValMapType = so.GetValue(_T("_uvt"));
  226. } else {
  227. __upValMapPtr = SquirrelVM::CreateTable();
  228. __upValMapType = SquirrelVM::CreateTable();
  229. } // if
  230. int varType = TypeInfo<T>::TypeID;
  231. __upValMapPtr.SetUserPointer(scriptVarName,&var);
  232. __upValMapType.SetValue(scriptVarName,varType);
  233. so.SetValue(_T("_uvp"),__upValMapPtr);
  234. so.SetValue(_T("_uvt"),__upValMapType);
  235. SquirrelObject delegate = so.GetDelegate();
  236. if (!delegate.Exists(_T("_set"))) {
  237. delegate = SquirrelVM::CreateTable();
  238. SquirrelVM::CreateFunction(delegate,"_set",setVarFunc2,_T("sn|b")); // String var name = number(int or float) or bool.
  239. SquirrelVM::CreateFunction(delegate,"_get",getVarFunc2,_T("s")); // String var name.
  240. so.SetDelegate(delegate);
  241. } // if
  242. } // bindVariable2
  243. #endif
  244. // === BEGIN Old, initial test versions. ===
  245. int setIntFunc(HSQUIRRELVM v) {
  246. StackHandler sa(v);
  247. if (sa.GetType(1) == OT_TABLE) {
  248. HSQOBJECT htable = sa.GetObjectHandle(1);
  249. SquirrelObject table(htable);
  250. const SQChar * el = sa.GetString(2);
  251. SquirrelObject upValMap = table.GetValue(_T("upValMap"));
  252. int * val = (int *)upValMap.GetUserPointer(el);
  253. if (val) {
  254. *val = sa.GetInt(3);
  255. return sa.Return(*val);
  256. } else {
  257. return sa.Return(-1);
  258. } // if
  259. } // if
  260. return SQ_ERROR;
  261. } // setIntFunc
  262. int getIntFunc(HSQUIRRELVM v) {
  263. StackHandler sa(v);
  264. if (sa.GetType(1) == OT_TABLE) {
  265. HSQOBJECT htable = sa.GetObjectHandle(1);
  266. SquirrelObject table(htable);
  267. int type = sa.GetType(2);
  268. const SQChar * el = sa.GetString(2);
  269. SquirrelObject upValMap = table.GetValue(_T("upValMap"));
  270. int * val = (int *)upValMap.GetUserPointer(el);
  271. if (val) {
  272. return sa.Return(*val);
  273. } else {
  274. return sa.Return(-1);
  275. } // if
  276. } // if
  277. return SQ_ERROR;
  278. } // getIntFunc
  279. // === END Old, initial tests versions. ===
  280. _DECL_STATIC_NAMESPACE(GB); // Globals
  281. _MEMBER_FUNCTION_IMPL(GB,Update) {
  282. StackHandler sa(v);
  283. scprintf(_T("GB.Update()\n"));
  284. return sa.Return(true);
  285. }
  286. enum {TEST_CONST=123};
  287. _BEGIN_NAMESPACE(GB)
  288. _MEMBER_FUNCTION(GB,Update,0,0)
  289. _BEGIN_NAMESPACE_CONSTANTS(GB)
  290. _CONSTANT_IMPL(TEST_CONST,OT_INTEGER)
  291. _END_NAMESPACE(GB,NULL)
  292. #if 0
  293. int getVarName(HSQUIRRELVM v) {
  294. StackHandler sa(v);
  295. const SQChar * varName = sq_getlocal(v,1,0);
  296. return sa.Return(varName);
  297. } // getVarName
  298. #endif
  299. void newtest(void) {
  300. scprintf(_T("NewTest\n"));
  301. }
  302. SQChar * newtestR1(const SQChar * inString) {
  303. scprintf(_T("NewTestR1: %s\n"),inString);
  304. return _T("Returned String");
  305. }
  306. struct NewTestObj {
  307. ScriptStringVar64 s1;
  308. ScriptStringVar32 s2;
  309. int pad;
  310. int val;
  311. int c1;
  312. ScriptStringVar8 c2; // 8 char plus null (max string is 8 printable chars).
  313. NewTestObj() : val(777) {
  314. s1 = _T("s1");
  315. s2 = _T("s2");
  316. c1 = 996;
  317. c2 = _T("It's a 997"); // Prints: "It's a 9", as only 8 chars in static buffer (plus null).
  318. }
  319. void newtest(void) {
  320. scprintf(_T("NewTest: %d\n"),val);
  321. }
  322. SQChar * newtestR1(const SQChar * inString) {
  323. scprintf(_T("NewTestR1: Member var val is %d, function arg is %s\n"),val,inString);
  324. return _T("Returned String");
  325. }
  326. int multiArgs(HSQUIRRELVM v) {
  327. StackHandler sa(v);
  328. int paramCount = sa.GetParamCount();
  329. int p1 = sa.GetInt(2);
  330. int p2 = sa.GetInt(3);
  331. int p3 = sa.GetInt(4);
  332. return 0;
  333. } // multiArgs
  334. int _set(HSQUIRRELVM v) {
  335. StackHandler sa(v);
  336. int paramCount = sa.GetParamCount();
  337. const SQChar * el = sa.GetString(2);
  338. val = sa.GetInt(3);
  339. return sa.Return(val);
  340. // return setInstanceVarFunc(v);
  341. }
  342. int _get(HSQUIRRELVM v) {
  343. StackHandler sa(v);
  344. int paramCount = sa.GetParamCount();
  345. // return getInstanceVarFunc(v);
  346. return sa.Return(val);
  347. }
  348. };
  349. struct CustomTestObj {
  350. ScriptStringVar128 name;
  351. int val;
  352. bool state;
  353. CustomTestObj() : val(0), state(false) { name = _T("empty"); }
  354. CustomTestObj(const SQChar * _name,int _val,bool _state) : val(_val), state(_state) {
  355. name = _name;
  356. }
  357. static int construct(HSQUIRRELVM v) {
  358. StackHandler sa(v);
  359. int paramCount = sa.GetParamCount();
  360. if (paramCount == 1) {
  361. return PostConstruct(v,new CustomTestObj(),release);
  362. } if (paramCount == 4) {
  363. return PostConstruct(v,new CustomTestObj(sa.GetString(2),sa.GetInt(3),sa.GetBool(4)?true:false),release);
  364. } // if
  365. return sq_throwerror(v,_T("Invalid Constructor arguments"));
  366. } // construct
  367. SQ_DECLARE_RELEASE(CustomTestObj)
  368. // Member function that handles variable types.
  369. int varArgTypes(HSQUIRRELVM v) {
  370. StackHandler sa(v);
  371. int paramCount = sa.GetParamCount();
  372. if (sa.GetType(2) == OT_INTEGER) {
  373. val = sa.GetInt(2);
  374. } // if
  375. if (sa.GetType(2) == OT_STRING) {
  376. name = sa.GetString(2);
  377. } // if
  378. if (sa.GetType(3) == OT_INTEGER) {
  379. val = sa.GetInt(3);
  380. } // if
  381. if (sa.GetType(3) == OT_STRING) {
  382. name = sa.GetString(3);
  383. } // if
  384. return 0;
  385. } // varArgTypes
  386. // Member function that handles variable types and has variable return types+count.
  387. int varArgTypesAndCount(HSQUIRRELVM v) {
  388. StackHandler sa(v);
  389. int paramCount = sa.GetParamCount();
  390. SQObjectType type1 = (SQObjectType)sa.GetType(1); // Always OT_INSTANCE
  391. SQObjectType type2 = (SQObjectType)sa.GetType(2);
  392. SQObjectType type3 = (SQObjectType)sa.GetType(3);
  393. SQObjectType type4 = (SQObjectType)sa.GetType(4);
  394. int returnCount = 0;
  395. if (paramCount == 3) {
  396. sq_pushinteger(v,val);
  397. returnCount = 1;
  398. } else if (paramCount == 4) {
  399. sq_pushinteger(v,val);
  400. sq_pushstring(v,name,-1);
  401. returnCount = 2;
  402. } // if
  403. return returnCount;
  404. } //
  405. int noArgsVariableReturn(HSQUIRRELVM v) {
  406. if (val == 123) {
  407. val++;
  408. return 0; // This will print (null).
  409. } else if (val == 124) {
  410. sq_pushinteger(v,val); // Will return int:124.
  411. val++;
  412. return 1;
  413. } else if (val == 125) {
  414. sq_pushinteger(v,val);
  415. name = _T("Case 125");
  416. sq_pushstring(v,name,-1);
  417. val = 123; // reset
  418. return 2;
  419. } // if
  420. return 0;
  421. } // noArgsVariableReturn
  422. // Registered with func() instead of funcVarArgs(): fixed (single) return type.
  423. const SQChar * variableArgsFixedReturnType(HSQUIRRELVM v) {
  424. StackHandler sa(v);
  425. int paramCount = sa.GetParamCount();
  426. SQObjectType type1 = (SQObjectType)sa.GetType(1); // Always OT_INSTANCE
  427. SQObjectType type2 = (SQObjectType)sa.GetType(2);
  428. SQObjectType type3 = (SQObjectType)sa.GetType(3);
  429. if (paramCount == 1) {
  430. return _T("No Args");
  431. } else if (paramCount == 2) {
  432. return _T("One Arg");
  433. } else if (paramCount == 3) {
  434. return _T("Two Args");
  435. } // if
  436. return _T("More than two args");
  437. } // variableArgsFixedReturnType
  438. void manyArgs(int i,float f,bool b,const SQChar * s) {
  439. scprintf(_T("i: %d, f: %f, b: %s, s: %s\n"),i,f,b?_T("true"):_T("false"),s);
  440. } // manyArgs
  441. float manyArgsR1(int i,float f,bool b,const SQChar * s) {
  442. manyArgs(i,f,b,s);
  443. return i+f;
  444. } // manyArgsR1
  445. };
  446. #if 0
  447. struct Base {
  448. int val1;
  449. ScriptStringVar16 nameBase;
  450. Base() : nameBase(_T("Base")) {
  451. val1 = 123;
  452. }
  453. void funcBase(void) {
  454. scprintf(_T("Val1: %d, Name: %s\n"),val1,nameBase.s);
  455. }
  456. };
  457. struct Derived {
  458. int val2;
  459. ScriptStringVar16 nameDerived;
  460. Derived() : nameDerived(_T("Derived")), val2(456) {
  461. val2 = 456;
  462. }
  463. void funcDerived(void) {
  464. scprintf(_T("Val2: %d, Name: %s\n"),val2,nameDerived.s);
  465. }
  466. };
  467. #endif
  468. //SQ_DECLARE_CLASS(NewTestObj);
  469. class TestSqPlus {
  470. public:
  471. void init(void) {
  472. SquirrelVM::Init();
  473. // sq_setprintfunc(SquirrelVM::GetVMPtr(),printfunc); //sets the print function.
  474. _INIT_CLASS(TestObj);
  475. _INIT_STATIC_NAMESPACE(GB);
  476. } // if
  477. TestSqPlus() {
  478. init();
  479. try {
  480. HSQUIRRELVM v = SquirrelVM::GetVMPtr();
  481. // === BEGIN Global Function binding tests ===
  482. // Implemented as SquirrelVM::CreateFunction(rootTable,func,name,typeMask);
  483. SquirrelVM::CreateFunctionGlobal(&testFunc,_T("testFunc0"));
  484. SquirrelVM::CreateFunctionGlobal(&testFunc,_T("testFuncN"),_T("n"));
  485. SquirrelVM::CreateFunctionGlobal(&testFunc,_T("testFuncS"),_T("s"));
  486. // === Register Standard Functions ===
  487. RegisterGlobal(v,&newtest,_T("test"));
  488. RegisterGlobal(v,&newtestR1,_T("testR1"));
  489. // === Register Member Functions to existing classes (as opposed to instances of classes) ===
  490. NewTestObj t1,t2,t3;
  491. t1.val = 123;
  492. t2.val = 456;
  493. t3.val = 789;
  494. RegisterGlobal(v,t1,&NewTestObj::newtest,_T("testObj_newtest1"));
  495. RegisterGlobal(v,t2,&NewTestObj::newtest,_T("testObj_newtest2")); // Register newtest() again with different name and object pointer.
  496. SquirrelObject tr = SquirrelVM::GetRootTable(); // Can be any object supporting closures (functions).
  497. Register(v,tr.GetObjectHandle(),t3,&NewTestObj::newtestR1,_T("testObj_newtestR1")); // Return value version.
  498. // === END Global Function binding tests ===
  499. // === BEGIN Class Instance tests ===
  500. #if 0
  501. SQClassDef<NewTestObj> sqClass(_T("NewTestObj"));
  502. sqClass.func(&NewTestObj::newtestR1,_T("newtestR1"));
  503. sqClass.var(&NewTestObj::val,_T("val"));
  504. sqClass.var(&NewTestObj::s1,_T("s1"));
  505. sqClass.var(&NewTestObj::s2,_T("s2"));
  506. sqClass.var(&NewTestObj::c1,_T("c1"),VAR_ACCESS_READ_ONLY);
  507. sqClass.var(&NewTestObj::c2,_T("c2"),VAR_ACCESS_READ_ONLY);
  508. sqClass.funcVarArgs(&NewTestObj::multiArgs,_T("multiArgs"));
  509. #else
  510. SQClassDef<NewTestObj>(_T("NewTestObj")).
  511. func(&NewTestObj::newtestR1,_T("newtestR1")).
  512. var(&NewTestObj::val,_T("val")).
  513. var(&NewTestObj::s1,_T("s1")).
  514. var(&NewTestObj::s2,_T("s2")).
  515. var(&NewTestObj::c1,_T("c1"),VAR_ACCESS_READ_ONLY).
  516. var(&NewTestObj::c2,_T("c2"),VAR_ACCESS_READ_ONLY).
  517. funcVarArgs(&NewTestObj::multiArgs,_T("multiArgs"));
  518. #endif
  519. SQClassDef<CustomTestObj> customClass(_T("CustomTestObj"));
  520. customClass.staticFuncVarArgs(&CustomTestObj::construct,_T("constructor"),_T("snb")); // string, number, bool (all types must match).
  521. customClass.funcVarArgs(&CustomTestObj::varArgTypes,_T("varArgTypes"),_T("s|ns|ns|ns|n")); // string or number + string or number.
  522. customClass.funcVarArgs(&CustomTestObj::varArgTypesAndCount,_T("varArgTypesAndCount"),_T("*")); // "*"): no type or count checking.
  523. customClass.funcVarArgs(&CustomTestObj::noArgsVariableReturn,_T("noArgsVariableReturn")); // No type string means no arguments allowed.
  524. customClass.func(&CustomTestObj::variableArgsFixedReturnType,_T("variableArgsFixedReturnType")); // Variables args, fixed return type.
  525. customClass.func(&CustomTestObj::manyArgs,_T("manyArgs")); // Many args, type checked.
  526. customClass.func(&CustomTestObj::manyArgsR1,_T("manyArgsR1")); // Many args, type checked, one return value.
  527. // Old macro-based method. Must use SQ_DECLARE_CLASS() macro above.
  528. #if 0
  529. SquirrelObject newClass = SQ_REGISTER_CLASS(NewTestObj);
  530. SQ_REGISTER_INSTANCE(newClass,NewTestObj,newtestR1);
  531. // Currently, can use either automatic variable handling OR manual handling (but not both at once).
  532. #if 1
  533. SQ_REGISTER_INSTANCE_VARIABLE(newClass,NewTestObj,val); // _set/_get will be defined to use automatic methods for val.
  534. #else
  535. SQ_REGISTER_INSTANCE_VARARGS(newClass,NewTestObj,_set); // _set is now defined and won't be overridden.
  536. SQ_REGISTER_INSTANCE_VARARGS(newClass,NewTestObj,_get);
  537. SQ_REGISTER_INSTANCE_VARIABLE(newClass,NewTestObj,val); // Access will be through _set/_get member functions above, not automatic methods.
  538. #endif
  539. #if 1
  540. // With an HSQUIRRELVM argument, can handle variable args, and when registered this way can return multiple values.
  541. SQ_REGISTER_INSTANCE_VARARGS(newClass,NewTestObj,multiArgs);
  542. #else
  543. // With an HSQUIRRELVM argument, can handle variable args, but can only return one value (defined by the function definition).
  544. SQ_REGISTER_INSTANCE(newClass,NewTestObj,multiArgs);
  545. #endif
  546. #endif
  547. #if 1
  548. SquirrelObject testReg0 = SquirrelVM::CompileBuffer(_T(" co <- CustomTestObj(\"hello\",123,true); co.varArgTypes(\"str\",123,123,\"str\"); co.varArgTypes(123,\"str\",\"str\",123); "));
  549. SquirrelVM::RunScript(testReg0);
  550. SquirrelObject testReg0a = SquirrelVM::CompileBuffer(_T(" print(co.varArgTypesAndCount(1,true)); print(co.varArgTypesAndCount(2,false,3.)); print(\"\\n\"); "));
  551. SquirrelVM::RunScript(testReg0a);
  552. SquirrelObject testReg0b = SquirrelVM::CompileBuffer(_T(" print(co.noArgsVariableReturn()); print(co.noArgsVariableReturn()); print(co.noArgsVariableReturn()); print(\"\\n\"); "));
  553. SquirrelVM::RunScript(testReg0b);
  554. SquirrelObject testReg0c = SquirrelVM::CompileBuffer(_T(" print(co.variableArgsFixedReturnType(1)); print(co.variableArgsFixedReturnType(1,2)); print(co.variableArgsFixedReturnType(1,2,3)); print(\"\\n\"); "));
  555. SquirrelVM::RunScript(testReg0c);
  556. SquirrelObject testReg0d = SquirrelVM::CompileBuffer(_T(" co.manyArgs(111,222.2,true,\"Hello\"); print(co.manyArgsR1(333,444.3,false,\"World\")); print(\"\\n\"); "));
  557. SquirrelVM::RunScript(testReg0d);
  558. #endif
  559. // Inheriting from an existing base class in this way is not currently supported.
  560. // Requires either a Squirrel language/behavior change, or extra code at the interface
  561. // layer to allocate memory and call constructor of parent class (and perhaps
  562. // handle constructor args) store pointer in UserData, and handle proper variable access
  563. // (get correct class/struct pointer) and member function calls (store class
  564. // type/id in function up-var and search/hash for actual 'this' pointer for function call).
  565. #if 0
  566. SQClassDef<Base>(_T("Base")).
  567. var(&Base::nameBase,_T("nameBase")).
  568. func(&Base::funcBase,_T("funcBase"));
  569. SQClassDef<Derived>("Derived",_T("Base")).
  570. var(&Derived::nameDerived,_T("nameDerived")).
  571. func(&Derived::funcDerived,_T("funcDerived"));
  572. // SquirrelObject testBaseDerived = SquirrelVM::CompileBuffer(_T(" local base = Base(); print(base.nameBase); local derived = Derived(); print(\"NameBase: \"+derived.nameBase+\" NameDerived: \"+derived.nameDerived); derived.funcBase(); "));
  573. SquirrelObject testBaseDerived = SquirrelVM::CompileBuffer(_T(" local derived = Derived(); print(\"NameBase: \"+derived.nameBase+\" NameDerived: \"+derived.nameDerived); derived.funcBase(); "));
  574. SquirrelVM::RunScript(testBaseDerived);
  575. #endif
  576. #if 1
  577. SquirrelObject testReg1a = SquirrelVM::CompileBuffer(_T(" co <- CustomTestObj(\"hello\",123,true); co.noArgsVariableReturn(); local t = NewTestObj(); print(\"C1: \"+t.c1); print(\"C2: \"+t.c2); // t.c1 = 123; "));
  578. SquirrelVM::RunScript(testReg1a);
  579. // Constant test (read only var). Var can change on C++ side, but not on script side.
  580. try {
  581. SquirrelObject testRegConstant = SquirrelVM::CompileBuffer(_T(" local t = NewTestObj(); t.c1 = 123; "));
  582. SquirrelVM::RunScript(testRegConstant);
  583. } // try
  584. catch (SquirrelError & e) {
  585. SQChar buff[256];
  586. scsprintf(buff,_T("Error: %s, %s\n"),e.desc,_T("Squirrel::TestConstant"));
  587. // OutputDebugString(buff);
  588. SCPUTS(buff);
  589. } // catch
  590. SquirrelObject testReg1 = SquirrelVM::CompileBuffer(_T(" local t = NewTestObj(); t.newtestR1(\"Hello\"); t.val = 789; print(t.val); print(t.s1); print(t.s2); t.s1 = \"New S1\"; print(t.s1); "));
  591. SquirrelVM::RunScript(testReg1);
  592. SquirrelObject testReg2 = SquirrelVM::CompileBuffer(_T(" local t = NewTestObj(); t.val = 789; print(t.val); t.val = 876; print(t.val); t.multiArgs(1,2,3); t.multiArgs(1,2,3,4); "));
  593. SquirrelVM::RunScript(testReg2);
  594. SquirrelObject testReg3 = SquirrelVM::CompileBuffer(_T(" test(); local rv = testR1(\"Hello\"); print(rv); "));
  595. SquirrelVM::RunScript(testReg3);
  596. SquirrelObject testReg4 = SquirrelVM::CompileBuffer(_T(" print(\"\\nMembers:\"); testObj_newtest1(); testObj_newtest2(); print(testObj_newtestR1(\"Hello Again\")); "));
  597. SquirrelVM::RunScript(testReg4);
  598. SquirrelObject defCallFunc = SquirrelVM::CompileBuffer(_T(" function callMe(var) { print(\"I was called by: \"+var); return 123; }"));
  599. SquirrelVM::RunScript(defCallFunc);
  600. SquirrelObject root = SquirrelVM::GetRootTable();
  601. // Get a function from the root table and call it.
  602. SquirrelFunction<int> callFunc(_T("callMe"));
  603. int ival = callFunc(_T("Squirrel"));
  604. scprintf(_T("IVal: %d\n"),ival);
  605. ival = 0;
  606. // Get a function from any table.
  607. SquirrelFunction<int> callFunc2(root.GetObjectHandle(),_T("callMe"));
  608. ival = callFunc(456); // Argument count is checked; type is not.
  609. // === END Class Instance tests ===
  610. // === BEGIN macro-only class-registrated tests ===
  611. // SquirrelVM::CreateFunctionGlobal(_T("getName",getVarName,"*")); // * = any type.
  612. // SquirrelObject main = SquirrelVM::CompileBuffer(_T("local testObj = TestObj(); testObj.print(); testObj.update(\"ab\"); testObj.print()"));
  613. // SquirrelObject main = SquirrelVM::CompileBuffer(_T("local LF = \"\\n\"; local testObj = TestObj(); testObj.print(); testObj.update(1.5); testObj.print(); testObj.y += 10.; testObj.z = -1.; print(testObj.y+LF); print(\"Array: \"+testObj[0]+LF); print(testObj); print(LF); "));
  614. // SquirrelObject main = SquirrelVM::CompileBuffer(_T("local testObj = TestObj(); testObj.z = -1.; print(testObj); testFunc(); testFunc0(); testFuncN(1.); testFuncS(\"Hello\"); "));
  615. // SquirrelObject main = SquirrelVM::CompileBuffer(_T("testFunc0(); testFuncN(1); testFuncN(1.23); testFuncS(\"Hello\");"));
  616. SquirrelObject main = SquirrelVM::CompileBuffer(_T("table1 <- {key1=\"keyVal\",key2 = 123};\n if (\"key1\" in table1)\n print(\"Sq: Found it\");\n else\n print(\"Sq: Not found\");"));
  617. SquirrelVM::RunScript(main);
  618. SquirrelObject table1 = root.GetValue(_T("table1"));
  619. if (table1.Exists(_T("key1"))) {
  620. scprintf(_T("C++: Found it.\n"));
  621. } else {
  622. scprintf(_T("C++: Did not find it.\n"));
  623. } // if
  624. // === BEGIN Simple variable binding tests ===
  625. int iVar = 777;
  626. float fVar = 88.99f;
  627. bool bVar = true;
  628. BindVariable(root,&iVar,_T("iVar"));
  629. BindVariable(root,&fVar,_T("fVar"));
  630. BindVariable(root,&bVar,_T("bVar"));
  631. static ScriptStringVar128 testString;
  632. scsprintf(testString,_T("This is a test string"));
  633. BindVariable(root,&testString,_T("testString"));
  634. // === END Simple variable binding tests ===
  635. // === BEGIN Array Tests ===
  636. SquirrelObject array = SquirrelVM::CreateArray(10);
  637. int i;
  638. for (i = 0; i < 10; i++) array.SetValue(i,i);
  639. array.ArrayAppend(123); // int
  640. array.ArrayAppend(true); // bool (must use bool and not SQBool (SQBool is treated as INT by compiler).
  641. array.ArrayAppend(false); // bool (must use bool and not SQBool (SQBool is treated as INT by compiler).
  642. array.ArrayAppend(123.456f); // float
  643. array.ArrayAppend(_T("string")); // string
  644. array.ArrayAppend(456); // Will be popped and thrown away (below).
  645. // Pop 3 items from array:
  646. array.ArrayPop(SQFalse); // Don't retrieve the popped value (int:123).
  647. SquirrelObject so1 = array.ArrayPop(); // Retrieve the popped value.
  648. const SQChar * val1 = so1.ToString(); // Get string.
  649. float val2 = array.ArrayPop().ToFloat(); // Pop and get float.
  650. scprintf(_T("[Popped values] Val1: %s, Val2: %f\n"),val1,val2);
  651. int startIndex = array.Len();
  652. array.ArrayExtend(10); // Implemented as: ArrayResize(Len()+amount).
  653. for (i = startIndex; i < array.Len(); i++) array.SetValue(i,i*10);
  654. root.SetValue(_T("array"),array);
  655. SquirrelObject arrayr = array.Clone(); // Get a copy as opposed to another reference.
  656. arrayr.ArrayReverse();
  657. root.SetValue(_T("arrayr"),arrayr);
  658. // === END Array Tests ===
  659. // SquirrelObject test = SquirrelVM::CompileBuffer(_T(" print(iVar); print(fVar); print(bVar); iVar += 1; fVar += 100.; bVar = false; print(iVar); print(fVar); print(bVar); xVar = 1; ")); // Test for xVar error.
  660. // SquirrelObject test = SquirrelVM::CompileBuffer(_T(" print(iVar); print(fVar); print(bVar); iVar += 1; fVar += 100.; bVar = false; print(iVar); print(fVar); print(bVar); print(testString); testString = \"New string value\"; print(testString);"));
  661. SquirrelObject define_printArray = SquirrelVM::CompileBuffer(_T(" function printArray(name,array) { print(name+\".len() = \"+array.len()); foreach(i, v in array) if (v != null) { if (typeof v == \"bool\") v = v ? \"true\" : \"false\"; print(\"[\"+i+\"]: \"+v); } } "));
  662. SquirrelVM::RunScript(define_printArray);
  663. SquirrelObject test = SquirrelVM::CompileBuffer(_T(" printArray(\"array\",array); printArray(\"arrayr\",arrayr); "));
  664. // SquirrelObject test = SquirrelVM::CompileBuffer(_T(" iVar = 1; print(iVar); "));
  665. // SquirrelObject test = SquirrelVM::CompileBuffer(_T(" print(\"GB:\"+GB.TEST_CONST); GB.TEST_CONST += 1; GB.Update(); print(\"GB2:\"+GB.TEST_CONST); \n"));
  666. SquirrelVM::RunScript(test);
  667. #endif
  668. } // try
  669. catch (SquirrelError & e) {
  670. // SquirrelVM::DumpStack();
  671. SQChar buff[256];
  672. scsprintf(buff,_T("Error: %s, %s\n"),e.desc,_T("Squirrel::TestObj"));
  673. // OutputDebugString(buff);
  674. SCPUTS(buff);
  675. } // catch
  676. }
  677. ~TestSqPlus() {
  678. SquirrelVM::Shutdown();
  679. }
  680. };
  681. void doTest(void) {
  682. TestSqPlus testSqPlus;
  683. } // doTest
  684. int main(int argc,char * argv[]) {
  685. // Run twice to make sure cleanup/shutdown works OK.
  686. SCPUTS(_T("Start Pass 1\n"));
  687. doTest();
  688. #if 0
  689. SCPUTS(_T("Start Pass 2\n"));
  690. doTest();
  691. #endif
  692. SCPUTS(_T("Done.\n"));
  693. scprintf(_T("Press RETURN to exit."));
  694. getchar();
  695. return 0;
  696. }