Simple game engine with complete export to scripting language
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.
 
 
 

209 lines
4.0 KiB

  1. #include "ScriptSystem.h"
  2. #include "Utilities/Log.h"
  3. // library includes
  4. #include "physfs.h"
  5. // system includes
  6. #include <iostream>
  7. #include <cmath>
  8. #include <stdio.h>
  9. #include <stdarg.h>
  10. using namespace std;
  11. namespace BlueCore
  12. {
  13. static ScriptSystem* gScriptSystem = 0;
  14. void _sq_compiler_error_handler(HSQUIRRELVM vm, const SQChar *error,
  15. const SQChar *source, SQInteger line, SQInteger column)
  16. {
  17. clog << "!!! Error compiling script '"<< source << ":"<< line << ": "
  18. << error << endlog;
  19. }
  20. static SQInteger _sq_runtime_error_handler(HSQUIRRELVM vm)
  21. {
  22. const SQChar *error = 0;
  23. if (sq_gettop(vm) >= 1)
  24. {
  25. if (SQ_SUCCEEDED(sq_getstring(vm, 2, &error) ) )
  26. {
  27. clog << "!!! Script Error: "<< error << endlog;
  28. }
  29. else
  30. {
  31. clog << "!!! Script Error: unknown"<< endlog;
  32. }
  33. }
  34. return 0;
  35. }
  36. void _sq_print(HSQUIRRELVM vm, const SQChar* s, ...)
  37. {
  38. va_list vl;
  39. va_start ( vl, s );
  40. vprintf(s, vl);
  41. va_end ( vl );
  42. }
  43. static SQInteger _sq_require(HSQUIRRELVM v)
  44. {
  45. const SQChar *scriptname = 0;
  46. if (SQ_SUCCEEDED(sq_getstring(v, 2, &scriptname) ))
  47. {
  48. if (gScriptSystem)
  49. gScriptSystem->loadScript(scriptname);
  50. }
  51. return 0;
  52. }
  53. SQInteger _sq_file_reader(SQUserPointer file)
  54. {
  55. char c;
  56. unsigned int count;
  57. count = PHYSFS_read( (PHYSFS_file *)file, &c, sizeof (c), 1);
  58. if (count > 0)
  59. return c;
  60. return 0;
  61. }
  62. ScriptSystem::ScriptSystem()
  63. {
  64. gScriptSystem = this;
  65. _VM = sq_open( 1024);
  66. sq_setcompilererrorhandler(_VM, _sq_compiler_error_handler);
  67. sq_newclosure(_VM, _sq_runtime_error_handler, 0);
  68. sq_seterrorhandler(_VM);
  69. sq_setprintfunc(_VM, _sq_print);
  70. sq_pushroottable(_VM);
  71. sq_pushstring(_VM, "require", -1);
  72. sq_newclosure(_VM, _sq_require, 0);
  73. sq_setparamscheck(_VM, 2, ".s");
  74. sq_newslot(_VM, -3, false);
  75. sq_pop(_VM, 1);
  76. clog << ">>> ScriptSystem constructed ..."<< endlog;
  77. }
  78. ScriptSystem::~ScriptSystem()
  79. {
  80. sq_close(_VM);
  81. clog << ">>> ScriptSystem destructed ..."<< endlog;
  82. }
  83. HSQUIRRELVM ScriptSystem::getVM()
  84. {
  85. return _VM;
  86. }
  87. bool ScriptSystem::loadScript(const std::string &name)
  88. {
  89. for (unsigned int i = 0; i < _LoadedScripts.size(); i++)
  90. {
  91. if (_LoadedScripts[i] == name)
  92. return true;
  93. }
  94. if (executeScript(name) )
  95. {
  96. _LoadedScripts.push_back(name);
  97. return true;
  98. }
  99. else
  100. clog << "!!! Script '"<< name << "' not found!"<< endlog;
  101. return false;
  102. }
  103. bool ScriptSystem::executeScript(const std::string &name)
  104. {
  105. string filename = name + ".nut";
  106. PHYSFS_file *file = PHYSFS_openRead(filename.c_str() );
  107. if ( !file)
  108. {
  109. clog << "!!! Script '"<< name << "' not found!"<< endlog;
  110. return false;
  111. }
  112. SQInteger ret;
  113. ret = sq_compile(_VM, _sq_file_reader, file, name.c_str(), 1);
  114. PHYSFS_close(file);
  115. if (SQ_FAILED(ret) )
  116. {
  117. return false;
  118. }
  119. sq_pushroottable(_VM);
  120. ret = sq_call(_VM, 1, SQFalse, SQTrue);
  121. sq_pop(_VM, 1);
  122. if (SQ_FAILED(ret) )
  123. {
  124. clog << "!!! Script execution failed: "<< name << endlog;
  125. return false;
  126. }
  127. else
  128. return true;
  129. }
  130. void ScriptSystem::callFunction(const std::string &name)
  131. {
  132. sq_pushroottable(_VM);
  133. sq_pushstring(_VM, name.c_str(), -1);
  134. if (SQ_SUCCEEDED(sq_get(_VM, -2)) )
  135. {
  136. sq_pushroottable(_VM);
  137. sq_call(_VM, 1, SQFalse, SQTrue);
  138. sq_pop(_VM, 1);
  139. }
  140. sq_pop(_VM, 1);
  141. }
  142. void ScriptSystem::callFunction(const std::string &name, double value)
  143. {
  144. sq_pushroottable(_VM);
  145. sq_pushstring(_VM, name.c_str(), -1);
  146. if (SQ_SUCCEEDED(sq_get(_VM, -2)) )
  147. {
  148. sq_pushroottable(_VM);
  149. sq_pushfloat(_VM, value);
  150. sq_call(_VM, 2, SQFalse, SQTrue);
  151. sq_pop(_VM, 1);
  152. }
  153. sq_pop(_VM, 1);
  154. }
  155. void ScriptSystem::callFunction(const std::string &name, double value1,
  156. double value2)
  157. {
  158. sq_pushroottable(_VM);
  159. sq_pushstring(_VM, name.c_str(), -1);
  160. if (SQ_SUCCEEDED(sq_get(_VM, -2)) )
  161. {
  162. sq_pushroottable(_VM);
  163. sq_pushfloat(_VM, value1);
  164. sq_pushfloat(_VM, value2);
  165. sq_call(_VM, 3, SQFalse, SQTrue);
  166. sq_pop(_VM, 1);
  167. }
  168. sq_pop(_VM, 1);
  169. }
  170. }