Advertisement

Build() hangs

Started by July 26, 2007 07:57 PM
6 comments, last by WitchLord 17 years, 4 months ago
I'm trying to type up my own version of the "tutorial" sample code, and everything seems to be working fine except that the call to Build(0) seems to hang. It's not returning any values or anything, and the program isn't timing out. Any suggestions as to what this could be? Thanks.
That has never happened to me before. Can you show me the application code and script that your using?

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

Advertisement
It's probably a stupid noob error, so before I paste the whole thing, I'll paste the section that holds the script and adds a script section, as it differs from the tutorial sample and perhaps I've done it wrong:

char code[] = "float calc(float x, float y) { Print(\"GOT THESE NUMBERS: \" + x + \", \" + y + \"\n\"); return x*y; }";      r = engine->AddScriptSection(0, "script", code, strlen(code), 0, false);   if (r < 0)   {      cout << "Failed add script section." << endl;   }      r = engine->Build(0);   if (r < 0)   {      cout << "Failed build." << endl;   }


Is this valid? If this code is fine, I'll go ahead and paste the whole thing if you want. Again, this Build() call is the one that hangs... adding a else { cout << "Build successful!" << endl; } proves that nothing is returned, as it will still not print anything.
There is no apparent error in your code.

Have you tried debugging the code to see where it hangs inside Build()?

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

I've traced it down to this while block in asCParser::SuperficiallyParseStatementBlock():
	int level = 1;	while( level > 0 && !isSyntaxError )	{		GetToken(&t1);		if( t1.type == ttEndStatementBlock )			level--;		else if( t1.type == ttStartStatementBlock )			level++;		else if( t1.type == ttEnd )			Error(TXT_UNEXPECTED_END_OF_FILE, &t1);	}


It would appear that an infinite loop is formed: GetToken continually makes t1.type = ttNonTerminatedStringConstant, and so the loop never exits. This seems like a pretty heavy problem for such a simple script, so I'm thinking that I just made a stupid mistake in my own code. I'll go ahead and paste that. Some notes first: this is being compiled on Windows XP; any lines that print "here!" or "here2!" are simply for debugging purposes, ignore them.

#define _CRT_SECURE_NO_DEPRECATE#include <iostream>#include <assert.h>#include <conio.h>#include <windows.h>#include "angelscript.h"#include "scriptstring.h"using namespace std;int RunApplication();void ConfigureEngine(asIScriptEngine *engine);int CompileScript(asIScriptEngine *engine);void PrintString(string &str);void LineCallback(asIScriptContext *ctx, DWORD *timeOut);int main (int argc, char **argv){   RunApplication();      cout << endl << "Press any key to quit." << endl;   while (!getch());      return 0;}void MessageCallback(const asSMessageInfo *msg, void *param){   const char *type = "ERR ";   if (msg->type == asMSGTYPE_WARNING)      type = "WARN";   else if (msg->type == asMSGTYPE_INFORMATION)      type = "INFO";      printf("%s (%d, %d) : %s : %s\n", msg->section, msg->row, msg->col, type, msg->message);}int RunApplication(){   int r;      // create the script engine   asIScriptEngine *engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);   if (engine == 0)   {      cout << "Failed to create script engine." << endl;      return -1;   }      // set callback for compile errors   engine->SetMessageCallback(asFUNCTION(MessageCallback), 0, asCALL_CDECL);   // config the engine   ConfigureEngine(engine);      // compile the script   r = CompileScript(engine);   if (r < 0)   {      cout << "Failed to compile." << endl;      engine->Release();      return -1;   }      // create a context for the script's execution   asIScriptContext *ctx = engine->CreateContext();   if (ctx == 0)   {      cout << "Failed to create the context." << endl;      engine->Release();      return -1;   }      // set a timeout   DWORD timeOut;   r = ctx->SetLineCallback(asFUNCTION(LineCallback), &timeOut, asCALL_CDECL);   if (r < 0)   {      cout << "Failed to set the line callback function." << endl;      ctx->Release();      engine->Release();      return -1;   }      // find the function id for the function we want to call   int funcId = engine->GetFunctionIDByDecl(0, "float calc(float, float)");   if (funcId < 0)   {      cout << "The function was not found." << endl;      ctx->Release();      engine->Release();      return -1;   }      // prepare the context to execute the function   r = ctx->Prepare(funcId);   if (r < 0)   {      cout << "Failed to prepare the context." << endl;      ctx->Release();      engine->Release();      return -1;   }      // pass the params in   ctx->SetArgFloat(0, 2.0f);   ctx->SetArgFloat(0, 6.0f);      // set the timeout   timeOut = timeGetTime() + 1000;      // execute the function   cout << "Executing the script." << endl;   r = ctx->Execute();      if (r == asEXECUTION_FINISHED)   {      // retrieve the value      float returnValue = ctx->GetReturnFloat();      cout << "Returned: " << returnValue << endl;   }   else   {      cout << "Failed execution." << endl;   }      ctx->Release();   engine->Release();      return 0;}void ConfigureEngine(asIScriptEngine *engine){   int r;      RegisterScriptString(engine);      r = engine->RegisterGlobalFunction("void Print(string &str)", asFUNCTION(PrintString), asCALL_CDECL); assert (r >= 0);   }int CompileScript(asIScriptEngine *engine){   int r;      cout << "here!" << endl;      char code[] = "float calc(float x, float y) { Print(\"GOT THESE NUMBERS: \" + x + \", \" + y + \"\n\"); return x*y; }";      r = engine->AddScriptSection(0, "script", code, strlen(code), 0, false);   if (r < 0)   {      cout << "Failed add script section." << endl;   }      cout << "here2!" << endl;      r = engine->Build(0);   if (r < 0)   {      cout << "Failed build." << endl;   }   else   {      cout << "IDksldjf" << endl;   }      cout << "here3!" << endl;      return 0;}void LineCallback(asIScriptContext *ctx, DWORD *timeOut){   if (*timeOut < timeGetTime())   {      ctx->Abort();      cout << "timed out" << endl;   }}void PrintString(string &str){   cout << str;}


Thanks!
Hi, I've never used AngelScript myself so this is just a quick guess, but it looks like this newline in code[] should be '\\n' instead of '\n'.
Advertisement
Quote: Original post by akluzz
Hi, I've never used AngelScript myself so this is just a quick guess, but it looks like this newline in code[] should be '\\n' instead of '\n'.


Guess what? That totally fixed it. Thank you so much. I knew it had to be some stupid typo or something. Thank you too, WitchLord, for taking time to try and help me. Now I can get on with getting to know AS better (I'll no doubt be posting some more ;) ).

Thanks again guys! =)
I'm glad you found the problem. I'll have to fix AngelScript so that incorrect scripts like this won't cause infinite loops in the future again.

Regards,
Andreas

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

This topic is closed to new replies.

Advertisement