#include <iostream>
#include <string>
#pragma comment(lib, "angelscriptd.lib")
#include "angelscript.h"
int i;
void print(char c)
{
std::cout << "print()" << c << std::endl;
}
int main()
{
asIScriptEngine *engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
if(engine == 0)
{
std::cout << "Failed to create script engine\n";
return -1;
}
engine->RegisterGlobalProperty("int i", &i);
engine->RegisterGlobalFunction("void print(char)", asFUNCTION(print), asCALL_CDECL);
std::string input;
for(;;)
{
std::cin >> input;
if(input == "q")
break;
int r = engine->ExecuteString(0, input.c_str());
if(r < 0)
std::cout << "Invalid script statement.\n";
else if(r == asEXECUTION_EXCEPTION)
std::cout << "A script exception was raised.\n";
}
engine->Release();
return 0;
}
🎉 Celebrating 25 Years of GameDev.net! 🎉
Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!
Total beginner exec problems
I've just downloaded angelscript and have tried to make a simple program based on the sample and the documentation.
Here is my code:
As you can see I'm trying to execute whatever is typed into the console. However I always get an "Invalid script statement." error.
I've tried typing many things into the console from i = i + 1; to print("d");. Both with and without the semi-colon (as I don't think it is used in the sample).
Where am I going wrong?
Hi Tera_Dragon,
I'm glad you've decided to try out AngelScript. I'll do my best to make it as easy for you as possible.
You've made a few mistakes, otherwise you seem to have understood how AS works.
This line will return -10 (asINVALID_DECLARATION) as 'char' is an unknown type in AngelScript. Because of this, all subsequent calls to Build() or ExecuteString() will fail, since the engine configuration is invalid. You would have cought this if you had added error checking. I suggest you do it like this:
Instead of char you could use uint8, or int8, but in AngelScript this is a number, not a character.
Once you fix this first error you will soon notice that you can't use strings in the script library, thus print("d") will always fail. This is because AngelScript doesn't have a default string type. If you look at the sample code you'll see a call to RegisterScriptString(), this is where the string type is registered with the engine. Once you add that call, you may change your print() function to the following:
and register it with:
Regards,
Andreas
I'm glad you've decided to try out AngelScript. I'll do my best to make it as easy for you as possible.
You've made a few mistakes, otherwise you seem to have understood how AS works.
engine->RegisterGlobalFunction("void print(char)", asFUNCTION(print), asCALL_CDECL);
This line will return -10 (asINVALID_DECLARATION) as 'char' is an unknown type in AngelScript. Because of this, all subsequent calls to Build() or ExecuteString() will fail, since the engine configuration is invalid. You would have cought this if you had added error checking. I suggest you do it like this:
r = engine->RegisterGlobalFunction("void print(char)", asFUNCTION(print), asCALL_CDECL); assert( r >= 0 );
Instead of char you could use uint8, or int8, but in AngelScript this is a number, not a character.
Once you fix this first error you will soon notice that you can't use strings in the script library, thus print("d") will always fail. This is because AngelScript doesn't have a default string type. If you look at the sample code you'll see a call to RegisterScriptString(), this is where the string type is registered with the engine. Once you add that call, you may change your print() function to the following:
void print(std::string &c){ std::cout << "print()" << c << std::endl;}
and register it with:
r = engine->RegisterGlobalFunction("void print(string ∈)", asFUNCTION(print), asCALL_CDECL); assert( r >= 0 );
Regards,
Andreas
EDIT: Fixed it. I made a typo on the second param for RegisterObjectMethod().
I just spent about an hour on that [bawling]
I'm now having some toruble with making an instance of a class from the script.
I'm using the same code as before (fixed) but have added this before the for loop:
This doesn't give any errors (thanks a lot for telling me about the assert function, it's extremly useful [smile]). But when I try to execute Print p; I get the "Invalid script statement." error.
I have this script:
The error occurs when the engine->Build() is called, and only when the p.output(5); is there.
[Edited by - Tera_Dragon on April 23, 2005 5:38:01 PM]
I just spent about an hour on that [bawling]
I'm now having some toruble with making an instance of a class from the script.
I'm using the same code as before (fixed) but have added this before the for loop:
void RegisterClass(asIScriptEngine *e){ r = e->RegisterObjectType("Printer", sizeof(Printer), asOBJ_CLASS_CD); assert(r>=0); r = e->RegisterObjectBehaviour("Printer", asBEHAVE_CONSTRUCT, "void f()", asFUNCTION(Constructor), asCALL_CDECL_OBJLAST); assert(r>=0); r = e->RegisterObjectBehaviour("Printer", asBEHAVE_DESTRUCT, "void f()", asFUNCTION(Destructor), asCALL_CDECL_OBJLAST); assert(r>=0); r = e->RegisterObjectMethod("Printer", "void ouput(int)", asMETHOD(Printer, output), asCALL_THISCALL); assert(r>=0);}
This doesn't give any errors (thanks a lot for telling me about the assert function, it's extremly useful [smile]). But when I try to execute Print p; I get the "Invalid script statement." error.
I have this script:
void foo(){ Printer p; p.output(5);}
The error occurs when the engine->Build() is called, and only when the p.output(5); is there.
[Edited by - Tera_Dragon on April 23, 2005 5:38:01 PM]
There is no specific character type in AngelScript. I don't think it is necessary. uint8 and int8 are compatible with C++'s unsigned char and char though.
It's great that assert() is helping you out. Another helpful utility is asIOutputStream, with it you'll get specific error messages from the compilation. Here's an example:
It would have showed you that the method "output" wasn't registered.
Regards,
Andreas
It's great that assert() is helping you out. Another helpful utility is asIOutputStream, with it you'll get specific error messages from the compilation. Here's an example:
class asCOutputStream : public asIOutputStream{public: void Write(const char *text) { printf(text); }};...asCOutputStream out;int r = engine->Build(0, &out);orint r = engine->ExecuteString(0, script_string, &out);
It would have showed you that the method "output" wasn't registered.
Regards,
Andreas
Every time you want to execute a script function with asIScriptContext::Execute() do you have to call asIScriptContext::Prepare() first? eg you can't prepare a function and then execute it twice in a row without preparing it again?
You have to call Prepare(), because this reinitializes internal states. You may call Execute() multiple times wihtout Prepare() if the script execution was suspended before it finishes, that would then continue the execution where it last stopped.
If you intend to call the same script functions multiple times, you may use Prepare(-1), which prepares the last function again. It is sligthly faster than Preparing() with a true function ID. Also it might be a good idea to store the function IDs you intend to call instead of using engine->GetFunctionIdByDecl() all the time, since that call is rather expensive.
If you intend to call the same script functions multiple times, you may use Prepare(-1), which prepares the last function again. It is sligthly faster than Preparing() with a true function ID. Also it might be a good idea to store the function IDs you intend to call instead of using engine->GetFunctionIdByDecl() all the time, since that call is rather expensive.
Quote: Original post by WitchLord
You may call Execute() multiple times wihtout Prepare() if the script execution was suspended before it finishes, that would then continue the execution where it last stopped.
When/why would this happen?
It never happens unless the application adds that functionality.
It could for example be an application registered function called from the script that suspends the execution. Or the application could use the line callback functionality to suspend the execution after a timeout, or at a specific line. You could also use a second application thread to suspend the execution of a script.
The execution is suspended with a call to asIScriptContext::Suspend().
It could for example be an application registered function called from the script that suspends the execution. Or the application could use the line callback functionality to suspend the execution after a timeout, or at a specific line. You could also use a second application thread to suspend the execution of a script.
The execution is suspended with a call to asIScriptContext::Suspend().
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement