• 13
• 18
• 19
• 27
• 10

# A few questions about fundamentals

This topic is 2472 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hi. I am totally noob in scripting languages, so many aspects of this technology are like a divine revelation for me. Please be merciful.
I finally decided to stick with AS for my scripting purposes and just an hour ago did run through the docs.
Surpsrisingly most of it is quite comprehendable, thanks. But of course a few things are still vague for me.
Explanation needed for:
1 - What is a Module thing? What is the purpose behind this entity? I understand that it's some kind of arbitrary collection of script-functions. But it seems this point of view is superficial.
2 - The same about code-section. Can I say that code section == content of script.as?
3 - Let's assume that I have three threads(Environment, Tank1, Tank2). I want AS to provide external event handlers for tanks, and some weather-generation scripts for Environment. So, what is the best strategy for AS application? Obviously I need three contexts for every thread. I guess I have to know which script-functions belong to tank 1, and tank 2. Probably It can be done via function naming convention like plasmaAtackHandler1, plasmaAtackHandler2. Maybe this is what are modules for? ... the flow of mind my be continued, but I'd like to see the optimal solution from AS's design point of view.

##### Share on other sites
1. You can think of the module as a program, or perhaps a library. The module holds the functions, class implementations, and global variables. Multiple contexts can execute functions from the same module, however all of them will share the same set of global variables.

2. You can think of the code sections as the script files. Multiple code sections can be built together as a single script, resulting in the module.

3. Assuming the tanks share the same logic, my suggestion is that you design your scripts to be in built in two modules. One module would hold the logic for the environment, and the other module would hold the logic for the tanks. If you other types, you would add more modules, one for each type, e.g. plane, car, motorcycle, etc. You don't want to use the global variables to store the state of the individual entities though, store this in an instance of a class instead. My recommendation is that you design your script to be event based, i.e. each function that is called executes and returns within the same frame. In my opinion this is the easiest way to work. With this you only need one script context that you will re-use for each of the calls to the scripts.

##### Share on other sites
1 - So a module may be considered as a user-defined collection representing a logic for a target entity or a group of entities with exactly the same behavior?
If I want my tanks to handle events differently I should create a module per tank?
PlasmaAtackHandler() //for tank 1
{
shutdown_and_cool();
}
PlasmaAtackHandler() //for tank 2
{
use_fire_exstinguisher();
}

2 - And if my tanks do exist in a separate threads than I have to do something like this to handle PlasmaAtackEvent from C++:
int funcId = engine->GetModule(tankId)->GetFunctionIdByName("[color=#1C2837][size=2]plasmaAtackHandler");

Am I correct?

##### Share on other sites
1.

Yes, you can design it that way, though you do not have to. I use it this way in my own game engine.

2.

Well, your tankId should probably be called tankType, to avoid confusing it with the id of the actual instance of the tank entity. Also, you will want to cache the funcId so you do not have to call GetFunctionIdByName (or better GetFunctionIdByDecl) everytime. Otherwise you're correct.

##### Share on other sites
I second the caching. Do it. You have no excuse not to. Expect your programs speed to bite the dust if you don't.

##### Share on other sites
Thanks. Understood.
Here's another wave.
I want to make uninstantiable reference type so I do this.

r = mEngine->RegisterObjectType("IEntity", 0, asOBJ_REF ); assert( r >= 0 );
r = mEngine->RegisterObjectMethod("IEntity", "int getId()", asMETHODPR(IEntity, getId, (void), int), asCALL_THISCALL); assert( r >= 0 );

And I have 2 problems:
1 - It forces me to remove constness from int getId() const. Otherwise compilation fails with some twisted static cast error. But getId is a standard const getter, I do not want to change it. What I did wrong?
2 - Later I get a set of errors "IEntity missing behaviors" and blah-blah. But aren't they needed for [color=#1C2837][size=2]asOBJ_VALUE?

##### Share on other sites

1 - It forces me to remove constness from int getId() const. Otherwise compilation fails with some twisted static cast error. But getId is a standard const getter, I do not want to change it. What I did wrong?

 r = mEngine->RegisterObjectMethod("IEntity", "int getId() const", asMETHODPR(IEntity, getId, (void) const, int), asCALL_THISCALL); assert( r >= 0 ); 

Notice the 'const' keyword I added in "int getId() const" as well as in "asMETHODPR(IEntity, getId, (void) const, int)"

##### Share on other sites
Thanks, that's it. What about 2?

##### Share on other sites

2 - Later I get a set of errors "IEntity missing behaviors" and blah-blah. But aren't they needed for [color="#1c2837"]asOBJ_VALUE?

For question 2, the problem is that you didn't register the ADDREF and RELEASE behaviours. An uninstanciable reference type just means the scripts cannot create new instances of the type, AS still needs to know how to handle the references it may receive from the application.

##### Share on other sites
For question 2, the problem is that you didn't register the ADDREF and RELEASE behaviours. An uninstanciable reference type just means the scripts cannot create new instances of the type, AS still needs to know how to handle the references it may receive from the application.

Well, what should I do if I do not wish to do any refernce counting? The lifecycle of the reference passed to AS-function is controlled by shared_ptr and I guarantee that it is, and will stay valid while it's in use.
So, as I understand AS expects me to register some function any way, so it's kinda stupid but may I just register empty AddRef() {} and what's the pitfall?