Extending Singletons?

BlitzMax Forums/BlitzMax Programming/Extending Singletons?

Gabriel(Posted 2006) [#1]
This is probably going to be my OOP-ignorance again, but I have a bunch of types/classes which will never have more than one instance. Ideally, it would be easier to have them as singletons. IE: no fields, no methods, just globals and functions.

Problem is, these classes/types are part of a graphics engine which is completely abstracted from the renderer. So there's an abstract base type which is then extended to provide the render functionality. I can't find a way to put the two together. Sure, I can just use TVEngine.Blah() instead of GameEngine.Blah() but that's dangerous because I'm sidestepping the base class altogether and potentially using functionality which is not identical between the base and derived classes. In other words, if I forget to get the abstraction right on some functionality, my game won't notice and won't care, because it's not using the abstract class at all.

Is there any way to do this or do I simply have to have an instance of my class, even though it doesn't strictly speaking need to exist?


FlameDuck(Posted 2006) [#2]
IE: no fields, no methods, just globals and functions.
Actually, a 'proper' Singleton has mostly methods and fields - but only one function (getInstance). Like so:
'Hello World Singleton example - by FlameDuck
SuperStrict

Type Singleton Final ' It needs to not be extendable to ensure that there truely is only one object in play at any time.
	Global myInstance:Singleton' This should actually be Private, so that it is only accessible to the Singleton in question. 
	Field somedata:String

	'Here you would normally have a private constructor, again to prevent other classes from arbitrarilly creating their own instances.
	'BlitzMAX dose not properly support access modifiers, so you'll have to be a better programmer, and remember not to do it yourself. Ever.

	Function getInstance:Singleton()
		If myInstance = Null
			myInstance = New Singleton
		End If
		Return myInstance
	End Function
	
	Method someMethod:String()
		Return somedata
	End Method
	
	Method someotherMethod( aString:String )
		somedata = aString
	End Method
End Type

Singleton.getInstance().someOtherMethod("Hello World")
Print Singleton.getInstance().someMethod()
Ofcourse there is no way to currently do this 'right' in BlitzMAX.


Paposo(Posted 2006) [#3]
Hello.

Any other methode is use de New method like:

method new()
if myInstance=null
myInstance=self
endif
return myInstance
endmethod

Using this methode the class are extensible. the new method is called for all class in correctly order

Bye,
Ramon


Gabriel(Posted 2006) [#4]
Those are both pretty much what I'm doing now. Except that I'm using a global outside the type instead of inside to store it. The principle is the same though.

I was trying to find a way to do it with a type which consists entirely of "statics" though. I guess that's not really possible/practical when you want to extend the type?


Dreamora(Posted 2006) [#5]
Depends on what you exactly want to achieve.

Globals within a type only exist ones within all extended types.
If you want to prevent that more than 1 instance is created, how about a global that saves the single allowed instance?
If a further one should be created just return that already existing one.

There are many ways like that, don't know if this is actually a way for you ...


Paposo(Posted 2006) [#6]
If you use a singleton class you not need put the instance in a extern global.
You acces to the same instance calling the class constructor.

In all parts of the code the call "new Singleton" offer same instance.

Is posible use a function for acces a static global var for not use the new operator. like:
Singleton.getInstance()

I not test the ultimate paragraph. Sorry.

Bye
Ramon


Gabriel(Posted 2006) [#7]
Yes, your previous reply doesn't work. You can't return anything but an int from a New() method. Looks like I'll have to stay as I was.


Paposo(Posted 2006) [#8]
Gabriel.

You are correct.
The new method not return anything.
Eliminating the line return myInstance and creating one function for get myInstance is possible.
You create a instance initially and it is not recolected for GC. It contains one reference of self.

Bye,
paposo