Re: Base class with member parameterized on type of extending class

2014-10-20 Thread Jacob Carlborg via Digitalmars-d-learn

On 2014-10-19 13:19, rcor wrote:

I'm trying to make a game, and would like to set up the following
hierarchy:
At any time, the game is in one Scene. Each scene has a state machine
that manages States of type T, where T is the type of the scene (e.g.
Overworld, Menu).

abstract class State!T {
   void update(T scene, float time, InputManager input);
   ...
}

class StateMachine!T { //manages states of type State!T }

abstract class Scene {
   alias T = // type of class extending Scene
   // methods pushState, popState, currentState access _stateMachine
   private StateMachine!T _stateMachine;
}

class MainMenu : Scene {
// I want _stateMachine of type StateMachine!MainMenu
}

class Overworld : Scene {
   // I want _stateMachine of type StateMachine!Overworld
}

class MoveToLocation : State!Overworld {
   override void update(Overworld world, float time, InputManager input) {
 // access properties of Overworld here
   }
}

Within the Scene class, I've tried alias T = typeof(this), but that
appears to be resolved within Scene. This means that any Scene, such as
Overworld, have a state machine of type StateMachine!Scene rather than
StateMachine!Overworld. Since States are particular to a certain scene
and are designed to manipulate properties specific to that type of
scene, this would involve a lot of casting if States are not
parameterized. It feels like I need something like a class version of
the (this T) syntax used in templates.

This all smells a bit off though, so I wouldn't be surprised if the
answer is that I'm approaching this all wrong, but right now I'm not
seeing it.


You can always make Scene a template class:

abstract class Scene (T)
{
private StateMachine!T _stateMachine;
}

class MainMenu : Scene!(MainMenu) {}

But I'm guessing you like to avoid that if possible.

--
/Jacob Carlborg


Re: Base class with member parameterized on type of extending class

2014-10-20 Thread rcor via Digitalmars-d-learn

On Monday, 20 October 2014 at 06:17:42 UTC, Jacob Carlborg wrote:


You can always make Scene a template class:

abstract class Scene (T)
{
private StateMachine!T _stateMachine;
}

class MainMenu : Scene!(MainMenu) {}

But I'm guessing you like to avoid that if possible.


I would, as I need to keep track of the current scene in a 
variable somewhere:


  Scene _currentScene; // problematic if Scene is a template

I could just declare the StateMachine separately in every Scene, 
but that seems like a lot of duplicate code (I then repeat the 
same code for updating the state machine, ect.)


Re: Base class with member parameterized on type of extending class

2014-10-20 Thread Jacob Carlborg via Digitalmars-d-learn

On 2014-10-20 12:27, rcor wrote:


I would, as I need to keep track of the current scene in a variable
somewhere:

   Scene _currentScene; // problematic if Scene is a template


If the state machine doesn't need to be exposed you can create base 
class for Scene which is not templated:


abstract class Scene {} // As it is now minus the state machine

abstract class ConcreteScene (T) : Scene
{
private StateMachine!T _stateMachine;

// other code that need access to _stateMachine
}

class MainMenu : ConcreteScene!(MainMenu)  {}

Scene _currentScene = new MainMenu;

ConcreteScene might not be the best name of an abstract class.


I could just declare the StateMachine separately in every Scene, but
that seems like a lot of duplicate code (I then repeat the same code for
updating the state machine, ect.)


Or you could use a template mixin:

template StateMachineMixin (T)
{
private StateMachine!T _stateMachine;

// other code that need access to _stateMachine
}

class MainMenu : Scene
{
mixin StateMachineMixin!(typeof(this));
}

--
/Jacob Carlborg


Re: Base class with member parameterized on type of extending class

2014-10-20 Thread rcor via Digitalmars-d-learn
If the state machine doesn't need to be exposed you can create 
base class for Scene which is not templated:


abstract class Scene {} // As it is now minus the state machine

abstract class ConcreteScene (T) : Scene
{
private StateMachine!T _stateMachine;

// other code that need access to _stateMachine
}

class MainMenu : ConcreteScene!(MainMenu)  {}

Scene _currentScene = new MainMenu;

ConcreteScene might not be the best name of an abstract class.


Just came up with something similar before I saw this post:

interface IScene { // enter, exit, update, draw }
class Scene!T : IScene {
private StateMachine!T _stateMachine;
void update(float time) {
_stateMachine.update(cast(T) this, time);
}
}
The cast is unfortunate but since it only happens once per update 
cycle I'm not that worried about it.


I could just declare the StateMachine separately in every 
Scene, but
that seems like a lot of duplicate code (I then repeat the 
same code for

updating the state machine, ect.)


Or you could use a template mixin:

template StateMachineMixin (T)
{
private StateMachine!T _stateMachine;

// other code that need access to _stateMachine
}

class MainMenu : Scene
{
mixin StateMachineMixin!(typeof(this));
}


Interesting idea, I might give this a try but the first 
suggestion seems fine for now. Thanks!


Base class with member parameterized on type of extending class

2014-10-19 Thread rcor via Digitalmars-d-learn
I'm trying to make a game, and would like to set up the following 
hierarchy:
At any time, the game is in one Scene. Each scene has a state 
machine that manages States of type T, where T is the type of the 
scene (e.g. Overworld, Menu).


abstract class State!T {
  void update(T scene, float time, InputManager input);
  ...
}

class StateMachine!T { //manages states of type State!T }

abstract class Scene {
  alias T = // type of class extending Scene
  // methods pushState, popState, currentState access 
_stateMachine

  private StateMachine!T _stateMachine;
}

class MainMenu : Scene {
   // I want _stateMachine of type StateMachine!MainMenu
}

class Overworld : Scene {
  // I want _stateMachine of type StateMachine!Overworld
}

class MoveToLocation : State!Overworld {
  override void update(Overworld world, float time, InputManager 
input) {

// access properties of Overworld here
  }
}

Within the Scene class, I've tried alias T = typeof(this), but 
that appears to be resolved within Scene. This means that any 
Scene, such as Overworld, have a state machine of type 
StateMachine!Scene rather than StateMachine!Overworld. Since 
States are particular to a certain scene and are designed to 
manipulate properties specific to that type of scene, this would 
involve a lot of casting if States are not parameterized. It 
feels like I need something like a class version of the (this T) 
syntax used in templates.


This all smells a bit off though, so I wouldn't be surprised if 
the answer is that I'm approaching this all wrong, but right now 
I'm not seeing it.