Reputation: 35
Here is the simplified code of my classes:
public class Game
{
World world;
DataManager dataManager;
public Game()
{
world = new World();
dataManager = new DataManager();
}
public void Run()
{
Menu mainMenu = new Menu(dataManager,world);
//world = dataManager.LoadFile("Games\\test game.xml");
//the commented line above is correcting my bug but I don't want
//to do it that way.
List <Location> locs = world.GetAllLocations();
//when the debug mode arrives at this point, world is empty.
}
}
public class Menu
{
DataManager dataManager ;
World world;
public Menu(DataManager _dataManager, World _world)
{
this.dataManager = _dataManager;
this.world = _world;
world = dataManager.LoadFile("Games\\test game.xml");
//the world is filled correctly here above.
}
}
Both classes are sharing the same namespace. My dataManager fill the world with an xml, which is perfectly working. the world should be the reference from the game.world property but it seems to become empty as soon as we come back in the Game class...
I really don't understand while the program behave that way. Here is the complete source if you need more:
https://github.com/mikyjax/TextAdventureGameEditor/tree/master/Text%20Adventure%20Engine
Upvotes: 3
Views: 897
Reputation: 62213
That is not how references work.
new Menu(dataManager,world);
<= you call the constructor and pass in the world
instance created in the constructor (this is not the same as passing in a reference).this.world = dataManager.LoadFile("Games\\test game.xml")
<= A new instance is created (so new pointer) and assigned to the local variable world
. What does NOT happen is that the calling method in run
now share the same world
instance, that is still null
.If that is what you intended you must use the ref keyword (or out
).
public Menu(DataManager _dataManager, ref World _world)
and call it with
new Menu(dataManager,ref world);
That said this is bad practice on 2 levels.
public class Menu {
DataManager dataManager ;
World world;
public Menu(DataManager _dataManager)
{
this.dataManager = _dataManager;
}
public World CreateWorld() {
if(this.world == null)
this.world = dataManager.LoadFile("Games\\test game.xml");
return this.world;
}
}
public class Game {
World world;
public void Run()
{
Menu mainMenu = new Menu(dataManager);
this.world = mainMenu.CreateWorld();
}
}
Upvotes: 4
Reputation: 51623
Your code makes something akin to:
A = B
A = C
and then you wonder why B
is not C
as well: you set the Menu.World = _world
and then rewrite Menu.Wold
to be what you load from the xml: _world
is unmodified by it.
Why has the Menu
constructor to populate the world at all - thats not really one its sole responsibility - is it?
I would rename your static LoadFile
to CreateWorld(..filename..)
and call that inside the Run
method before creating the Menu. That way you can give the prepared World
to the Menu constructor.
What I am still wondering about is, why ever a menu needs access to your raw world data ...
Upvotes: 1