Memory Access Exception

Monkey Forums/Monkey Beginners/Memory Access Exception

Hero(Posted 2015) [#1]
Hi,

why does this create a memory access exception:

Strict
Import mojo
Import player

Class Playfield
	
	Const GridSizeX:Int = 32
	Const GridSizeY:Int = 32
	
	Global Instance:Playfield
	
	Public Field ScreenWidth:Int
	Public Field ScreenHeigth:Int
	Public Field PaddingX:Float
	Public Field PaddingY:Float
	
	Field Player:player.Player = New player.Player(32, 32, Instance)
	
	Function GetInstance:Playfield()
		If (Instance = Null)
			Instance = New Playfield()
		EndIf
		
		Return Instance
	End
	
	Method Init:Void(screenWidth:Int, screenHeight:Int)
		ScreenWidth = screenWidth
		ScreenHeigth = screenHeight
		PaddingX = (screenWidth Mod GridSizeX) / 2
		PaddingY = (screenHeight Mod GridSizeY) / 2
		
		Return
	End
		
	Method Render:Void()

		Player.Render()
	End
End
[/Code]

[Code]
Strict
Import mojo
Import playfield

Class Player

	Const HEIGHT:Int = 32
	Const WIDTH:Int = 32
			
	Field Playfield:playfield.Playfield
	
	Field PosX:Float
	Field PosY:Float
	
	Method New(posX:Int, posY:Int, playfield:playfield.Playfield)
		
		PosX = posX
		PosY = posY
		Playfield = playfield
		
	End
	
	Method Render:Void()
		SetColor(255, 0, 0)
		DrawCircle(Playfield.PaddingX + PosX, Playfield.PaddingY + PosY, WIDTH)
	End
End


The Exception is thrown when trying to access Playfield.PaddingX from the Player.Render Method.


AnotherMike(Posted 2015) [#2]
I haven't looked at it closely but I guess the "Instance" variable is simply null when you pass it to the player object. Doesn't it only get initialized when you call GetInstance()?


Hero(Posted 2015) [#3]
You are right. I had to move the instantiation of Player to the Playfield.Init Method.
Thanks.


ziggy(Posted 2015) [#4]
You're missing the oportunity of making a property-like function for your singleton. Having both a public Instance global and a GetInstance function is not very nice if you ask me.
I would make the Instance global private (named globalIntance or the like), and I would make the GetInstance a global property like this:
Strict
Import mojo
Import player

Class Playfield
	
	Const GridSizeX:Int = 32
	Const GridSizeY:Int = 32
		
	Public Field ScreenWidth:Int
	Public Field ScreenHeigth:Int
	Public Field PaddingX:Float
	Public Field PaddingY:Float
	
	Field Player:player.Player = New player.Player(32, 32, Instance)
	
	Function Instance:Playfield()
		If (_globalInstance = Null)
			_globalInstance = New Playfield()
		EndIf
		
		Return _globalInstance
	End
	
	Method Init:Void(screenWidth:Int, screenHeight:Int)
		ScreenWidth = screenWidth
		ScreenHeigth = screenHeight
		PaddingX = (screenWidth Mod GridSizeX) / 2
		PaddingY = (screenHeight Mod GridSizeY) / 2
		
		Return
	End
		
	Method Render:Void()

		Player.Render()
	End

	Private
	Global _globalInstance:Playfield

End

This way, you can't ever have a null "Instance", no mater where or who calls it. It's like a inmutable and not nullable field.


Hero(Posted 2015) [#5]
You are right ziggy. This is a good suggestion. Thank you.