c_scripting.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2012 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #include "platform/platform.h"
  23. #include "console/compiler.h"
  24. #include "console/console.h"
  25. #include "console/consoleInternal.h"
  26. #include "core/util/tDictionary.h"
  27. #include "app/mainLoop.h"
  28. // External scripting cinterface, suitable for import into any scripting system which support "C" interfaces (C#, Python, Lua, Java, etc)
  29. #ifdef TORQUE_OS_WIN
  30. #include "windowManager/win32/win32Window.h"
  31. #include "windowManager/win32/winDispatch.h"
  32. #endif
  33. extern "C" {
  34. struct MarshalNativeEntry
  35. {
  36. const char* nameSpace;
  37. const char* name;
  38. Namespace::Entry* entry;
  39. S32 minArgs;
  40. S32 maxArgs;
  41. S32 cbType;
  42. };
  43. static Namespace::Entry* GetEntry(const char* nameSpace, const char* name)
  44. {
  45. Namespace* ns = NULL;
  46. if (!nameSpace || !dStrlen(nameSpace))
  47. ns = Namespace::mGlobalNamespace;
  48. else
  49. {
  50. nameSpace = StringTable->insert(nameSpace);
  51. ns = Namespace::find(nameSpace); //can specify a package here, maybe need, maybe not
  52. }
  53. if (!ns)
  54. return NULL;
  55. name = StringTable->insert(name);
  56. Namespace::Entry* entry = ns->lookupRecursive(name);
  57. return entry;
  58. }
  59. const char * script_getconsolexml()
  60. {
  61. Namespace::Entry* entry = GetEntry("", "consoleExportXML");
  62. if (!entry)
  63. return "";
  64. static const char* exportArgv[1] = { "consoleExportXML" };
  65. static StringStackConsoleWrapper exportCmd(1, exportArgv);
  66. return entry->cb.mStringCallbackFunc(NULL, exportCmd.argc, exportCmd.argv);
  67. }
  68. MarshalNativeEntry* script_get_namespace_entry(const char* nameSpace, const char* name)
  69. {
  70. static MarshalNativeEntry mentry;
  71. Namespace::Entry* e = GetEntry(nameSpace, name);
  72. if (!e)
  73. return NULL;
  74. mentry.nameSpace = e->mNamespace->mName;
  75. mentry.name = e->mFunctionName;
  76. mentry.minArgs = e->mMinArgs;
  77. mentry.maxArgs = e->mMaxArgs;
  78. mentry.cbType = e->mType;
  79. mentry.entry = e;
  80. return &mentry;
  81. }
  82. void* script_get_stringtable_entry(const char* string)
  83. {
  84. return (void*)StringTable->insert(string);
  85. }
  86. // FIELD ACCESS
  87. // fieldNames must be from stringTable coming in! See Engine.stringTable
  88. const char* script_simobject_getfield_string(U32 id, const char* fieldName)
  89. {
  90. SimObject *object = Sim::findObject( id );
  91. if( object )
  92. {
  93. return (const char *) object->getDataField(fieldName, "");
  94. }
  95. return "";
  96. }
  97. void script_simobject_setfield_string(U32 objectId, const char* fieldName, const char* v)
  98. {
  99. SimObject *object = Sim::findObject( objectId );
  100. if( object )
  101. {
  102. object->setDataField(fieldName, "", v);
  103. }
  104. }
  105. bool script_simobject_getfield_bool(U32 objectId, const char* fieldName)
  106. {
  107. SimObject *object = Sim::findObject( objectId );
  108. if( object )
  109. {
  110. const char *v = object->getDataField(fieldName, "");
  111. return dAtob(v);
  112. }
  113. return false;
  114. }
  115. void script_simobject_setfield_bool(U32 objectId, const char* fieldName, bool v)
  116. {
  117. SimObject *object = Sim::findObject( objectId );
  118. if( object )
  119. {
  120. object->setDataField(fieldName, "", v ? "1" : "0");
  121. }
  122. }
  123. S32 script_simobject_getfield_int(U32 objectId, const char* fieldName)
  124. {
  125. SimObject *object = Sim::findObject( objectId );
  126. if( object )
  127. {
  128. const char *v = object->getDataField(fieldName, "");
  129. return dAtoi(v);
  130. }
  131. return false;
  132. }
  133. void script_simobject_setfield_int(U32 objectId, const char* fieldName, S32 v)
  134. {
  135. SimObject *object = Sim::findObject( objectId );
  136. if( object )
  137. {
  138. // this seems pretty lame, though it is how it is handled in consoleType.cpp
  139. char buf[256];
  140. dSprintf(buf, 256, "%d", v );
  141. object->setDataField(fieldName, "", buf);
  142. }
  143. }
  144. F32 script_simobject_getfield_float(U32 objectId, const char* fieldName)
  145. {
  146. SimObject *object = Sim::findObject( objectId );
  147. if( object )
  148. {
  149. const char *v = object->getDataField(fieldName, "");
  150. return dAtof(v);
  151. }
  152. return false;
  153. }
  154. void script_simobject_setfield_float(U32 objectId, const char* fieldName, F32 v)
  155. {
  156. SimObject *object = Sim::findObject( objectId );
  157. if( object )
  158. {
  159. char buf[256];
  160. dSprintf(buf, 256, "%g", v );
  161. object->setDataField(fieldName, "", buf);
  162. }
  163. }
  164. const char* script_call_namespace_entry_string(Namespace::Entry* entry, S32 argc, const char** argv)
  165. {
  166. // maxArgs improper on a number of console function/methods
  167. if (argc < entry->mMinArgs)// || argc > entry->mMaxArgs)
  168. return "";
  169. SimObject* o = NULL;
  170. if (entry->mNamespace && entry->mNamespace->isClass())
  171. {
  172. o = Sim::findObject(dAtoi(argv[1]));
  173. if (!o)
  174. return "";
  175. }
  176. StringStackConsoleWrapper args(argc, argv);
  177. return entry->cb.mStringCallbackFunc(o, args.count(), args);
  178. }
  179. bool script_call_namespace_entry_bool(Namespace::Entry* entry, S32 argc, const char** argv)
  180. {
  181. // maxArgs improper on a number of console function/methods
  182. if (argc < entry->mMinArgs)// || argc > entry->mMaxArgs)
  183. return false;
  184. SimObject* o = NULL;
  185. if (entry->mNamespace && entry->mNamespace->isClass())
  186. {
  187. o = Sim::findObject(dAtoi(argv[1]));
  188. if (!o)
  189. return false;
  190. }
  191. StringStackConsoleWrapper args(argc, argv);
  192. return entry->cb.mBoolCallbackFunc(o, args.count(), args);
  193. }
  194. S32 script_call_namespace_entry_int(Namespace::Entry* entry, S32 argc, const char** argv)
  195. {
  196. // maxArgs improper on a number of console function/methods
  197. if (argc < entry->mMinArgs)// || argc > entry->mMaxArgs)
  198. return 0;
  199. SimObject* o = NULL;
  200. if (entry->mNamespace && entry->mNamespace->isClass())
  201. {
  202. o = Sim::findObject(dAtoi(argv[1]));
  203. if (!o)
  204. return 0;
  205. }
  206. StringStackConsoleWrapper args(argc, argv);
  207. return entry->cb.mIntCallbackFunc(o, args.count(), args);
  208. }
  209. F32 script_call_namespace_entry_float(Namespace::Entry* entry, S32 argc, const char** argv)
  210. {
  211. // maxArgs improper on a number of console function/methods
  212. if (argc < entry->mMinArgs)// || argc > entry->mMaxArgs)
  213. return 0.0f;
  214. SimObject* o = NULL;
  215. if (entry->mNamespace && entry->mNamespace->isClass())
  216. {
  217. o = Sim::findObject(dAtoi(argv[1]));
  218. if (!o)
  219. return 0.0f;
  220. }
  221. StringStackConsoleWrapper args(argc, argv);
  222. return entry->cb.mFloatCallbackFunc(o, args.count(), args);
  223. }
  224. void script_call_namespace_entry_void(Namespace::Entry* entry, S32 argc, const char** argv)
  225. {
  226. // maxArgs improper on a number of console function/methods
  227. if (argc < entry->mMinArgs)// || argc > entry->mMaxArgs)
  228. return;
  229. SimObject* o = NULL;
  230. if (entry->mNamespace && entry->mNamespace->isClass())
  231. {
  232. Sim::findObject(dAtoi(argv[1]));
  233. if (!o)
  234. return;
  235. }
  236. StringStackConsoleWrapper args(argc, argv);
  237. entry->cb.mVoidCallbackFunc(o, args.count(), args);
  238. }
  239. S32 script_simobject_get_id(SimObject* so)
  240. {
  241. return so->getId();
  242. }
  243. S32 script_simobject_find(const char* classname, const char* name)
  244. {
  245. SimObject *object;
  246. if( Sim::findObject( name, object ) )
  247. {
  248. // if we specified a classname do type checking
  249. if (classname && dStrlen(classname))
  250. {
  251. AbstractClassRep* ocr = object->getClassRep();
  252. while (ocr)
  253. {
  254. if (!dStricmp(ocr->getClassName(), classname))
  255. return object->getId();
  256. ocr = ocr->getParentClass();
  257. }
  258. }
  259. // invalid type
  260. return 0;
  261. }
  262. // didn't find object
  263. return 0;
  264. }
  265. void script_export_callback_string(StringCallback cb, const char *nameSpace, const char *funcName, const char* usage, S32 minArgs, S32 maxArgs)
  266. {
  267. if (!nameSpace || !dStrlen(nameSpace))
  268. Con::addCommand(funcName, cb, usage, minArgs + 1, maxArgs + 1);
  269. else
  270. Con::addCommand(nameSpace, funcName, cb, usage, minArgs + 1, maxArgs + 1);
  271. }
  272. void script_export_callback_void(VoidCallback cb, const char *nameSpace, const char *funcName, const char* usage, S32 minArgs, S32 maxArgs)
  273. {
  274. if (!nameSpace || !dStrlen(nameSpace))
  275. Con::addCommand(funcName, cb, usage, minArgs + 1, maxArgs + 1);
  276. else
  277. Con::addCommand(nameSpace, funcName, cb, usage, minArgs + 1, maxArgs + 1);
  278. // example of package support
  279. // note that Parent:: does not work with this, at least not yet anyway
  280. /*
  281. Namespace* ns;
  282. StringTableEntry nspace = NULL;
  283. if (nameSpace && dStrlen(nameSpace))
  284. nspace = StringTable->insert(nameSpace);
  285. Namespace::unlinkPackages();
  286. ns = Namespace::find(nspace, StringTable->insert("fps"));
  287. ns->addCommand(StringTable->insert(funcName), cb, StringTable->insert(usage), minArgs + 1, maxArgs + 1 );
  288. Namespace::relinkPackages();
  289. */
  290. }
  291. void script_export_callback_bool(BoolCallback cb, const char *nameSpace, const char *funcName, const char* usage, S32 minArgs, S32 maxArgs)
  292. {
  293. if (!nameSpace || !dStrlen(nameSpace))
  294. Con::addCommand(funcName, cb, usage, minArgs + 1, maxArgs + 1);
  295. else
  296. Con::addCommand(nameSpace, funcName, cb, usage, minArgs + 1, maxArgs + 1);
  297. }
  298. void script_export_callback_int(IntCallback cb, const char *nameSpace, const char *funcName, const char* usage, S32 minArgs, S32 maxArgs)
  299. {
  300. if (!nameSpace || !dStrlen(nameSpace))
  301. Con::addCommand(funcName, cb, usage, minArgs + 1, maxArgs + 1);
  302. else
  303. Con::addCommand(nameSpace, funcName, cb, usage, minArgs + 1, maxArgs + 1);
  304. }
  305. void script_export_callback_float(FloatCallback cb, const char *nameSpace, const char *funcName, const char* usage, S32 minArgs, S32 maxArgs)
  306. {
  307. if (!nameSpace || !dStrlen(nameSpace))
  308. Con::addCommand(funcName, cb, usage, minArgs + 1, maxArgs + 1);
  309. else
  310. Con::addCommand(nameSpace, funcName, cb, usage, minArgs + 1, maxArgs + 1);
  311. }
  312. #ifdef TORQUE_OS_WIN
  313. void script_input_event(S32 type, S32 value1, S32 value2)
  314. {
  315. if (PlatformWindowManager::get() && PlatformWindowManager::get()->getFirstWindow())
  316. {
  317. Win32Window* w = (Win32Window*) PlatformWindowManager::get()->getFirstWindow();
  318. WindowId devId = w->getWindowId();
  319. switch (type)
  320. {
  321. case 0:
  322. w->mouseEvent.trigger(devId,0,value1,value2,w->isMouseLocked());
  323. break;
  324. case 1:
  325. if (value2)
  326. w->buttonEvent.trigger(devId,0,IA_MAKE,value1);
  327. else
  328. w->buttonEvent.trigger(devId,0,IA_BREAK,value1);
  329. break;
  330. }
  331. }
  332. }
  333. #endif
  334. }
  335. DefineEngineStringlyVariadicFunction(TestFunction2Args, const char *, 3, 3, "testFunction(arg1, arg2)")
  336. {
  337. return "Return Value";
  338. }