🎉 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!

Questions

Started by
9 comments, last by SharkBait 19 years, 2 months ago
I found AngelScript a couple days ago; have been toying with it a little. My project is currently using Lua, and AngelScript seems to have some features that make me interested in using it instead. Got a couple questions. 1. Lua is great for configuration/setting type scripts. I can't seem to find any way to execute a script buffer without needing a function aside from ExecuteString(). Is there any way to do this / is it ok to do that with ExecuteString? 2. Registering global properties. Is it safe to work with registered global properties from in the host application? Seems like a dumb question, but I want to make sure. 3. Variable number of arguments. I've read somewhere that AngelScript allows you to define variable number of arguments (or register functions that have them?) but does not directly support this. Is it ok to register a global function that takes a variable number of arguments? Or will this horribly break things. I don't forsee an issue with AngelScript functions having dynamic arguments as I know what I'll be expecting from the function viewpoint. 4. Is it possible to capture error information from a script build without the need for an asIOutputStream? *checks* Okay, I see the exception stuff in asIScriptContext, but nothing for asIScriptEngine. (or it does have a context, and can retrieve it with asGetActiveContext() ?) 5. It seems the bitwise operators are not implemented by default. Is this intended? (No conversion from 'int' to 'bits' available.) Hopefully I havn't jumbled up what i'm trying to ask too much. :)
Advertisement
Fellow user here, but I'll try to save Witchlord from a long post :)

1. Scripts consist of global variable/const declarations and functions. There cannot be any script code outside a function that executes automatically or a main() function that is called automatically as in C, C++ etc. However, global variable assignments *within* the scipt are performed on compilation of the scipt into a module. You can then access the module's global variables using asIScriptEngine::GetGLobalVar...() methods. Alternatively, register global variables and put the assignments in a main() function. Finally, add code to run the main() function if it is present in the module - if you centralise it, you only need to do it once.

2. It depends: If you want to perform some form of validation on the values assigned to registered variables from the script, it is better to expose getter and setter functions to the scipt and use those. This will allow you to validate property values in your setter functions. This is all up to you and your specific requirements really.

3. Not as far as I know.. but I'm not the most qualified to answer this question :)

4. You lost me there.. see (3) But as far as I know, the only way to capture detailed compilation errors is via asIOutputStream. The only other alternative that I know of is the status codes that basically tell you if it is compiled or otherwise.. not very helpful when debugging. I personally resorted to having the compilation output captured in an exception that eventually results in a popup message box.

5. As far as I know, AS doesn't support implicit (and explicit) casting.. best route is to register some casting functions... Witchlord, correct me if I am wrong..
tIDE Tile Map Editorhttp://tide.codeplex.com
Thanks for the help SharkBait.

Here's some more info:

1. Lua is superior in configuring large data structures. AngelScript currently doesn't even have initialization lists to automatically initialize arrays. Still, if it is data structures you wish to initialize then I personally prefer using xml or another file format.

The string passed to ExecuteString() is wrapped inside a function and then compiled as a script and executed. This means that you can declare variables, and execute multiple statements in ExecuteString(). The only thing you can't do is declare global variables, or return values from the function.

2. Yes, it is safe to continue to use the same global properties from within the application. AngelScript stores a reference to the properties, thus any changes made to them from within the application will be visible in the scripts. Just make sure you don't invalidate the pointer, e.g. by deleting the object you registered.

3. The script language doesn't understand the concept of variable number of arguments. But you may register C/C++ functions that take variable number of arguments, but from AngelScript's point of view it will be a fixed number of arguments. Note, that class methods that take a variable number of arguments use a different calling convention than normal class methods, thus will likely crash the application if AngelScript tries to call one of those (global cdecl functions work fine though).

Even though AngelScript can successfully call a C function that expects a variable number of arguments I do not recommend using them. This is because the function usually looks at one of the arguments to determine how many variable arguments there are. It will be difficult to make sure that the arguments that are passed from AngelScript will match what the function expects.

4. Build() returns a negative value if the build failed. But the only way to determine the exact error is by using the asIOutputStream. ExecuteString() also accepts asIOutputStream.

Runtime errors are reported through exceptions. If the context's Execute() return asEXECUTION_EXCEPTION (3) then you may use the context's method to obtain information about this exception.

If you intend to report possible exceptions from ExecuteString() then you need to retrieve the context used by ExecuteString(). ExecuteString() create the context for you and return it in the context parameter, or you can create the context and pass it to ExecuteString() in the context parameter (just set the flag correctly).

5. Bitwise operators are implemented, but a bug prevents you from using them on integer values right now. It seems the implicit type conversions aren't fully working as intended. You can still explicitly convert an int to bits though, e.g. bits(13)>>4.

---

I'm very pleased that you are considering using AngelScript over Lua. AngelScript is still very young and far from complete though, so you will likely find things that Lua does and AngelScript doesn't. If you need something that AS doesn't currently do, feel free to tell me so that I can implement it. Smaller requests are usually implemented quickly, and larger requests are implemented when the development schedule permits it.

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

I've recently had a need for something similar to variable number of arguments.

My way around it was this:

argument that stores the number of arguments passed to the function.
array of void* (or bits in AS) that is passed to the function that contains the actual arguments.

It is obviously not type safe and prone to user error or other oversight but for what i needed it did the job.
Thanks for your replies.

Is there any way to determin the nature of output to asIOutputStream, or is it only used for error output? (when specified in Build())

What exactly is the bits type for? (eg, why doesn't it work directly on int/uint rather than typecasting?)

I (well, in Lua) was using variable number of arguments for easy data sending for TCP. Formats would be registered with the host application and Lua would call them in that format ( send(1,2,"hi") ) and the host application would build the buffer based on the arguments it received. Is it possible to manipulate the stack in AngelScript? (I believe I read AngelScript is stack based?) Or is there a way to enable a function in the host to manipulate the stack?
asIOutputStream is only used during compilation of the scripts and will only report errors and warnings, in the form of text strings. Perhaps I should rename the interface to better reflect its use.

The bits type was introduced mostly for design. Also with this type it is possible to do bitwise conversion from float to int and back. In C++ this is only possible using either a union or doing pointer tricks.

Anyway, since the bits type is implicitly converted to and from int/uint you shouldn't see much difference. The bug that prevented the conversion from int to bits has been fixed and will be available early next week, with 2.1.0b.

Lua's stack works differently from AngelScript's (at least as far as I know) with Lua the type of the value stored on the stack is also dynamically available. This is not so for AngelScript, which would make it potentially disastrous to manipulate the stack directly. However, by using the calling convention asCALL_GENERIC, your application function receives an asIScriptGeneric pointer, that allows you to query the values on the stack. Using this calling convention you could register more than one script function using the same application function, which would then examine the arguments to determine what to do. Still, it is not as flexible as Lua, and I really don't recommend it.

Can you show me with an example why you believe it is so important to have functions with variable arguments? If you can convince me that it really is important, maybe I will put in the effort to add support for it in AngelScript.

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

Right now I am only using it for sockets...

It allows me to have a generic function to handle multiple possible types of data packages rather than having an individual function for each case.

send(int func, ...)

The host application would take the arguments, package them up and then send it.

ala:

send(MSG_CHAT, "hello there");
send(MSG_MOVE, id, x, y);

etc.

I thought about having the host application automatically register overloaded functions all possible argument sets, but how would the host application receive this without having the equivilent on it's side?

I want the script enviornment to have control over what it can send.

Perhaps I could use an array, ala:

send(MSG_CHAT, {"hello there"});
send(MSG_MOVE, {id, x, y});

Is this something that is supported by AngelScript?
It seems very cumbersome to try to register all possible variations. And since variable arguments are not supported in AngelScript I would suggest you do something like this:


// Example script
package pkg1;
pkg1.AddValue("Hello there");
send(MSG_CHAT, pkg1);

package pkg2;
pkg2.AddValue(id);
pkg2.AddValue(x);
pkg2.AddValue(y);
send(MSG_MOVE, pkg2);


The package type would be a host registered object with overloaded methods for each of the types you wish to be able to send.

If AngelScript were to support variable arguments it would have to do something like this behind the scene anyway, i.e. build a special function context with the arguments and their types that the application would be able to query.

I may try to implement something like that in the future.

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

That'd work, but it seems a little complicated from the scripters' point of view. I guess I'll go with that for now.
That's the solution i came up with, except i called my function "PushParameter"

This topic is closed to new replies.

Advertisement