inheritance problem in AngelScript

Started by
4 comments, last by WitchLord 9 years, 3 months ago

Im trying to create a game states system based on this http://gamedevgeek.com/tutorials/managing-game-states-in-c/ using AngelScript (the engine I use is Urho3D). I made a mistake, I created the states first, and then added the state manager. Everything stopped working, and I discovered that the problem was that derived classes methods were not called, only the ancestor class methods. This is my code:


class GameState //the game states inherit from this class
{
   GameState() {}
   void Init() {Print("Gamestate init");}
   void Leave() {}
   void HandleUpdate(StringHash eventType, VariantMap& eventData) {}
   void HandleKeyDown(StringHash eventType, VariantMap& eventData) {}
   void HandleKeyUp(StringHash eventType, VariantMap& eventData) {}
   void HandleControlClicked(StringHash eventType, VariantMap& eventData) {}
}



The game state manager



#include "Scripts/Engine/GameState.as"

class StateManager
{
  StateManager()
  {
    states.Clear();
  }

  void SubscribeToEvents()
  {
    //SubscribeToEvent(scene, "SceneUpdate", "HandleUpdate");
      SubscribeToEvent("KeyDown", "HandleKeyDown");
      SubscribeToEvent("KeyUp", "HandleKeyUp");
      SubscribeToEvent("UIMouseClick", "HandleControlClicked");
  }

  void Push(GameState st)
  {
    states.Push(st);
    states[states.length-1].Init();
  }

  /**
  Removes state on top
  */
  void Pop()
  {
    //exit current state
    states[states.length].Leave();
    states.Pop();
  }


  void HandleUpdate(StringHash eventType, VariantMap& eventData)
  {
    states[states.length-1].HandleUpdate(eventType, eventData);
  }

   void HandleKeyDown(StringHash eventType, VariantMap& eventData)
   {
    states[states.length-1].HandleKeyDown(eventType, eventData);
   }

   void HandleKeyUp(StringHash eventType, VariantMap& eventData)
   {
    states[states.length-1].HandleKeyDown(eventType, eventData);
   }

   void HandleControlClicked(StringHash eventType, VariantMap& eventData)
   {
    states[states.length-1].HandleKeyDown(eventType, eventData);
  }

   Array<GameState> states;
   int current;
}

So, this code:


class MainMenuState: GameState
{
 ******
}

MainMenuState menu;
menu = MainMenuState()
stManager.Push(menu);

Instead of callin MainMenuState members, calls GameState members.

I tried to declare the methods in derived classes as override, but didnt solved the problem. Also tried declaring ancestor as abstract, but then I cant use it to declare parameters. How can I solve this?

Advertisement

Your array stores objects directly, instead of handles to objects. That might be why this is happening. It's probably copying the given objects.

To make sure this doesn't happen you should declare the GameState class as abstract, as described here: http://www.angelcode.com/angelscript/sdk/docs/manual/doc_script_class_inheritance.html#doc_script_class_inheritance_2

I moved your topic to the AngelCode forum. I hope you don't mind :)

I see two problems in your code.

1. StateManager::Push takes the GameState by value rather than by reference or handle.

2. The GameState class should probably be an interface rather than a class.

The first problem is what causes your code to call the base class' members rather than the derived class' members, since when the object is passed to the Push method the object is copied as a GameState object, thus losing all information about the derived class.

The second problem would have prevented the first, since it is not possible to pass an interface by value (since it is abstract).

(actually, as the GameState class has no opAssign method it shouldn't be allowed to be copied anyway, but I guess Urho3D has turned off this behaviour)

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

Thanks you for moving it, Andreas. Im quite new to AS (started 2 months ago), but I figured out that perhaps passing the parameter by value would cause some problem. I tried to do MainMenuState@ menu, but that produces an error, so, Im missing somethinng here that is needed to create handles of that class. Can somebody explain me?

Never mind, I found the solution. I made a quick test:


interface  Parent
{
	//Parent(){}
	void init();

}

class Child: Parent
{
	Child() {}
	void init()
	{
		Print("Child init");
	}
}

void test(Parent@ param)
{
	param.init();
}

void Start()
{
	Print("Start");
	Child@ c = Child();
	test(c);
	engine.Exit();  //urh3d exit
}

Is it correct ot pass Child@ and put it in an Array?

Yes, it's correct. It works the same way as in C++ and other languages that support polymorphism.

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