MetaEng – Part IV

How does MetaEng handle the ability for scripts of different languages to call a unified set of C/C++ functions, or “natives”?

Quite simply, it doesn’t. In Part Five I will post about the original MetaEng architecture which tried to do this and failed. It’s absurdly difficult. Yet, the problem still needs to be solved, just not by MetaEng. In the SrcMod Framework the job of unifying natives is left up to the host architecture – in our case, SourceMod. Unfortunately, this was one of the most difficult hurdles to jump, and the flaming wreckage that resulted is called “Connectors”. They are what makes SourceMod powerful, overly complicated, and in the end, both a blessing and a curse to development.

Connectors, simply put, are DLLs that hold very primitive wrappers and callback routines. Their sole purpose is to sit in between the MetaEngine’s loading of a plugin and SourceMod’s initial execution of a plugin.

Take this example. We have host application A (SourceMod) with an exported function called “PrintMessage”. The C/C++ MetaEngine obviously has no problem accessing that through the SourceMod Interface Manager… but how does an AMX or JavaScript plugin access A::PrintMessage?

Since we don’t want to hardcode either the MetaEngine or the core, we make a connector DLL that does this:
1. Provide a static wrapper function for accessing A->PrintMessage() natively in the scripting language.
2. Hook the script’s load process.
3. Inject the script with the wrapper information (depends on MetaEngine API).

This means that a connector is a many-to-many relationship, hopping through a MetaEngine. Each Connector connects N functions to M plugins, using a MetaEngine’s API as the gateway (this is trivial since the MetaEngine should be exporting its API through the Interface Manager).

They sound complicated, but more realistically, they are trivial to make and simply rather annoying to pump out. For each MetaEngine (other than C++) you must supply a connector DLL for every set of functions you wish to make available to that language.

This is pretty nice for SourceMod’s core, as then we simply have core_js and core_amx. Unfortunately, it gets fustrating for module writers, who are forced to make a wrapper for every module they write. If I make a module called Sockets, I must also write Sockets_js and Sockets_amx, otherwise, those people will not be able to use my provided functions in their plugins.

The last notable thing about connectors, to ease the pain on both the user and developer, is that they are totally transparent. You simply throw them in the MetaEngine’s directory and it will have one of three load states (Loaded, Not Needed, Load Failed). You don’t have to worry about adding them to configuration files and such.

For examples of Connectors, you can see /cvsroot/sourcemod/ core_js, core_amx, demos/sample_module/samplemodule_amx, samplemodule_js.

Interestingly, there is a project called “SWIG” which could (in theory) be used to easily build Connectors. It will take a set of C++ definitions and built a module for a specific language, automagically! It supports more heavy-duty languages like PHP/Perl, so you can’t use it for AMX/JavaScript. The site’s description is: ” SWIG is an interface compiler that connects programs written in C and C++ with scripting languages”. Hey, doesn’t that sound familiar? It could be modified to simplify the development of connectors, as you’d just input your module header and it would spit out the connector for a given MetaEngine. So, if MetaEng lets you call multiple scripting language functions from C, Swig is the opposite, providing an interface for letting you call C functions from multiple scripting languages. Cool stuff. However, it wasn’t intended for this exact usage, and since a MetaEngine has its own ways of exporting the scripting API, it would have to be changed. In Part V I’ll talk about how MetaEng originally tried to do what SWIG does, except dynamically, not at compile time.

Tune in next time for a conclusion and history of how MetaEng evolved into the current framework for SourceMod, tentatively called “SrcMod”.

Leave a Reply

You must be logged in to post a comment.