Sign in to follow this  

import facility doubts

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

If you intended to correct an error in the post then please contact us.

Recommended Posts

import void btLineFormation(int i) from "GUIScript"; wrote something like this, can you shed some light on how to exactly use it and make sure it works. GUIScript is the section but i have used 0 for section names or they wouldnt work. can you gimme more info on this?

Share this post


Link to post
Share on other sites

// Script 1
void btLineFormation(int i)
{
// Do something
}



// Script 2
import void btLineFormation(int i) from "GUIScript";

void test()
{
btLineFormation(1);
}



// C++
// Build module GUIScript
engine->AddScriptSection("GUIScript", "script1", script1, strlen(script1));
engine->Build("GUIScript");

// Build the other module that imports from GUIScript
engine->AddScriptSection(0, "script2", script2, strlen(script2));
engine->Build(0);

// Bind all imported functions in the module
engine->BindAllImportedFunctions(0);


The import statement imports functions from other modules, not from script sections. The imported modules can be recompiled at later times by first unbinding the functions, recompiling the module, and then binding the functions again.

Share this post


Link to post
Share on other sites
I am using different Engine Instances right now. I need to know if i can bind imported functions from another engine instance, the problem is i will have to use section names in most functions then to make sure they work.

Is it better to use a single engine instance with different sections instead?

Share this post


Link to post
Share on other sites
It's not possible to import functions from different engine instances.

You keep mentioning sections, so I'm not sure you understand the difference between modules and sections. A section is just a piece of script that will be compiled together with other sections into one module, the name you give the section will help you identify the location of any errors during build but they all share the same namespace. Different modules use different namespaces and are compiled separately, a function can be bound from one module to another, much like how a function is dynamically linked from a DLL.

Share this post


Link to post
Share on other sites
I guess you cleared my doubt, i would like to know though if it is better to use 1 instance of the engine with different scripts as different. can you tell me the advantages and disadvantages?

Share this post


Link to post
Share on other sites
One engine / many modules:
Pros:
Import facility actually works.
Only one instance of the engine in memory.
Don't need to pass around an engine pointer (just supply a global method of access to it)

Many engines / one module each:
Cons:
Import facility does NOT work. (But preprocessing can do the same thing, except it's harder to change what they link to)
Wastes memory
Try getting the script context from the wrong engine. Oops.


Personally, I don't like the fact that I have to have the module name hardcoded into the script to import things. I'd get around this by always having the module name the same as the filename, and then writing a macro so I can stick the filename first (ala, IMPORT(FILE,FUNCTION) )

Share this post


Link to post
Share on other sites
Yes, But the problem i am facing is, i would have to call each function context with it's section name, this is a bit of a drain, cos i need to remember which function goes where

engine->GetFunctionIDByName(0, (const char *)funcname);

like that, i cannot maintain multiple modules, i am using 0 now, if i dont use multiple section and a single module, then my error messages would give me wrong line numbers, is there a workaround

I want to change my code to use a single engine with multiple sections, but i cannot pass the section name to function contexts too, it doesnt seem practical.(existing method - multiple engines / 0 as the script section pointer)

Share this post


Link to post
Share on other sites
Quote:
Original post by Deyja
Personally, I don't like the fact that I have to have the module name hardcoded into the script to import things. I'd get around this by always having the module name the same as the filename, and then writing a macro so I can stick the filename first (ala, IMPORT(FILE,FUNCTION) )


The module name in the import statement can be mapped to something else if the application wishes. Though you'll have manually enumerate all imported functions and bind them one by one using the following methods:


int GetImportedFunctionCount(const char *module);
int GetImportedFunctionIndexByDecl(const char *module, const char *decl);
const char *GetImportedFunctionDeclaration(const char *module, int importIndex, int *length = 0);
const char *GetImportedFunctionSourceModule(const char *module, int importIndex, int *length = 0);
int BindImportedFunction(const char *module, int importIndex, int funcID);

Share this post


Link to post
Share on other sites
EddHead:

My recomendation is to use one engine per interface you wish to expose to the scripts, e.g. one engine for AI scripts, one engine for GUI scripts, one engine for Console scripts, etc.

Let's take the AI scripts as an example. If you have two AI types, grunt and boss, then you have at least two options for writing their scripts: Either you write one large script where the script functions for both types share the same namespace or you divide them in two scripts where each of them have their own namespace. In either case you'll have to know how to separate the functions so that the right application knows which function to call for which AI type. When using multiple modules you can do it like this:


// The grunt script uses only one file
engine->AddScriptSection("grunt", grunt_filename, grunt_script, strlen(grunt_script));
engine->Build("grunt");

// For some reason the boss script is divided in two files
engine->AddScriptSection("boss", boss_filename, boss_script, strlen(boss_script));
engine->AddScriptSection("boss", boss_filename2, boss_script2, strlen(boss_script2));
engine->Build("boss");

struct AIInterface
{
int thinkFunc;
int actFunc;
} gruntAI, bossAI;

gruntAI.thinkFunc = engine->GetFunctionIDByDecl("grunt", "void think(entity&)");
gruntAI.actFunc = engine->GetFunctionIDByDecl("grunt", "void act(entity&)");
bossAI.thinkFunc = engine->GetFunctionIDByDecl("boss", "void think(entity&)");
bossAI.actFunc = engine->GetFunctionIDByDecl("boss", "void act(entity&)");


Share this post


Link to post
Share on other sites
I am already doing that, but my problem is i think it is pretty inconvinient to use the section names and function declarations everytime i need to execute a function,

The main kinda application i have for the script is the ability to dynamically allocate script function to entities like FSM state continuous functions and stuff like that, this helps me make it as generic, is there a way which i can make sure that all functions are available to all scripts (via import) and i dont need to remember section names or complete function declarations(i use GetFunctionIDByName), and still get the error locations to work on a file-to-file basis?

Share this post


Link to post
Share on other sites
Can you show me with an example of how you want it to work? I think I don't quite understand what you're trying to tell me.

The import statement will only work with the complete function declaration, as the compiler needs this information to know how the function is called.

If you don't want to have to remember all the function declarations with their parameters and return types, how are you supposed to know how to call the functions?

You never have to remember the section names, they are only used for compiler messages. If you don't want to have to remember module names, then compile all script sections into one module with no name.

The error locations will be correct as long as you don't alter the script file before adding them to the module with AddScriptSection(). Each file should be added with a separate call to AddScriptSection() where the section name is the filename.

Share this post


Link to post
Share on other sites
yep, i have been using it this way,

AddFSMState( fsm1, ANGRY, "angryfunc" );

what i do is use GetFunctionIDByName to get the context for the function angryfunc and call this function from the FSM handler code, very convinient(which was what made me so obsessed with this library). i normally dont send more than 1 parameter, maybe like a single integer paramater. this helps em alot in dynamic behavior changing. i could explain better i guess...but my english sucks.

Share this post


Link to post
Share on other sites
Sounds like a good way of handling it.

If you wish to use modules, then you could either add the name of the module as a parameter to the AddFSMState() function. Or you could pass the function ID instead of the function name:

AddFSMState(fsm1, ANGRY, engine->GetFunctionIDByDecl("module", "void angryfunc()"));

Share this post


Link to post
Share on other sites
Yes, but like i said the module names are cumbersome, i would like to add module names only if i am handling it internally, since scripts are mostly used by Modders, i would like to give as minimal control to them as possible.

i would like to bypass the usage of a Module name.

Share this post


Link to post
Share on other sites
Who is doing the calls to AddFSMState? Isn't that the your application when it loads the scripts for the AI entities?

Why would the script writers need to know the module names? Why do you need to use the import statement?

True namespaces would perhaps have been easier to use, but I haven't implemented them yet.

Share this post


Link to post
Share on other sites
Most of the Modders i am talking about will be more advanced than the usual modder, i require them to have some coding knowledge anyway, but AddFSMState is an example. these are called in the script defs for FSM creation. (yes i want to be able Mod to that level).

Share this post


Link to post
Share on other sites
Most of the time you don't need to specify the module name, because the application can obtain the module name from the context when an application function is called:


void func()
{
asIScriptContext *ctx = asGetActiveContext();
uint funcID = ctx->GetCurrentFunction();
string modulename = ctx->GetEngine()->GetModuleNameFromIndex(funcID >> 16);

... Do something where the module name is needed
}


Share this post


Link to post
Share on other sites

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

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this