Why is getControlObject shapebase based?
by Demolishun · in Torque Game Engine · 11/02/2009 (5:16 pm) · 7 replies
I am working on a gamebase derived object and the function getControlObject in gameConnection.h/.cc returns a shapebase object. This seems to be in direct conflict with the idea of preferring new objects to be derived from gamebase. So, please explain to me why it is shapebase. Are there assumptions made that require that object to be shapebase other than everything expects a shapebase object? Or should I be looking at creating a different gameConnection object? It is not clear how to proceed from here.
SimObjectPtr<ShapeBase> mControlObject; SimObjectPtr<ShapeBase> mCameraObject;
ShapeBase* getControlObject() { return mControlObject; }About the author
I love programming, I love programming things that go click, whirr, boom. For organized T3D Links visit: http://demolishun.com/?page_id=67
#2
It seems to me that GameConnection and GameBase could be modified to seemlessly provide a GameBase based GameConnection, but retain any ShapeBase specific features. It would be a hack and probably would be better done as a GameConnection object that is based on GameBase and a GameConnection object derived from the GameBase version that is specific to ShapeBase. It almost seems like it could be done as a template.
To test the idea I think modifying GameConnection would be the best bet and retain the ShapeBase interface. This could be done by changing it to GameBase internally, but any routines that work with ShapeBase would be maintained through the use of dynamic casts. A test could also be done to determine if this is a ShapeBase object by masking the GameBase object before casting. This would be especially important for ShapeBase specific values and functions that GameConnection deals with. It would be a giant hack, but would allow reuse of the GameConnection code for GameBase and introduce the control object concept before ShapeBase.
Long term they should be separated so that the Torque style GameConnection would be available for GameBase and derived after that other objects. There is some evidence that was in the plan based on commented out code in ShapeBase and GameBase. I read through the Torque info on GameConnection and it started to make sense yesterday.
The only thing that confuses me is if GameBase were to contain both a client connection reference and GameBase object reference which would it take its control from? This would have to watched closely or you could end up with two control inputs to the same object. Haha! That would be wild.
11/03/2009 (11:03 pm)
I researched this a bit and found that Gamebase is client controlled and ShapeBase is object controlled. However, because ShapeBase is Gamebase derived it gets it's client control from the GameBase version of itself. It also seems that GameConnection assumes a ShapeBase object for FPS style functions such as Whiteout and other ShapeBase specific things.It seems to me that GameConnection and GameBase could be modified to seemlessly provide a GameBase based GameConnection, but retain any ShapeBase specific features. It would be a hack and probably would be better done as a GameConnection object that is based on GameBase and a GameConnection object derived from the GameBase version that is specific to ShapeBase. It almost seems like it could be done as a template.
To test the idea I think modifying GameConnection would be the best bet and retain the ShapeBase interface. This could be done by changing it to GameBase internally, but any routines that work with ShapeBase would be maintained through the use of dynamic casts. A test could also be done to determine if this is a ShapeBase object by masking the GameBase object before casting. This would be especially important for ShapeBase specific values and functions that GameConnection deals with. It would be a giant hack, but would allow reuse of the GameConnection code for GameBase and introduce the control object concept before ShapeBase.
Long term they should be separated so that the Torque style GameConnection would be available for GameBase and derived after that other objects. There is some evidence that was in the plan based on commented out code in ShapeBase and GameBase. I read through the Torque info on GameConnection and it started to make sense yesterday.
The only thing that confuses me is if GameBase were to contain both a client connection reference and GameBase object reference which would it take its control from? This would have to watched closely or you could end up with two control inputs to the same object. Haha! That would be wild.
#3
NetConnection->GameBaseConnection->GameConnection
Trying to make it seamless for anything that uses GameConnection. Also removing non-shapebase specific code from GameConnection and putting it in GameBaseConnection. Definitely a challenge and is forcing me to learn more about the engine internals (which was the goal).
11/07/2009 (8:34 am)
GameConnection is messy. It is written to where it pretty much has to be based on Shapebase. In the middle of writing an intermediate class:NetConnection->GameBaseConnection->GameConnection
Trying to make it seamless for anything that uses GameConnection. Also removing non-shapebase specific code from GameConnection and putting it in GameBaseConnection. Definitely a challenge and is forcing me to learn more about the engine internals (which was the goal).
#4
How do you end up with your GameBase class using an object (GameConnection) that uses a sub-class of itself (ShapeBase)?!
So, again, please explain to me why GameConnection is ShapeBase Based or why is GameBase not using NetConnection? Either way you would have avoided this nasty circular reference of GameBase uses GameConnection which references ShapeBase.
This makes it difficult to sub class GameBase and properly implement sub-classed netconnections.
I guess the answer is to redefine the call in GameBase in the new object derived from GameBase. It is too bad as this almost forces you to abandon ShapeBase. Can your own NetConnection derived class coexist with GameConnection objects? This is so confusing.
11/08/2009 (9:22 pm)
What a royal pain. You can't subclass GameBase and create a clone of GameConnection for your new non-shapebase class because it needs to call getControllingClient which is in GameBase. On top of that getControllingClient returns GameConnection which is ShapeBase based! How do you end up with your GameBase class using an object (GameConnection) that uses a sub-class of itself (ShapeBase)?!
So, again, please explain to me why GameConnection is ShapeBase Based or why is GameBase not using NetConnection? Either way you would have avoided this nasty circular reference of GameBase uses GameConnection which references ShapeBase.
This makes it difficult to sub class GameBase and properly implement sub-classed netconnections.
I guess the answer is to redefine the call in GameBase in the new object derived from GameBase. It is too bad as this almost forces you to abandon ShapeBase. Can your own NetConnection derived class coexist with GameConnection objects? This is so confusing.
#5
The main things were to dynamically cast places in ShapeBase based objects (player, vehicle, etc) from NetConnection to GameConnection by checking for a flag set on it. This is similar to the way you can get for ShapeBase or Player by using flags. Another important change is completely removing writePacketUpdate and readPacketUpdate from GameBase. They do nothing and are not used by anything but ShapeBase and above. Now, you will need to define them for your own classes to handle what they handle in your reimplementation of GameConnection. If they are present the GameConnection versions never get called!
The best part of this is that to inherit to GameBase is done right now. It could be done another way and probably reduce code: Base class for GameConnection for instance, but this way is working. I may revisit now that I have learned quite a bit from this effort. I should be able to proceed to create my own version of GameConnection for my own objects. I do like the way GG has designed their client server connections and want to maintain that. I just did not like the dependence on ShapeBase and the assumption of it being there.
If anyone is interested I can send you code for the changes I made. But it is conceptually covered by this post.
11/14/2009 (10:27 pm)
Okay, so I decided to get radical on this issue. I made GameBase NetConnection based instead of GameConnection. This IS probably the better way to do this. It provides a clean break for GameBase from the derived ShapeBase objects. The main things were to dynamically cast places in ShapeBase based objects (player, vehicle, etc) from NetConnection to GameConnection by checking for a flag set on it. This is similar to the way you can get for ShapeBase or Player by using flags. Another important change is completely removing writePacketUpdate and readPacketUpdate from GameBase. They do nothing and are not used by anything but ShapeBase and above. Now, you will need to define them for your own classes to handle what they handle in your reimplementation of GameConnection. If they are present the GameConnection versions never get called!
The best part of this is that to inherit to GameBase is done right now. It could be done another way and probably reduce code: Base class for GameConnection for instance, but this way is working. I may revisit now that I have learned quite a bit from this effort. I should be able to proceed to create my own version of GameConnection for my own objects. I do like the way GG has designed their client server connections and want to maintain that. I just did not like the dependence on ShapeBase and the assumption of it being there.
If anyone is interested I can send you code for the changes I made. But it is conceptually covered by this post.
#6
It looks like there is a dynamic_cast of an object to ShapeBase without using a mask to determine if it can be a ShapeBase object. Or is dynamic_cast enough to determine if it has ShapeBase as a base class?
Edit:
Well you learn something every day:
Dynamic Cast Info
So, I don't really need the mask check I implemented. Hmmm, that will make it easier if you fork code so duplicate casts are not created. I will have to test this out.
11/15/2009 (4:04 pm)
It is interesting how much of engine is based upon GameConnection. In game.cc there is a lot of use of GameConnection. However, I don't think any of it would need to be dependent upon it. I could see migrating some of the functionality in GameConnection to NetConnection or intermediate class. This would allow more migration possibilities. As it is if there is a white out condition and you are using a GameBase object it could have problems.It looks like there is a dynamic_cast of an object to ShapeBase without using a mask to determine if it can be a ShapeBase object. Or is dynamic_cast enough to determine if it has ShapeBase as a base class?
Edit:
Well you learn something every day:
Dynamic Cast Info
So, I don't really need the mask check I implemented. Hmmm, that will make it easier if you fork code so duplicate casts are not created. I will have to test this out.
#7
note that Dynamic Casts are moderately slow operations because they're implemented via a bunch of string compares. they're fine for low-frequency stuff, but be sure to keep them out of core rendering loops. ie, if a mask-check will do the job, it might be better to go that way.
11/16/2009 (1:01 pm)
nice work Frank.note that Dynamic Casts are moderately slow operations because they're implemented via a bunch of string compares. they're fine for low-frequency stuff, but be sure to keep them out of core rendering loops. ie, if a mask-check will do the job, it might be better to go that way.
Associate Scott Burns
GG Alumni
The high level version though is that shapeBase is intended to be the actual object within the game that the player would have control over. Thus getControlObject returns a shapeBase.
If that didn't help any I'll be able to dig up my notes tomorrow for another crack at it, if someone else doesn't beat me to it.