Best way to implement singletons?


#1

Hi

What is the best way to implement singletons in Haxe? I can make a class and pass it between subclasses etc but I do not want to do that is possible. I am looking for a simpler way to do that as the singleton pattern supposed to keep things simple. It would be nice all instanced classes can access this data without passing them around to keep it simple.

https://en.m.wikipedia.org/wiki/Singleton_pattern////


#2

Here’s my favorite way:

class MySingleton {
    public static var instance(get, null):MySingleton;
    private static function get_instance():MySingleton {
        if(instance == null) {
            instance = new MySingleton();
        }
        return instance;
    }
}

Now you can access MySingleton.instance from anywhere.


#3

A common way to do this is as follows:

class someClass {
   // You refer to "someClass.instance.<<whatever>>"
   static public var instance(get_instance, never) : someClass; 
   //
   // This is the "secret stash" that holds the instance itself.
   static private var _INSTANCE : someClass;
   //
   // ... and here's the code that does the magic:
   static public function get_instance():AwayStats {
     return (_INSTANCE != null) ? 
       _INSTANCE : 
       _INSTANCE = new someClass();
    }
    ...
}

The various modules in your application simply refer to “someClass.instance.whatever

Because both the getter-function and the corresponding (private …) variable have been defined to be “static,” they belong to the class, not to any particular object-instance. The first caller causes the object to be instantiated. All subsequent calls return the same object. (Note that this technique is, at least theoretically, “not thread-safe,” since … in your computer-science class, at least … a race could occur to instantiate the variable.)


#4

For the record, Mike’s way is equivalent to mine, only slightly more verbose.


#5

Thanks guys, great help.


#6

Hi

I might be doing something wrong here, but openfl complaints that the singleton class does not have a constructor.


#7

You do need to make a constructor for it. Make it private if you like, because it will only need to be called in the get_instance() function.


#8
class MySingleton {    
    static public var instance(get, null):MySingleton;
    static function get_instance(): MySingleton return (instance == null) ? instance = new MySingleton() : instance;    
    // ...
    private function new() {}
}

For the record, player_03’s version is equivalent to mine, only slightly more verbose… :wink:


#9

Of course, Haxe is Haxe, and there’s a macro for Singletons too:


:smile:


#10

Well played.

I made a better version:


#11

Great!
(Writing something here, just becuse this forum requires posts to have more than 20 chars…)


#12

@player_03 couldn’t the macro create the constructor too?


#13

Done.

It will now define a constructor if you haven’t defined one yourself. (Which you’ll have to do if you need to supply arguments to the superclass constructor.)


#14

I added that using haxelib install (https://github.com/DelishusCake/Singleton) and it seems to be working pretty well. And advantage of others over this one?


#15

In the haxelib version, Singleton is a class, and you can only extend one class at a time. If you want a singleton of a display object, you’re out of luck.

In my version, it’s an interface, so it doesn’t get in the way. (You can implement as many interfaces as you want.)

Also, my version requires slightly less code - you only have to type ClassName.instance, rather than ClassName.getInstance().


#16

@player_03

That is great. Is this on haxelib?


#17

No, not yet. I submitted a pull request, but it’s up to DelishusCake to accept it. I guess I could submit it under a different name, but that’s far from ideal.


#18

Thanks for the update. Please let us know when it is there. I prefer to use Haxelib since it is easier to manage.


#19

Oof, three years later and the Haxelib version still isn’t updated. I went ahead and submitted my version as a separate library instead.

I know everyone involved in this thread has probably moved on, but I’m doing this anyway, in case someone new stops by.