Adventure Game Studio

AGS Support => Advanced Technical Forum => Topic started by: edmundito on Mon 10/10/2005 02:43:07

Title: Plugin API: Managed Objects - huh?
Post by: edmundito on Mon 10/10/2005 02:43:07
Can someone explain and give out some examples on the API Functions RegisterManagedObject, AddManagedObjectReader, and so on? I keep scratching my head when I read Plugin API (http://www.adventuregamestudio.co.uk/acplugin.htm) doc.  ???

Yep, I'm a total n00b at plugins.
Title: Re: Plugin API: Managed Objects - huh?
Post by: scotch on Mon 10/10/2005 07:34:24
The documentation is fairly unclear on the subject, and I'd like to make an OO interface to my plugin, so I tried to work out how to use them, here is what I have gathered...

Managed objects are objects created in the plugin that the script can manipulate using a pointer, the pointer is reference counted, so your plugin will be notified when the object is no longer needed by the script and you can delete it.

A managed object type needs a couple of classes implemented for it and passed to the runtime so that AGS can use it -
IAGSScriptManagedObject ( which is responsible for destroying objects that aren't needed, and serializing them for when the game is saved) and IAGSManagedObjectReader (which is responsible for rebuilding objects from the saved data).

The interface that the managed object uses should be declared in the script header for your plugin using a struct definition, in my test I had an object called Circle, and the header was like this -
managed struct Circle {
import attribute int radius;
import int getArea();
import static Circle* create();
Ã,  };
import Circle* CreateCircle();


The "managed" keyword makes it impossible to declare a struct in the script, which would not do what you wanted, you can only manipulate it with a pointer that you get from a function, such as the CreateCircle one I put there.
All the members should be declared with "import" so that the engine looks for them in your plugin.
The "attribute" thing is needed on member variables that you want to be able to get from the object in the plugin, when you specify a member variable as an attribute then you need to create get_name and set_name member functions and tell the engine about them.Ã,  In that case I had to make "Circle::get_radius" and "Circle::set_radius".
Now, this worked fine with int parameters, but I couldn't get the get_radius function to work with a float return type, not sure what I was doing wrong yet.

I could write more, but it's probably more confusing than showing some code, so here:

http://caverider.com/ags_managedtest.cpp

With that you can create and manipulate Circle objects.

CJ, would it not be possible to register member variables in a quicker way, saving the get/set functions, by using something like
engine->RegisterManagedObjectMember("Circle", "float radius", offsetof(Circle, radius));
that'd give you the byte offset of the variable in the object so AGS can manipulate it directly.Ã,  Just an idea... the get/set method has its advantages also.

All in all ManagedObjects seem really useful, I'll use them for my game.


EDIT: found this thread http://www.adventuregamestudio.co.uk/yabb/index.php?topic=22628.0 which covers some of the stuff, still, could anyone answer the question about returning floats, or does it work for everyone else?
Title: Re: Plugin API: Managed Objects - huh?
Post by: Pumaman on Mon 10/10/2005 18:47:05
scotch has given a nice introduction to using managed types from plugins. As he's also pointed out, there is more information in this thread:
http://www.adventuregamestudio.co.uk/yabb/index.php?topic=22628.0

QuoteCJ, would it not be possible to register member variables in a quicker way, saving the get/set functions, by using something like
engine->RegisterManagedObjectMember("Circle", "float radius", offsetof(Circle, radius));
that'd give you the byte offset of the variable in the object so AGS can manipulate it directly.  Just an idea... the get/set method has its advantages also.

Well, property accesses are generated as function calls by the script compiler, so AGS would have to effectively generate a wrapper get/setter in this situation anyway. Also, generally you'd want to do some sort of validation in the setter. However I see what you're saying, and it would perhaps simplify the process of creating plugins.

Quotecould anyone answer the question about returning floats, or does it work for everyone else?

Floats are a bit special in the AGS scripting system. This is because most compilers such as GCC and MSVC always convert floats to doubles (64-bit) when passing to and from functions, whereas the AGS script actually uses them as 32-bit floats.

This is an extract from the AGS Source Code on how the engine deals with this problem. It's not pretty.

#define SCRIPT_FLOAT(x) long __script_float##x
#define INIT_SCRIPT_FLOAT(x) float x = *((float*)&__script_float##x)
#define FLOAT_RETURN_TYPE long
#define RETURN_FLOAT(x) return *((long*)&x)

int FloatToInt(SCRIPT_FLOAT(value), int roundDirection) {
  INIT_SCRIPT_FLOAT(value);

  int intval = (int)value;

  return intval;
}

FLOAT_RETURN_TYPE IntToFloat(int value) {
  float fval = value;

  RETURN_FLOAT(fval);
}


Above are some examples of a (stripped-down) version of FloatToInt and IntToFloat to demonstrate how the macros are used.
Title: Re: Plugin API: Managed Objects - huh?
Post by: edmundito on Mon 10/10/2005 20:16:02
OMG! Teh Source has been leaked. Now everyone shall make their own AGS-clone!

Um, yeah, I looked at that older thread, but it just gave me a headache, because everyone talked assuming that they knew the whole managed objects stuff already.

Anyway, I think I'm starting to get it.
Title: Re: Plugin API: Managed Objects - huh?
Post by: Kweepa on Mon 10/10/2005 23:19:19
Quote from: Edmundo on Mon 10/10/2005 20:16:02
Um, yeah, I looked at that older thread, but it just gave me a headache, because everyone talked assuming that they knew the whole managed objects stuff already.

Yeah, what was that about? I was rather confused too. Managed? Where did that terminology come from and how come everyone was bandying it around like it was common knowledge?
Title: Re: Plugin API: Managed Objects - huh?
Post by: edmundito on Tue 11/10/2005 00:32:24
Quote from: SteveMcCrea on Mon 10/10/2005 23:19:19
Quote from: Edmundo on Mon 10/10/2005 20:16:02
Um, yeah, I looked at that older thread, but it just gave me a headache, because everyone talked assuming that they knew the whole managed objects stuff already.

Yeah, what was that about? I was rather confused too. Managed? Where did that terminology come from and how come everyone was bandying it around like it was common knowledge?

Obviously, this is all one big joke between Scotch and Puma that they devised at Mittens last year to confuse everyone.  :=

Edit: Good example... now I pretty much understand it.

One weird thing, though, on AGS 2.71 RC (well who knows if it's 2.7 too): The little helper window that pops up with the member functions does not pop up for Circle or Circle's members, and I noticed that you indeed registered the names:

  engine->RegisterScriptFunction("Circle::create^0", CreateCircle);
  engine->RegisterScriptFunction("Circle::getArea^0", Circle_getArea);
  engine->RegisterScriptFunction("Circle::set_radius", Circle_set_radius);
  engine->RegisterScriptFunction("Circle::get_radius", Circle_get_radius);
  engine->RegisterScriptFunction("CreateCircle", CreateCircle);
Title: Re: Plugin API: Managed Objects - huh?
Post by: scotch on Tue 11/10/2005 02:04:16
Thanks CJ!
Hm, you are right about the plugin's script header not being picked up by the autocomplete, Edmundo, not sure what's up there.
And I had no idea about managed objects either :P I had to work this out with trial and error, like struct member functions, CJ adds cool stuff, and doesn't even tell anyone how to use it!

Edit by strazer:

AGS v2.71 RC2:
* Fixed plugin headers not being parsed for autocomplete in RC 1.
Title: Re: Plugin API: Managed Objects - huh?
Post by: edmundito on Tue 11/10/2005 03:55:09
Okay, say that you have this...

Struct A { MyManagedObj *B; }

and you have

A a;
a.B = createB();
MyManagedObj *C = a.B;

AGS says it's missing A::get_B. how do we get around this situation?
Title: Re: Plugin API: Managed Objects - huh?
Post by: Pumaman on Tue 11/10/2005 20:18:52
How exactly have you defined the struct? The "missing A::get_b" message will appear if you used "attribute" when declaring the variable, but didn't provide such an attribute definition in the plugin.
Title: Re: Plugin API: Managed Objects - huh?
Post by: edmundito on Thu 13/10/2005 14:37:15
I got my problems fixed, and thanks to scotch I understand this stuff pretty well. However, there was still some problems passing objects to functions and changing the values, so the best way for me to tacle the problems were like:

MyManagedObj* f() {
  MyManagedObj *temp = MyManagedObj.new();
  temp.number = 5;
  return temp;
}


followed by:

MyManagedObj *a = f();

Instead of having:

function f(MyManagedObj *temp) {
  b.number = 5;
}


followed by:

MyManagedObj *a = MyManagedObj.new();
f(a);


I just forgot about making functions with a type (eg- MyManagedObj whatever() {})  on AGS since usually function whatever() can return a lot of the types that I usually need, you know? and there was no need for it with pre-2.7 scripting, anwyay.
Title: Re: Plugin API: Managed Objects - huh?
Post by: scotch on Fri 14/10/2005 16:08:26
Somewhat related, is it possible to take Strings as parameters to a plugin function? How would I do it, if it is?
Title: Re: Plugin API: Managed Objects - huh?
Post by: Pumaman on Fri 14/10/2005 18:31:59
Yes, just declare the function as taking a "const string" parameter in the script header, and then in your plugin code declare it as a "const char*" and it'll be fine.

One thing you can't do at the moment though is return a String from a plugin function, which is something I should add.

Edit by strazer:

AGS v2.71 RC2:
* Added plugin API CreateScriptString method to allow plugins to return Strings.
Title: Re: Plugin API: Managed Objects - huh?
Post by: edmundito on Sat 15/10/2005 22:11:38
While we're on this topic of advanced stuff for AGS, I think there needs to be a programmer's manual for AGS featuring the unofficial support for stuff that is an optional download from the website. it would include information on the API functions as well and so on, but also on struct inheritance and other features not mentioned in the manual.

For example, I don't know if you can have private/protected functions on structs. Some guy claimed that you could, but he didn't know the syntax, so he was worthless.
Title: Re: Plugin API: Managed Objects - huh?
Post by: Janik on Sat 22/10/2005 01:38:35
Thanks for that sample code you posted, scotch - it was a great help for a plugin I am working on at the moment. I think it could be made part of the official plugin documentation.

Managed objects look like a very useful addition. They certainly made life easier for my plugin. I imagine that for the many people working on AGS RPGs, creating a custom object for a character's stats etc. would be a godsend.  :=