SUGGESTION: Beating a dead horse with pointers to custom struct types.

Started by monkey0506, Fri 22/01/2010 22:08:09

Previous topic - Next topic

monkey0506

As per the subject line, I know I'm beating a dead horse with this, but I've been putting a lot of serious thought into it and I'm thinking that perhaps the idea wouldn't necessarily be as difficult to implement now as it once was.

One of the biggest concerns in any scripting environment allowing pointers is garbage collection. AGS does not currently support dynamic memory management aside from dynamic arrays. Strictly speaking this isn't a problem. We don't need dynamic memory to provide pointers so long as we can point a pointer to a static object in memory.

The only concern with garbage collection then would be that of what happens when the object the pointer is pointing to gets destroyed. I'm not sure how other languages handle this (I actually think the pointer would remain valid while pointing to junk memory) but the simplest route for AGS to take here would be for the pointers to be set to null.

This could actually be managed by creating a collection of all the pointers that had been created and then simply updating each pointer. If the object the pointer was pointing to had been destroyed and was no longer valid the pointer could be set to null and then even removed from the collection since it was no longer pointing to anything.

Another issue that has been mentioned is that of persisting the data in save games. If the aforementioned collection of pointers was implemented it presumably would not be any different to save the collection than it is saving pointers to AGS's managed types. These pointers to the managed types are already saved and persisted across save games as would be expected. So saving the collection of custom pointers could be managed the same way. The actual data of the object the pointer is pointing to is already being saved.

The final major issue that has been raised is that of actually creating the pointers. However, as of AGS 3.0 it is possible to create a pointer to a custom type. Any extender method declared on a custom type creates a this pointer dynamically at the time the method is called on an instance of the struct. So at this point we can create a pointer to an instance of a custom struct type, the only thing we can't do is store it anywhere.

If we try to create a pointer to our custom type we get the following error message:

QuoteError (line ###): Cannot declare pointer to non-managed type

Well obviously that's not entirely true since we know that the extender methods are creating pointers. The creation is possible, the issue is falling back to that of garbage collection which is the reason for the managed types. Our custom type isn't defined as a managed type so that means the garbage collection isn't being managed. Well what if we try to make it a managed type:

Code: ags
managed struct Pointer {
  int A;
  float B;
  String C;
};


But now we can't create an instance of this struct or else we get the following error:

QuoteError (line ###): Cannot declare local instance of managed type

Okay, so what if we make a derived type with our "managed" type as the base?

Code: ags
struct Instance extends Pointer {
};


We can now create an instance of the Instance type and use it as expected:

Code: ags
Instance instance;
instance.A = 42;
instance.B = 42.0;
instance.C = "42";


All of which works perfectly. Okay, so now to create a pointer to our "managed" type we need a pointer to the derived type. Let's try an extender method:

Code: ags
Pointer* GetPointer(this Instance*) {
  return this; // valid cast to base type from Instance* to Pointer*
}

Pointer *pointer = instance.GetPointer();


It compiles fine. But...when we run the game, we get another error:

QuoteError: Pointer cast failure: the object being pointed to is not in the managed object pool

Which actually...unfortunately...makes sense. Our instance isn't in the pool of objects marked for managed garbage collection.

So the way I'm looking at this now is that the only real issue keeping us from having pointers to custom types is the garbage collection issue. Again, I'm not suggesting that we have full dynamic memory in AGS. That would be a huge endeavor.

Instead I'm suggesting that a collection could be added internally to track non-managed pointers. If a pointer is set to point to an object that isn't in the managed pool the pointer could then be added to the collection of non-managed pointers. If the object they are pointing to is destroyed the pointers could then be updated to null.

To simplify my suggestion as much as possible, I'm not even asking that any changes would have to be made to the way we define a custom type. We could use the existing managed keyword to define that we want to define a pointer type as I have done above.

Ultimately the reason I'm asking for this is because it would be simpler to be able to do a pointer-cast to a base type than have to perform data conversion. The matter is made exponentially more difficult if you need to use methods of the base type and store the result back into the instance of the derived type.

Of course this talk all only bears relevance in terms of polymorphism which isn't technically a supported feature of AGS though it is possible.

Basically, I want to be able to do this:

Code: ags
managed struct BasePointer {
  import function DoSomething();
};

struct Base extends BasePointer {
  import BasePointer* GetPointer();
};

managed struct DerivedPointer extends Base {
};

struct Derived extends DerivedPointer {
};

DerivedPointer* GetPointer(this Derived*) {
  return this;
}

function BasePointer::DoSomething() {
  return 42;
}

function DoSomething(this DerivedPointer*) {
  BasePointer *base = this;
  int result = base.DoSomething();
  return result * 2;
}

Derived instance;
Display("%d", instance.DoSomething()); // displays 84
BasePointer *pointer = instance.GetPointer();
Display("%d", pointer.DoSomething()); // displays 42


Which all compiles fine but crashes at BasePointer *base = this;.

So what do you think CJ? Managed collection of non-managed pointers possible? Eh? Please? Pretty please? :=

Pumaman

As we've discussed before, this is a feature that can be added, it's all a matter of priorities. There certainly won't be any new feautres like this until 3.2 Final is released :)

monkey0506

Haha, I know that. ;D

But what about 3.2.1 (the Countdown edition 8))? Eh? Eh?? :=

jhonberg


Crimson Wizard

Quote from: jhonberg on Sun 05/08/2018 08:59:31
Was there a solution to this on 3.4.1 ?

No, it's still not possible in AGS... We've been discussing this only one day ago: http://www.adventuregamestudio.co.uk/forums/index.php?topic=56213.msg636592258#msg636592258 ?

PS. Probably I was not clear when I said that "solutions do exist" in the other thread; I meant that it should be theoretically possible to ADD them to the AGS. But no one did.

SMF spam blocked by CleanTalk