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

Sharing modules (but not globally)

Started by
1 comment, last by noizex 8 years, 5 months ago

Hello,

After looking at it for a while, I think the title of the topic may be a bit misleading, sorry. Basically I need a way to add some new code to already existing and compiled module or make two+ modules "see" each other as if they were one module. I tried searching the forums and I couldn't find a similar case. I know about shared entities, and I read the section from documentation:

While modules are independent, it may sometimes be necessary to exchange information between them. This can be accomplished in many different ways. One way is through function binding, where one module imports functions from another module and call those directly. Another way is with shared script entities, where handles to objects or functions can be exchanged between the modules. A third alternative is through messaging or proxy functions exposed by the application.

but I still can't figure that one out. So let me explain the structure I have and what I want to achieve. I have a GUI system that works with "overlays" - each overlay is self-contained and isolated piece of interface. It consists of a single Angelscript file that should define 2 methods: Init() for start-up work, and Update() for ticking. So let's say I have:


inventory.as
=========================================================================================
Context@ context; <---- this is global appended to every overlay script by C++ code

void Init()
{
   Document@ inv = context.loadDocument("inventory.rml");
   inv.show();
}

inventory.rml
=========================================================================================
<script>
   void do_something()
   {
      context.doSomethingWithContext();
   }
</script>
<input onclick='do_something()'>clickme!</input>

Now what happens when I create overlay from "inventory.as" is - it loads script from that AS file and compiles it as a module under the name of overlay (in this case "inventory"), it also appends a little global "Context@ context" to every such module. Then it calls Init() function to call script code to initialize logic, which in turn loads GUI document and shows it. But the problem is - this GUI document often contains snippets of embedded AS code like in the above example between tag "script" (it's based on JavaScript idea in HTML so that's how it works). And as the main module has already been compiled, I can't compile it again with the same name, and "append" the code. What is even more complicated, I have inline events like that onclick event, that also need to be in the same scope - right now it works because I call CompileFunction() on asIScriptModule (as it's just a single function, not some piece of code).

What I'd like to achieve, is to end up with the compiled module that has following code:


module "inventory"

____main_section

Context@ context;

void Init()
{
   Document@ inv = context.loadDocument("inventory.rml");
   inv.show();
}

____dynamically_loaded_script_section
void do_something()
{
context.doSomethingWithContext();
}

____dynamically_loaded_inline_section_0
void InlineFunction(Element@ this) { do_something() }

Is this even possible in Angelscript? The biggest problem with script section is that it can be anything, class definition, variables, function calls etc. Just any AS code. So either I make something shared (can I share whole module? without prepending everything with "shared"?) or compile it all together, which is impossible because when I create the module for the first time I have no knowledge what other documents with script code will be loaded (as it's dynamic).

Is there any way to, say, make two or more modules "interconnected" so they appear "shared" to each other? Like some kind of linking, so instead of recompiling whole source from the scratch (also probably impossible because I can't really afford loosing or recreating whole UI script whenever it loads new document) I can just link pieces together and they'll see each other?

I hope the case is explained well enough, if something is unclear - let me know. I know that most obvious solution is probably remove these embedded scripts and force all logic into main script file (in this case inventory.as) but I'd rather try some other way if there is a chance to make it work the way I initially wanted.


Where are we and when are we and who are we?
How many people in how many places at how many times?
Advertisement

An already compiled script module can be appended with new global functions and global variables through the use of asIScriptModule::CompileFunction and CompileGlobalVar, but it is not possible to append arbitrary scripts that may contain multiple functions, classes, etc.

Even if it was possible to append to an existing module (which is actually something I already have on my to-do list), I'm not sure it would be easy to remove part of the module when your GUI loaded a different document. How should the application or script engine know what should be removed?

---

Perhaps you could do something like this:

1. When loadDocument is called

2. Application serializes any existing objects, values in the module (i.e. store a backup)

3. Create a new module

4. Add the original "inventory.as" script, plus all the embedded script sections from the XML

5. Compile the module

6. If the compilation is successful, restore (deserialize) the objects and values from the previous backup

This is often known as 'hot loading' modified scripts, and normally used to allow the source code to be modified on-the-fly, but should work perfectly in your case too. The serializer add-on can be used to make the backup of values and objects and then restore them.

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

GUI script may load more than one document, and if it gets unloaded at some point I think it wouldn't be necessary to unload that part of the script which came with unloaded document (but not sure yet, logically if document goes away so should the code that was contained in it). It's incremental loading that's the biggest problem, and your solution is probably the only one that will work.

Thanks!


Where are we and when are we and who are we?
How many people in how many places at how many times?

This topic is closed to new replies.

Advertisement