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.

921 lines
24KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCETICE project - Copyright 2009 by Lucio Asnaghi.
  4. JUCETICE is based around the JUCE library - "Jules' Utility Class Extensions"
  5. Copyright 2007 by Julian Storer.
  6. ------------------------------------------------------------------------------
  7. JUCE and JUCETICE can be redistributed and/or modified under the terms of
  8. the GNU General Public License, as published by the Free Software Foundation;
  9. either version 2 of the License, or (at your option) any later version.
  10. JUCE and JUCETICE are distributed in the hope that they will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with JUCE and JUCETICE; if not, visit www.gnu.org/licenses or write to
  16. Free Software Foundation, Inc., 59 Temple Place, Suite 330,
  17. Boston, MA 02111-1307 USA
  18. ==============================================================================
  19. */
  20. #if JUCE_SUPPORT_SCRIPTING
  21. #if JUCE_WIN32
  22. #undef T
  23. #undef GetObject
  24. #endif
  25. namespace angelscriptNamespace
  26. {
  27. #if JUCETICE_INCLUDE_ANGELSCRIPT_CODE
  28. #include "../dependancies/angelscript/include/angelscript.h"
  29. #include "../dependancies/angelscript/source/as_arrayobject.cpp"
  30. #include "../dependancies/angelscript/source/as_atomic.cpp"
  31. #include "../dependancies/angelscript/source/as_builder.cpp"
  32. #include "../dependancies/angelscript/source/as_bytecode.cpp"
  33. #include "../dependancies/angelscript/source/as_callfunc.cpp"
  34. #include "../dependancies/angelscript/source/as_callfunc_arm.cpp"
  35. #include "../dependancies/angelscript/source/as_callfunc_mips.cpp"
  36. #include "../dependancies/angelscript/source/as_callfunc_ppc_64.cpp"
  37. #include "../dependancies/angelscript/source/as_callfunc_ppc.cpp"
  38. #include "../dependancies/angelscript/source/as_callfunc_sh4.cpp"
  39. #include "../dependancies/angelscript/source/as_callfunc_x64_gcc.cpp"
  40. #include "../dependancies/angelscript/source/as_callfunc_x86.cpp"
  41. #include "../dependancies/angelscript/source/as_callfunc_xenon.cpp"
  42. #include "../dependancies/angelscript/source/as_compiler.cpp"
  43. #include "../dependancies/angelscript/source/as_configgroup.cpp"
  44. #include "../dependancies/angelscript/source/as_context.cpp"
  45. #include "../dependancies/angelscript/source/as_datatype.cpp"
  46. #include "../dependancies/angelscript/source/as_gc.cpp"
  47. #include "../dependancies/angelscript/source/as_generic.cpp"
  48. #include "../dependancies/angelscript/source/as_memory.cpp"
  49. #include "../dependancies/angelscript/source/as_module.cpp"
  50. #include "../dependancies/angelscript/source/as_objecttype.cpp"
  51. #include "../dependancies/angelscript/source/as_outputbuffer.cpp"
  52. #include "../dependancies/angelscript/source/as_parser.cpp"
  53. #include "../dependancies/angelscript/source/as_restore.cpp"
  54. #include "../dependancies/angelscript/source/as_scriptcode.cpp"
  55. #include "../dependancies/angelscript/source/as_scriptengine.cpp"
  56. #include "../dependancies/angelscript/source/as_scriptfunction.cpp"
  57. #include "../dependancies/angelscript/source/as_scriptnode.cpp"
  58. #include "../dependancies/angelscript/source/as_scriptstruct.cpp"
  59. #include "../dependancies/angelscript/source/as_string.cpp"
  60. #include "../dependancies/angelscript/source/as_string_util.cpp"
  61. #include "../dependancies/angelscript/source/as_thread.cpp"
  62. #include "../dependancies/angelscript/source/as_tokenizer.cpp"
  63. #include "../dependancies/angelscript/source/as_typeinfo.cpp"
  64. #include "../dependancies/angelscript/source/as_variablescope.cpp"
  65. #else
  66. #include <angelscript.h>
  67. #endif
  68. }
  69. #if JUCE_WIN32
  70. #define T(stringLiteral) JUCE_T(stringLiteral)
  71. #ifdef UNICODE
  72. #define GetObject GetObjectW
  73. #else
  74. #define GetObject GetObjectA
  75. #endif // !UNICODE
  76. #endif
  77. BEGIN_JUCE_NAMESPACE
  78. #include "bindings/jucetice_ScriptableEngineString.h"
  79. #include "bindings/jucetice_ScriptableEngineCore.h"
  80. using namespace angelscriptNamespace;
  81. //==============================================================================
  82. void ScriptableEngineMessageCallback (asSMessageInfo* msg, ScriptableEngine* engine)
  83. {
  84. String msgType = "Unknown";
  85. switch (msg->type) {
  86. case asMSGTYPE_ERROR: msgType = "Error"; break;
  87. case asMSGTYPE_WARNING: msgType = "Warning"; break;
  88. case asMSGTYPE_INFORMATION: msgType = "Info"; break;
  89. }
  90. if (engine)
  91. engine->printErrorMessage (msgType, msg->message, msg->section, msg->row);
  92. }
  93. void ScriptableEngineLineCallback (asIScriptContext* context, ScriptableEngine* engine)
  94. {
  95. #if 0
  96. // If the time out is reached we suspend the script
  97. if (script->timeOut < Time::currentTimeMillis())
  98. context->Suspend();
  99. #endif
  100. }
  101. //==============================================================================
  102. ScriptableEngine::ScriptableEngine()
  103. : engine (0),
  104. status (Invalid)
  105. {
  106. initialise ();
  107. }
  108. ScriptableEngine::~ScriptableEngine()
  109. {
  110. shutdown ();
  111. }
  112. void ScriptableEngine::initialise ()
  113. {
  114. // creates the engine
  115. asIScriptEngine* currentEngine = asCreateScriptEngine (ANGELSCRIPT_VERSION);
  116. if (currentEngine != 0)
  117. {
  118. // now dispose the current engine
  119. shutdown ();
  120. engine = currentEngine;
  121. // set the common compiler message handler
  122. currentEngine->SetMessageCallback (asFUNCTION (ScriptableEngineMessageCallback), currentEngine, asCALL_THISCALL);
  123. // set engine properties
  124. currentEngine->SetEngineProperty (asEP_ALLOW_UNSAFE_REFERENCES, 1);
  125. // register extensions
  126. Bindings::RegisterObjectTypeString (this);
  127. Bindings::RegisterObjectTypeCore (this);
  128. // engine status created
  129. status = Ready;
  130. }
  131. }
  132. void ScriptableEngine::shutdown ()
  133. {
  134. if (engine)
  135. {
  136. ((asIScriptEngine*) engine)->Release();
  137. engine = 0;
  138. }
  139. status = Invalid;
  140. }
  141. void ScriptableEngine::printErrorMessage (const String& type,
  142. const String& message,
  143. const String& section,
  144. const int lineNumber)
  145. {
  146. printf ("%s: section %s %d - %s",
  147. (const char*) type,
  148. (const char*) section,
  149. lineNumber,
  150. (const char*) message);
  151. }
  152. void ScriptableEngine::executeScript (const String& script)
  153. {
  154. asIScriptEngine* currentEngine = (asIScriptEngine*) engine;
  155. if (currentEngine != 0 && status != Invalid)
  156. {
  157. int r, func_id;
  158. // create the module
  159. asIScriptModule* module = currentEngine->GetModule (0, asGM_CREATE_IF_NOT_EXISTS);
  160. r = module->AddScriptSection ("script", (const char*) script, script.length()); jassert (r >= 0);
  161. r = module->Build(); jassert (r >= 0);
  162. func_id = module->GetFunctionIdByName ("main"); jassert (func_id >= 0);
  163. asIScriptContext* context = currentEngine->CreateContext();
  164. if (context != 0)
  165. {
  166. if (r >= 0)
  167. {
  168. r = context->Prepare (func_id); jassert (r >= 0);
  169. r = context->Execute (); jassert (r >= 0);
  170. }
  171. context->Release();
  172. context = 0;
  173. currentEngine->GarbageCollect (asGC_FULL_CYCLE);
  174. }
  175. }
  176. }
  177. bool ScriptableEngine::compileScript (const String& scriptCode)
  178. {
  179. asIScriptEngine* currentEngine = (asIScriptEngine*) engine;
  180. if (currentEngine != 0 && status != Invalid)
  181. {
  182. int r;
  183. // remove carriage returns if any...
  184. String scriptCodeProcessed = scriptCode.replaceCharacter('\r','\n');
  185. scriptCodeProcessed += T(' '); // hack if the script is empty
  186. // create the module
  187. asIScriptModule* module = currentEngine->GetModule (0, asGM_CREATE_IF_NOT_EXISTS);
  188. // add a script section
  189. r = module->AddScriptSection ("main", (const char*) scriptCodeProcessed, scriptCodeProcessed.length());
  190. if (r < 0)
  191. return false;
  192. // build the script
  193. r = module->Build();
  194. if (r < 0)
  195. return false;
  196. status = Compiled;
  197. return true;
  198. }
  199. return false;
  200. }
  201. void ScriptableEngine::executeFunction (const String& functionName)
  202. {
  203. asIScriptEngine* currentEngine = (asIScriptEngine*) engine;
  204. if (currentEngine != 0 && status == Compiled)
  205. {
  206. int r, func_id;
  207. // get the module
  208. asIScriptModule* module = currentEngine->GetModule (0, asGM_CREATE_IF_NOT_EXISTS);
  209. // get the function to execute
  210. func_id = module->GetFunctionIdByName ((const char*) functionName); jassert (func_id >= 0);
  211. if (func_id < 0)
  212. {
  213. printErrorMessage ("Runtime", String("Cannot find function ") + functionName, "", -1);
  214. return;
  215. }
  216. // creates the context
  217. asIScriptContext* context = currentEngine->CreateContext();
  218. if (! context)
  219. {
  220. printErrorMessage ("Runtime", "Cannot create context for execution", "", -1);
  221. return;
  222. }
  223. r = context->SetLineCallback (asFUNCTION(ScriptableEngineLineCallback), this, asCALL_CDECL);
  224. r = context->Prepare (func_id);
  225. if (r < 0)
  226. {
  227. printErrorMessage ("Runtime", "Cannot prepare function ececution", "", -1);
  228. return;
  229. }
  230. status = Running;
  231. bool abortScript = false;
  232. bool exitLoop = false;
  233. while (! abortScript)
  234. {
  235. try
  236. {
  237. int timeOut = Time::getMillisecondCounter() + 100; // 100
  238. r = context->Execute();
  239. }
  240. catch(...)
  241. {
  242. r = asEXECUTION_EXCEPTION;
  243. }
  244. switch (r)
  245. {
  246. case asEXECUTION_FINISHED:
  247. {
  248. exitLoop = true;
  249. break;
  250. }
  251. case asEXECUTION_SUSPENDED:
  252. {
  253. MessageManager::getInstance()->runDispatchLoopUntil (250);
  254. break;
  255. }
  256. case asEXECUTION_ABORTED:
  257. {
  258. printErrorMessage ("Exception",
  259. "The script has timed out.",
  260. "", // TODO
  261. context->GetExceptionLineNumber());
  262. exitLoop = true;
  263. break;
  264. }
  265. case asEXECUTION_EXCEPTION:
  266. {
  267. printErrorMessage ("Exception",
  268. context->GetExceptionString(),
  269. "", // TODO
  270. context->GetExceptionLineNumber());
  271. exitLoop = true;
  272. break;
  273. }
  274. }
  275. if (exitLoop)
  276. break;
  277. }
  278. context->Release();
  279. context = 0;
  280. status = Compiled;
  281. }
  282. /*
  283. // Retrieve the return value from the context
  284. float returnValue = context->GetReturnFloat();
  285. cout << "The script function returned: " << returnValue << endl;
  286. returnValue = true;
  287. */
  288. }
  289. #if 0
  290. //==============================================================================
  291. class ScriptableCompilerStream
  292. {
  293. public:
  294. ScriptableCompilerStream (ScriptableEngine* const engine_) :
  295. engine (engine_)
  296. {}
  297. void Write (asSMessageInfo* msg)
  298. {
  299. String msgType = "Unknown";
  300. if (msg->type == asEMsgType::asMSGTYPE_ERROR) msgType = "Error";
  301. if (msg->type == asEMsgType::asMSGTYPE_WARNING) msgType = "Warning";
  302. if (msg->type == asEMsgType::asMSGTYPE_INFORMATION) msgType = "Info";
  303. String file (msg->section);
  304. int line = msg->row;
  305. switch (msg->type)
  306. {
  307. case asEMsgType::asMSGTYPE_ERROR:
  308. engine->engineModel->reportErrors (msgType, msg->message, file, line);
  309. break;
  310. case asEMsgType::asMSGTYPE_WARNING:
  311. case asEMsgType::asMSGTYPE_INFORMATION:
  312. if (engine->warningsOn)
  313. engine->engineModel->reportErrors (msgType, msg->message, file, line);
  314. break;
  315. }
  316. }
  317. private:
  318. ScriptableEngine* engine;
  319. };
  320. //==============================================================================
  321. class ScriptableByteCodeInStream : public asIBinaryStream
  322. {
  323. public:
  324. ScriptableByteCodeInStream (ScriptableEngine* compiler_,
  325. const File& byteCodeFile_) :
  326. compiler (compiler_),
  327. byteCodeFile (byteCodeFile_)
  328. {
  329. in = byteCodeFile.createInputStream();
  330. }
  331. ~ScriptableByteCodeInStream () {
  332. delete in;
  333. }
  334. void Write (const void *ptr, asUINT size) {}
  335. void Read (void *ptr, asUINT size) {
  336. in->read (ptr, size);
  337. }
  338. private:
  339. ScriptableEngine* compiler;
  340. FileInputStream* in;
  341. File byteCodeFile;
  342. };
  343. class ScriptableByteCodeOutStream : public asIBinaryStream
  344. {
  345. public:
  346. ScriptableByteCodeOutStream (ScriptableEngine* compiler_,
  347. const File& byteCodeFile_) :
  348. compiler (compiler_),
  349. byteCodeFile (byteCodeFile_)
  350. {
  351. out = byteCodeFile.createOutputStream();
  352. }
  353. ~ScriptableByteCodeOutStream () {
  354. delete out;
  355. }
  356. void Read (void *ptr, asUINT size) {}
  357. void Write (const void *ptr, asUINT size) {
  358. out->write (ptr, size);
  359. }
  360. private:
  361. ScriptableEngine* compiler;
  362. FileOutputStream* out;
  363. File byteCodeFile;
  364. };
  365. //==============================================================================
  366. /*
  367. String PrintVariables (asIScriptContext *ctx, int stackLevel)
  368. {
  369. String error;
  370. int numVars = ctx->GetVarCount(stackLevel);
  371. asIScriptEngine *engine = ctx->GetEngine();
  372. for( int n = 0; n < numVars; n++ )
  373. {
  374. int typeId = ctx->GetVarTypeId(n, stackLevel);
  375. if( typeId == engine->GetTypeIdByDecl(0, "int") )
  376. {
  377. error << ctx->GetVarDeclaration(n, 0, stackLevel)
  378. << " " << *(int*)ctx->GetVarPointer(n, stackLevel) << "\n";
  379. }
  380. else if( typeId == engine->GetTypeIdByDecl(0, "String") )
  381. {
  382. error << ctx->GetVarDeclaration(n, 0, stackLevel)
  383. << " " << (const char*) ((*(asString**)ctx->GetVarPointer(n, stackLevel))->buffer);
  384. }
  385. }
  386. return error;
  387. }
  388. void ScriptableExceptionCallback (asIScriptContext *context, void *param)
  389. {
  390. ScriptableEngine* script = (ScriptableEngine*) param;
  391. asIScriptEngine *engine = context->GetEngine();
  392. int funcID = context->GetExceptionFunction();
  393. String error = "Exception: ";
  394. error
  395. << context->GetExceptionString() << "\n"
  396. << engine->GetFunctionDeclaration(funcID) << "\n";
  397. error += PrintVariables (context, -1);
  398. error += "\n";
  399. for( int n = 0; n < context->GetCallstackSize(); n++ )
  400. {
  401. funcID = context->GetCallstackFunction (n);
  402. error += engine->GetFunctionDeclaration(funcID);
  403. error += "\n";
  404. error += PrintVariables (context, n);
  405. error += "\n";
  406. }
  407. if (script->engineModel)
  408. script->engineModel->reportErrors ("runtime", error);
  409. }
  410. */
  411. //==============================================================================
  412. void ScriptableDebuggerOutput (const char* message, const int appendMode)
  413. {
  414. ScriptableEngine* script = ScriptableEngine::getInstance();
  415. if (script && script->engineModel)
  416. {
  417. script->engineModel->reportOutput (message, appendMode);
  418. }
  419. }
  420. //==============================================================================
  421. void ScriptableLineCallback (asIScriptContext* context, ScriptableEngine* script)
  422. {
  423. // If the time out is reached we suspend the script
  424. if( script->timeOut < Time::currentTimeMillis() )
  425. context->Suspend();
  426. }
  427. void ScriptableLineCallbackDebug (asIScriptContext* context, ScriptableEngine* script)
  428. {
  429. if (script->engineModel)
  430. script->engineModel->debugLineCallback (script, context);
  431. context->Suspend();
  432. }
  433. //==============================================================================
  434. ScriptableEngine::ScriptableEngine() :
  435. timeOut (0),
  436. debugMode (false),
  437. warningsOn (true),
  438. preprocessFailed (false),
  439. compileFailed (false),
  440. runningScript (false),
  441. abortScript (false),
  442. continueSilently (false),
  443. outStreamPreprocessor (0),
  444. outStream (0),
  445. engineModel (0),
  446. engine (0)
  447. {
  448. // creates the engine
  449. engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
  450. if( engine == 0 )
  451. {
  452. return;
  453. }
  454. // set the common compiler message handler
  455. outStream = new ScriptableCompilerStream (this);
  456. engine->SetMessageCallback (asMETHOD(ScriptableCompilerStream,Write), outStream, asCALL_THISCALL);
  457. // set engine properties
  458. engine->SetEngineProperty (asEP_ALLOW_UNSAFE_REFERENCES, 1);
  459. // add some predefined resolvePaths
  460. // resolvePaths.add ( File::getCurrentWorkingDirectory().getFullPathName() );
  461. // resolvePaths.add ( File::getCurrentApplicationFile().getParentDirectory().getFullPathName() );
  462. }
  463. ScriptableEngine::~ScriptableEngine()
  464. {
  465. if (engine)
  466. engine->Release();
  467. if (outStream)
  468. delete (ScriptableCompilerStream*) outStream;
  469. }
  470. //==============================================================================
  471. void ScriptableEngine::resetEngine ()
  472. {
  473. // release the engine
  474. if (engine)
  475. engine->Release ();
  476. if (outStream)
  477. delete (ScriptableCompilerStream*) outStream;
  478. // recreates the engine
  479. engine = asCreateScriptEngine (ANGELSCRIPT_VERSION);
  480. if( engine == 0 )
  481. return;
  482. outStream = new ScriptableCompilerStream (this);
  483. engine->SetMessageCallback (asMETHOD(ScriptableCompilerStream,Write), outStream, asCALL_THISCALL);
  484. debugMode = false;
  485. runningScript = false;
  486. abortScript = false;
  487. continueSilently = false;
  488. preprocessFailed = false;
  489. compileFailed = false;
  490. }
  491. //==============================================================================
  492. void ScriptableEngine::setDefaultContextStackSize (const int initialSize, const int maxSize)
  493. {
  494. engine->SetDefaultContextStackSize (initialSize, maxSize);
  495. }
  496. //==============================================================================
  497. void ScriptableEngine::registerGlobalProperty(const String& declaration, void* object)
  498. {
  499. engine->RegisterGlobalProperty ((const char*)declaration,object);
  500. }
  501. //==============================================================================
  502. bool ScriptableEngine::compileScript (const String& strScript, const String& strSection)
  503. {
  504. jassert (engine != 0);
  505. compileFailed = false;
  506. // do garbage collect
  507. engine->GarbageCollect (true);
  508. // remove carriage returns if any...
  509. String preScript = strScript.replaceCharacter('\r','\n');
  510. preScript += T(' '); // hack if the script is empty
  511. // call the pre compiler callback
  512. preCompileCallback ();
  513. // add a script section
  514. int r = engine->AddScriptSection (0, (const char*) strSection, (const char*) strScript, outVector.size(), 0);
  515. if (r < 0)
  516. {
  517. compileFailed = true;
  518. return false;
  519. }
  520. // build the script
  521. r = engine->Build (0);
  522. if (r < 0)
  523. {
  524. compileFailed = true;
  525. return false;
  526. }
  527. return true;
  528. }
  529. //==============================================================================
  530. asIScriptContext* ScriptableEngine::createContext()
  531. {
  532. asIScriptContext* context = engine->CreateContext();
  533. if( context != 0 )
  534. {
  535. int r;
  536. if (debugMode)
  537. r = context->SetLineCallback (asFUNCTION(ScriptableLineCallbackDebug), this, asCALL_CDECL);
  538. else
  539. r = context->SetLineCallback (asFUNCTION(ScriptableLineCallback), this, asCALL_CDECL);
  540. if (r < 0)
  541. {
  542. context->Release();
  543. context = 0;
  544. }
  545. }
  546. return context;
  547. }
  548. //==============================================================================
  549. bool ScriptableEngine::executeFunction (const String& strFunction)
  550. {
  551. jassert (engine != 0);
  552. if (compileFailed)
  553. return false;
  554. // get the function to execute
  555. int functionID = engine->GetFunctionIDByName(0, (const char*) strFunction);
  556. if (functionID < 0)
  557. {
  558. reportErrors ("runtime", String("Cannot find function ") + strFunction, "", -1);
  559. return false;
  560. }
  561. // creates the context
  562. asIScriptContext* context = createContext();
  563. if (context == 0)
  564. {
  565. reportErrors ("runtime", "Cannot create context for execution", "", -1);
  566. return false;
  567. }
  568. // prepare the function
  569. int r = context->Prepare (functionID);
  570. if (r < 0)
  571. {
  572. reportErrors ("runtime", "Cannot prepare function ececution", "", -1);
  573. return false;
  574. }
  575. bool returnValue = false;
  576. bool exitLoop = false;
  577. runningScript = true;
  578. abortScript = false;
  579. continueSilently = true;
  580. while (!abortScript)
  581. {
  582. // try
  583. {
  584. timeOut = Time::getMillisecondCounter() + 100; // 100
  585. r = context->Execute();
  586. }
  587. // catch(...)
  588. // {
  589. // r = asEXECUTION_EXCEPTION;
  590. // }
  591. switch(r)
  592. {
  593. case asEXECUTION_FINISHED:
  594. {
  595. returnValue = true;
  596. exitLoop = true;
  597. break;
  598. }
  599. case asEXECUTION_SUSPENDED:
  600. {
  601. MessageManager::getInstance()->dispatchPendingMessages ();
  602. break;
  603. }
  604. case asEXECUTION_ABORTED:
  605. {
  606. reportErrors ("Exception",
  607. "The script has timed out.",
  608. resolveOriginalFile (context->GetExceptionLineNumber()),
  609. context->GetExceptionLineNumber());
  610. exitLoop = true;
  611. break;
  612. }
  613. case asEXECUTION_EXCEPTION:
  614. {
  615. int funcID = context->GetExceptionFunction();
  616. engineModel->reportErrors ("Exception",
  617. resolveFunctionDeclaration (funcID) + " : " +context->GetExceptionString(),
  618. resolveOriginalFile (context->GetExceptionLineNumber()),
  619. resolveOriginalLine (context->GetExceptionLineNumber()) );
  620. exitLoop = true;
  621. break;
  622. }
  623. default:
  624. exitLoop = true;
  625. break;
  626. }
  627. if (exitLoop)
  628. break;
  629. }
  630. /*
  631. // Retrieve the return value from the context
  632. float returnValue = context->GetReturnFloat();
  633. cout << "The script function returned: " << returnValue << endl;
  634. returnValue = true;
  635. */
  636. context->Release();
  637. runningScript = false;
  638. return returnValue;
  639. }
  640. bool ScriptableEngine::executeString (const String& strScript)
  641. {
  642. if (!engine)
  643. return false;
  644. int r = engine->ExecuteString (0, (const char*)strScript);
  645. if( r < 0 )
  646. {
  647. return false;
  648. }
  649. return true;
  650. }
  651. //==============================================================================
  652. void ScriptableEngine::abortExecution ()
  653. {
  654. // @XXX - hack for the component bindings
  655. asComponentManager::getInstance()->releaseComponents();
  656. abortScript = true;
  657. }
  658. void ScriptableEngine::continueExecution ()
  659. {
  660. continueSilently = true;
  661. }
  662. //==============================================================================
  663. int ScriptableEngine::resolveOriginalLine (const int lineNumber)
  664. {
  665. return lineTranslator.ResolveOriginalLine (lineNumber);
  666. }
  667. String ScriptableEngine::resolveOriginalFile (const int lineNumber)
  668. {
  669. return String ((const char*) lineTranslator.ResolveOriginalFile (lineNumber).c_str());
  670. }
  671. String ScriptableEngine::resolveFunctionDeclaration (const int functionID)
  672. {
  673. return String (engine->GetFunctionDeclaration (functionID));
  674. }
  675. String ScriptableEngine::serializeVariable (asIScriptContext* context, const int variableNumber)
  676. {
  677. void* varPointer = context->GetVarPointer (variableNumber);
  678. int typeID = context->GetVarTypeId (variableNumber);
  679. String typeDecl = engine->GetTypeDeclaration (typeID);
  680. if (typeDecl == "bool")
  681. {
  682. return String ((int)*(bool*)(varPointer));
  683. }
  684. else if (typeDecl == "int8" ||
  685. typeDecl == "int16" ||
  686. typeDecl == "int32" ||
  687. typeDecl == "int")
  688. {
  689. return String (*(int*)(varPointer));
  690. }
  691. else if (typeDecl == "uint8" ||
  692. typeDecl == "uint16" ||
  693. typeDecl == "uint32" ||
  694. typeDecl == "uint")
  695. {
  696. return String ((int)*(unsigned int*)(varPointer));
  697. }
  698. else if (typeDecl == "float")
  699. {
  700. return String (*(float*)(varPointer));
  701. }
  702. else if (typeDecl == "double")
  703. {
  704. return String (*(double*)(varPointer));
  705. }
  706. else
  707. {
  708. /*
  709. char* buffer = 0;
  710. for (int i=0; i<plugins.size(); i++)
  711. {
  712. ScriptableExtensionModel* plug =
  713. (ScriptableExtensionModel*) plugins.getUnchecked (i);
  714. buffer = plug->variableCallback (engine, typeID, varPointer);
  715. if (buffer != 0)
  716. {
  717. String varValue = buffer;
  718. free (buffer);
  719. return varValue;
  720. }
  721. }
  722. */
  723. }
  724. return "???";
  725. }
  726. //==============================================================================
  727. void ScriptableEngine::addResolveFilePath (const File& directoryToLookInto)
  728. {
  729. jassert (!directoryToLookInto.exists());
  730. if (directoryToLookInto.existsAsFile())
  731. resolvePaths.add (directoryToLookInto.getParentDirectory().getFullPathName());
  732. else
  733. resolvePaths.add (directoryToLookInto.getFullPathName());
  734. }
  735. void ScriptableEngine::removeResolveFilePath (const File& directoryToLookInto)
  736. {
  737. jassert (! directoryToLookInto.exists());
  738. if (directoryToLookInto.existsAsFile())
  739. resolvePaths.removeString (directoryToLookInto.getParentDirectory().getFullPathName());
  740. else
  741. resolvePaths.removeString (directoryToLookInto.getFullPathName());
  742. }
  743. File ScriptableEngine::findResolveFilePaths (const String& fileName)
  744. {
  745. File fileFound;
  746. int pathToResolve = resolvePaths.size();
  747. for (int i=0; i<pathToResolve; i++)
  748. {
  749. String filePath = resolvePaths [i];
  750. filePath << "\\" << fileName;
  751. File fileToLoad (filePath);
  752. if (fileToLoad.existsAsFile())
  753. {
  754. fileFound = fileToLoad;
  755. break;
  756. }
  757. }
  758. return fileFound;
  759. }
  760. #endif
  761. END_JUCE_NAMESPACE
  762. #endif // JUCE_SUPPORT_SCRIPTING