0

I have a little engine (defined as public class ScreenManager : DrawableGameComponent) to manage input and screens (with transitions etc.), who works with a public abstract class GameScreen. For menu screens I have an abstract class MenuScreen : GameScreen. I'm trying to get from class OptionsMenuScreen : MenuScreen a value stored in the main class of the game (the one called by Program.cs), but I always get NullReferenceException. I need that value because while starting application I need to get some option and these options can be changed from OptionsMenuScreen, but I want that changes from that screen automatically reflects on the rest of application, so a screen can base it's computation on that value, without force the user to reload entire application to get values in main class updated. I do this with

public ScreenManager ScreenManager
{
    get { return screenManager; }
    internal set { screenManager = value; }
}

ScreenManager screenManager;

in GameScreen.cs and

/// <summary>
/// Adds a new screen to the screen manager.
/// </summary>
public void AddScreen(GameScreen screen, PlayerIndex? controllingPlayer)
{
    screen.ControllingPlayer = controllingPlayer;
    screen.ScreenManager = this;
    screen.IsExiting = false;

    // If we have a graphics device, tell the screen to load content.
    if (isInitialized)
    {
        screen.LoadContent();
    }

    screens.Add(screen);

    // update the TouchPanel to respond to gestures this screen is interested in
    TouchPanel.EnabledGestures = screen.EnabledGestures;
}

as method to add a Screen to ScreenManager' list of screens. But when I try to do something like

separateAxis = (ScreenManager.GameInstance as Main).SeparateAxis;

I get always NullReferenceException. Despite it works from other Screens (deriving directly from GameScreen, not MenuScreen).

Any ideas?

abatishchev
  • 98,240
  • 88
  • 296
  • 433
Giorgio Aresu
  • 1,138
  • 1
  • 7
  • 9
  • 1
    Does `((Main)ScreenManager.GameInstance).SeparateAxis` work? Do you know how `as` works? Writing `(ScreenManager.GameInstance as Main).SeparateAxis` instead of `((Main)ScreenManager.GameInstance).SeparateAxis` is asking for this kind of trouble. – R. Martinho Fernandes Nov 15 '11 at 11:01
  • Relevant: [What is a NullReferenceException in .NET?](http://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-in-net) – R. Martinho Fernandes Nov 15 '11 at 11:03
  • 1
    When do you call the problem line, is it in the consturctor of the screen, in which case the screenmanager won't be assigned a value yet. – George Duckett Nov 15 '11 at 11:17
  • It doesn't work neither casting with (Main), in fact this was my first try. Even if I move the line outside the constructor, in another method it always gives exception on ScreenManager – Giorgio Aresu Nov 15 '11 at 15:32

1 Answers1

1

There are 2 posibilies from your code, either ScreenManager is null, or (ScreenManager.GameInstance as Main) is.


For the first case:

I think you're calling your problem line from within the option screen's constructor, or at least before the screenmanager's AddScreen method is called.

Move it to the screen's LoadContent method.

For the second case:

Check that GameInstance is an instance of Main.


It's worth noting that this is the GameStateManagement sample you're basing your code on.

Community
  • 1
  • 1
George Duckett
  • 31,770
  • 9
  • 95
  • 162
  • Yes, I applied that engine to my application. And yes, GameInstance is an instance of Main (in fact Main is of type Game and also GameInstance obviously is). But also trying to put that in one of the events (the LoadContent it's not there by default, I can add if it serves) it gives the same exception... – Giorgio Aresu Nov 15 '11 at 15:35
  • 1
    Put a breakpoint on that line of code. Hover your cursor over `ScreenManager`. Is it null? Hover over the `as`, is that expression null? Override the `GameScreen`'s `LoadContent` method in your `OptionsScreen`, and put the code there. That should work. – George Duckett Nov 15 '11 at 15:37