I am currently working on a voxel (Minecraft-like) engine in C++. Almost all of the code (ie. world generation, rendering, user input) needs to access data about the block types. To accomplish this, I created a BlockRegistry class with member functions to register and access BlockType instances. Each BlockType instance has member functions to access all of it's properties (ie. textures, shape). The problem I am having is making sure that all parts of the code have access to this class. Right now, I am passing around a pointer to it, but this increases coupling greatly since, for example, if a class b provides something that class a needs, and class b needs to access the block registry, I need to modify class a and everywhere I am using class a to pass it through.

My first thought was to use the singleton pattern (or a class with all static members), but, from what I understand a singleton pattern should only be used if the singleton does not have any state, which isn't the case because the BlockRegistry stores a modifiable block list. Making this block list immutable isn't an option, because that makes mod support impossible. Additionally, if, somehow, different instances of the game end up running in the same process and require separate BlockRegistries this would be a nightmare to factor out. Should I even be worrying about this?

The other option I am thinking of is to have a single "main" class with members for the BlockRegistry, World (basically an infinite paged array to store all the data in the in-game world), OpenGl engine, and other commonly used features, in which case I can pass a pointer to my main class around. I would then pass a pointer to this class around to all parts of the program, since then adding new commonly used classes is as simple as adding a member to this main class. This also solves the issue of having multiple instances of the voxel engine in the same process.

When I have a class that I need many parts of the program to access, should it be a singleton or passed around with a main class? If it should be a singleton, should I do that in the form of a static class or an actual singleton?

  • It could be a matter of opinion or taste. – Basile Starynkevitch Jun 20 '17 at 7:45
  • @basilestarynkevitch A good answer would list the pros and cons of different approaches. – john01dav Jun 20 '17 at 7:47

There's no reason why a singleton can't have state, but singletons are frowned upon by a lot of people.

Would it be better to pass a reference to the BlockRegistry into the constructor of any classes that need it, rather than cluttering up the individual methods? Make sure the BlockRegistry is constructed right at the start, then pass it into the constructors of your major objects, which can pass it down further as required.

  • That's what I am doing, but my hierarchy is several layers deep and it is very combersome to refactor all of the constructors in the hierarchy every time a new use for it appears. Also, doing that in previous projects, I've ended up with 30 parameter constructors for all of the objects that provide common services, this seems a bit extreme to me. – john01dav Jun 20 '17 at 7:53
  • 1
    @john01dav If your object has 30 dependencies then you have a problem. Making the dependencies global state won't solve the problem even if the constructor looks nicer. – Goyo Jun 20 '17 at 8:33
  • @john01dav 30-parameter constructors are a sign of a problem. Either clump together closely-related ones into objects-of-objects, or (better) create new objects that know about those 30 objects, and which have methods to do whatever it is that you want to do to them - so you don't have to pass everything down to every object. – Simon B Jun 20 '17 at 16:07
  • So, basically, I should use a main class as I described in the question? Also, why are singletons frowned upon? – john01dav Jun 20 '17 at 16:10
  • @john01dav possibly, but don't forget the Single Responsibility Principle. Avoid creating "god objects" that just do everything. As for singletons, Google "singleton antipattern". – Simon B Jun 20 '17 at 16:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.