so I'm working on a text based game and I'm running into an issue of an aray of object not being populated properly during run-time. I'm not entirely sure why this is happening, but here is the code:
public class Area
{
public List<Area> options;
public string name;
public string text;
public uint time;
private void loadOptions()
{
MainWindow.app.options.Children.Clear();
for(int i = 0; i < options.Count(); i++)
{
Button b = new Button();
b.Content = options[i].name;
b.Name = "b"+i;
b.Click += new RoutedEventHandler(optionClick);
MainWindow.app.options.Children.Add(b);
}
}
private void optionClick(object sender, EventArgs e)
{
Button clicked = (Button)sender;
int index = Int32.Parse(clicked.Name.Split('b')[1]);
options[index].load();
}
public void load()
{
loadOptions();
MainWindow.app.mainText.SelectAll();
MainWindow.app.mainText.Selection.Text = text;
}
}
that is the logic portion of the Area class, and I'm holding all the other areas in a seperate file, in an Areas class, shown here:
public static class Areas
{
public static Area opening = new Area()
{
name = "Opening",
text = "This is the first area, just a test for now, but will be fully filled out at a later time",
time = 0,
options = new List<Area>()
{
second
}
};
public static Area second = new Area()
{
name = "second",
text = "this is the second area for stuffs and stuffs",
time = 0,
options = new List<Area>()
{
opening
}
};
}
both are a part of the same namespace, but are in separate files for readability. The idea is that the options array holds all the possible menus that the player can go to from that menue. the first test area's code is this:
public Area test = new Area()
{
text = "This is yet another test to test stuffs and things and places",
time = 0,
options = new List<Area>
{
Areas.opening
}
};
and that loads properly, but as soon as I click on the button, the entire thing crashes and throws a null reference exception.
Here are the details of the error:
System.NullReferenceException
HResult=0x80004003
Message=Object reference not set to an instance of an object.
Source=LostWorlds
StackTrace:
at LostWorlds.Area.loadOptions() in C:\Users\Max\source\repos\LostWorlds\LostWorlds\LostWorlds\MainWindow.xaml.cs:line 356
at LostWorlds.Area.load() in C:\Users\Max\source\repos\LostWorlds\LostWorlds\LostWorlds\MainWindow.xaml.cs:line 373
at LostWorlds.Area.optionClick(Object sender, EventArgs e) in C:\Users\Max\source\repos\LostWorlds\LostWorlds\LostWorlds\MainWindow.xaml.cs:line 368
at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
at System.Windows.UIElement.RaiseEvent(RoutedEventArgs e)
at System.Windows.Controls.Primitives.ButtonBase.OnClick()
at System.Windows.Controls.Button.OnClick()
at System.Windows.Controls.Primitives.ButtonBase.OnMouseLeftButtonUp(MouseButtonEventArgs e)
at System.Windows.UIElement.OnMouseLeftButtonUpThunk(Object sender, MouseButtonEventArgs e)
at System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget)
at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
at System.Windows.UIElement.ReRaiseEventAs(DependencyObject sender, RoutedEventArgs args, RoutedEvent newEvent)
at System.Windows.UIElement.OnMouseUpThunk(Object sender, MouseButtonEventArgs e)
at System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget)
at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
at System.Windows.UIElement.RaiseTrustedEvent(RoutedEventArgs args)
at System.Windows.UIElement.RaiseEvent(RoutedEventArgs args, Boolean trusted)
at System.Windows.Input.InputManager.ProcessStagingArea()
at System.Windows.Input.InputManager.ProcessInput(InputEventArgs input)
at System.Windows.Input.InputProviderSite.ReportInput(InputReport inputReport)
at System.Windows.Interop.HwndMouseInputProvider.ReportInput(IntPtr hwnd, InputMode mode, Int32 timestamp, RawMouseActions actions, Int32 x, Int32 y, Int32 wheel)
at System.Windows.Interop.HwndMouseInputProvider.FilterMessage(IntPtr hwnd, WindowMessage msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at System.Windows.Interop.HwndSource.InputFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)
at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
at System.Windows.Application.RunDispatcher(Object ignore)
at System.Windows.Application.RunInternal(Window window)
at System.Windows.Application.Run(Window window)
at System.Windows.Application.Run()
at LostWorlds.App.Main()
from what I've gathered, there's some issue with populating the area's options list with the objects in the static class Areas, whenever I look at the values of the list, it has one entry that is null.
I came to realize that this is an issue with Hoisting, because "opening" referenced "second" before "second" was declared, "opening" didn't have anything to populate itself with, and thus returned a null reference. so the solution is to do as follows:
public static Area second = new Area()
{
name = "second",
text = "this is the second area for stuffs and stuffs",
time = 0,
options = new List<Area>()
{
opening
}
};
public static Area opening = new Area()
{
name = "Opening",
text = "This is the first area, just a test for now, but will be fully filled out at a later time",
time = 0,
options = new List<Area>()
{
second
}
};
not entirely sure yet how to make the references cyclical, but I'm sure I can figure it out.
User contributions licensed under CC BY-SA 3.0