[C++] How do I import plugin functions as part of a struct?

Started by Scavenger, Sat 12/12/2015 21:08:29

Previous topic - Next topic

Scavenger

I have a lot of functions in my plugin, and I'd like to organize them a little so the interface to the end user isn't a complete mess. I've seen plugins use structs for their functions before (the Adplug plugin for instance), but I'm not sure how to do it myself. I'd assume it's similar to how you do it in AGS, but it's not documented and I'm not sure.

Also, the AGSObject* structure doesn't have IgnoreScaling and IgnoreLighting as flags - how do I check this from the plugin?

Wyz

It's actually not that different from how you would do it in Modules so your guesses are right.
You would provide a plugin header something like this:
Code: ags

struct MyPlugin {
    /// Autocomplete text for Function 1
    import static void Function1();            // $AUTOCOMPLETESTATICONLY$
    /// Autocomplete text for Function 2
    import static int Function2(int a, int b); // $AUTOCOMPLETESTATICONLY$
    int dummy;                                 // $AUTOCOMPLETEIGNORE$
};


Then you would register them like this:
Code: C++

engine->RegisterScriptFunction("MyPlugin::Function1^0", (void *) Function1);
engine->RegisterScriptFunction("MyPlugin::Function2^2", (void *) Function2);


Oh and don't forget that dummy if your struct is otherwise empty or your are in for some hair pulling when the game keeps crashing. ;)

Hope that helps you. :)
Life is like an adventure without the pixel hunts.

Scavenger

Thank you so much for the help!

So if I get it right, you'd type out that header like:
Code: C++

const char *ourScriptHeader =
"struct MyPlugin {                                                         \r\n"
"    /// Autocomplete text for Function 1                                  \r\n"
"    import static void Function1();            // $AUTOCOMPLETESTATICONLY$\r\n"
"    /// Autocomplete text for Function 2                                  \r\n"
"    import static int Function2(int a, int b); // $AUTOCOMPLETESTATICONLY$\r\n"
"    int dummy;                                 // $AUTOCOMPLETEIGNORE$    \r\n"
"}                                                                         \r\n";

,add "StructName::Function^[num. of arguments]" to RegisterScriptFunction, and I don't need to change the function declarations at all in the actual code? (Except for, I'm assuming, adding the static keyword?)

Because there are a few functions I use internally I'd like to open up to the end user (Such as GetColor565, MixColorAlpha etc) and I'm not sure how I could handle a struct that isn't even technically declared in the plugin code itself. Unless I, like, make wrapper functions to put in the struct.

Also, there's quite a few things there I've not seen in the plugin documentation. You can make autocomplete text for plugin functions?? What does $AUTOCOMPLETESTATICONLY$ mean? There's so much I haven't ever seen before, and it feels like I've been working on this forever x3 Where do I get this information from?


EDIT: It ain't working. I'm not sure why, I followed your instructions? Do I need to make a copy of the struct in the script header in the code itself?

Code: C++

const char *ourScriptHeader =
  "struct TestStruct{\r\n"
  "import static void dummyfunction (); // $AUTOCOMPLETESTATICONLY$\r\n"
  "import int dummy; //$AUTOCOMPLETEIGNORE$\r\n"
  "}\r\n";

static void dummyfunction ()
{
}

//elsewhere in the AGS Engine startup code.
engine->RegisterScriptFunction ("TestStruct::dummyfunction^0", (void*)dummyfunction);


Am I missing anything? It just says:
__Plugin100.ash: 'import' not valid in this context

Wyz

Ok, that was my fault: I forgot the semicolon after the struct closes. Whoops (roll).

Btw, static in C or C++ outside of a class means something else which is an interesting story but not very relevant, it will work without. I can tell you if you want to learn more about C/C++ but otherwise never mind that. :)
Now for AGS the static makes that you can call the function on struct itself instead of an instance so
Code: ags
Mystruct.Function1();
instead of
Code: ags
MyStruct foo;
foo.Function1();
which is exactly what we want.

The $AUTOCOMPLETESTATICONLY$ directive tells the autocompleter to hide the function when using an instance instead of the struct itself; that is just nice to do to prevent confusion. The $AUTOCOMPLETEIGNORE$ directive hides it completely which is what we want for our dummy. It will only hide it btw, it is still there. You can also use this to create undocumented functions etc.

Lines before functions starting with three slashes create autocompleter hints: these will be shown when you type the function names in the editor; really nice to create self documented plugins
Life is like an adventure without the pixel hunts.

Monsieur OUXX

Reminder: there's the "Easy plugin" tool available for lazy people.
 

SMF spam blocked by CleanTalk