Advertisement

Working out the details of my new design

Started by February 01, 2009 12:47 PM
2 comments, last by WitchLord 15 years, 10 months ago
I was just rereading the discussion in the persistent objects thread, and I noticed you mentioned that globals are maintained inside modules. When I run time construct a script object, is it held in the module, not the context? Another question, I know I keep asking, but should it be safe to share a module and context's between threads? Lastly, whats the syntax for the new inheritances?

class Child : Base {
}


Like that? I guess my big question is. Say a script object (A) holds a handle to a Link object from some other script object (B). And B is deleted application side, but the Link object for it is left dangling because something is holding a reference to it. I guess the only way have A release it's handle would be to notify it in some way that A was deleted... How do you handle this? [Edited by - Wavesonics on February 1, 2009 6:09:22 PM]
==============================
A Developers Blog | Dark Rock Studios - My Site
I noticed you had the script class taking in a CGameObject:
Quote:
CPlayer(CGameObject @entity)


I know you just wrote that up off the top of your head, so really it should take in a Link object right? Which is why you replicate the CGameObject's functionality in the Link object right?

And Script objects never have references to each other, but instead they contain references to each other's link objects?

I'm implementing a watered down version of things for the moment, with an eye to everything being completely scripted in the future.

So far this is what I'm planning on having my script class look like:
// EntityController.asinterface EntityController {    void update();};// Turret.asclass Turret : EntityController {    GameObject@ m_o;    Turret( GameObject@ o ) {        m_o = o;    }    void update() {    }    void onFire( Creep@ c ) {    }};// TurretClient.as#include "Turret.as"class TurretClient : Turret {    GameObjectClient@ m_oc;    TurretClient( GameObjectClient@ o ) {        m_o = o;        m_oc = o;    }    void update() {    }};


Ok here is the ideas with it.
1) All of the "Client" things contain extra methods and data for drawing. (That's already how things work). So the server instantiates plain Turrets which handle all the important logic. And Clients instantiate TurretClient's which contain addition stuff for drawing.

2) Using this division, a Server would only load Turret.as and thus could apply the stricter config group. Clients loading TurretClient.as would get the expanded config group with draw function bindings.

3) I declare an implicit cast for GameObjectClient to GameObject to make some of that work there.

4) For the child class's constructor, I noticed you said you wouldn't be do initializer lists, so is this the proper way to replicate the Base class's constructor?

5) If I over ride a function, is there anyway to call the base function?

6) I was probably going to register GameObjectLink to the scripting engine as GameObject just so that layer of indirection is invisible in the scripts.

7) As long as a GameObject is alive, it's GameObjectLink and EntityController are NECESSARILY alive.
* If a GameObject is destroyed and nothing else holds a reference to the GameObjectLink, both the link and EntityController will be destroyed via the GameObjectLink's destructor.

* If a GameObject is destroyed while other things hold references to it's Link object, they may continue to act on the EntityControler/GameObjectLink as if it were alive, but to no effect, because the proxy functions in GameObjectLink will just dump out when they detect the GameObject has been destroyed. Probably need a way to alert other script objects that the link has been severed so they will drop their references.

[Edited by - Wavesonics on February 1, 2009 1:05:56 PM]
==============================
A Developers Blog | Dark Rock Studios - My Site
Advertisement
Quote: Original post by Wavesonics
I was just rereading the discussion in the persistent objects thread, and I noticed you mentioned that globals are maintained inside modules.

When I run time construct a script object, is it held in the module, not the context?


The context is just the call stack. Think of the context as a thread, rather than a complete instance of a program. The objects that are instanciated by the context needs to be stored in some global memory for them to outlive the contexts, e.g. a global variable in the module, or somewhere within the application.

Quote: Original post by Wavesonics
Another question, I know I keep asking, but should it be safe to share a module and context's between threads?


You can share modules and contexts between threads, but the application will have the responsibility of making sure shared resources are accessed properly between threads.

Manual: Multithreading


Quote: Original post by Wavesonics
Lastly, whats the syntax for the new inheritances?

*** Source Snippet Removed ***

Like that?


Exactly. The inheritance is declared the same way that interfaces are used.

class A : B, C, D {}


In the above snippet, only one of B, C, and D can be a class, the others must be interfaces, otherwise you'll get a compilation error.


Quote: Original post by Wavesonics
I guess my big question is. Say a script object (A) holds a handle to a Link object from some other script object (B). And B is deleted application side, but the Link object for it is left dangling because something is holding a reference to it. I guess the only way have A release it's handle would be to notify it in some way that A was deleted...

How do you handle this?


(A) will ask the link object if the (B) is still alive. For example:

  if( !linkToB.isAlive() )    @linkToB = null;


This will allow the scripts to gracefully handle the situation where they loose a link to an object that has been destroyed.

If the application knew how to notify each object that held a reference to (B), then you wouldn't need the link object, as then you could just have the notification clear the reference immediately.

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

Quote: Original post by Wavesonics
I noticed you had the script class taking in a CGameObject:
Quote:
CPlayer(CGameObject @entity)


I know you just wrote that up off the top of your head, so really it should take in a Link object right? Which is why you replicate the CGameObject's functionality in the Link object right?


I register the CGameObjectLink as CGameObject with AngelScript.

Quote:
And Script objects never have references to each other, but instead they contain references to each other's link objects?


Correct.




Quote:
4) For the child class's constructor, I noticed you said you wouldn't be do initializer lists, so is this the proper way to replicate the Base class's constructor?


I'm taking some ideas from the D language; The derived class will be able to call the constructor of the base class by using the keyword 'super'.

    TurretClient( GameObjectClient@ o ) {        super(o);        m_oc = o;    }


Quote:
5) If I over ride a function, is there anyway to call the base function?


Yes, you will be able to call the base function the same way it is done in C++, i.e.

class A : B{   void func()   {    // Call base class' implementation    B::func();  }} 

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

This topic is closed to new replies.

Advertisement