Páginas

segunda-feira, 9 de abril de 2018

Parameters by reference, raw pointer, smart pointer… THAT’S CRAZY!

C++ is a very flexible language which allows the programmers to decide how to handle memory allocation and deallocation. With this power, comes the responsibility of deciding and keeping the integrity of resources ownership. Then, with the new C++ 11 and onwards standards, move operations and standard operations are also players.

Now to the point of this post. How to pass things by parameters!? There are many possibilities, and without any kind of guidelines, it is easy to step into the horrible realm of code insanity. The guidelines I’m posting here are ones that I came up while reading discussions on stackoverflow and blogs, and consolidated with my own experience while programming Heldelland. For pointers and references:

  • Pass object by reference, if nullptr is not a valid input value;
  • Pass a raw pointer to object, if nullptr is a valid input value.

In both cases above, the caller must guarantee data validity while the method or function executes. If it was a constructor, the data must outlive the created object, if it stores the reference/pointer. It is preferred to pass by reference if nullptr is not a valid (non-error) input. This way, propagation of null checks can be avoided:

  • Pass unique pointers only if it is possible to happen an ownership change. They should be passed by non-const reference.

The idea behind passing non-const reference is that it makes clear that the method might acquire ownership of the passed address. If no such ownership change is possible, a pass by a raw pointer or reference is preferred. If the unique pointer is not passed by reference, the caller will need to move it, potentially resulting in deallocated object if an error happens before the called method changes ownership:

  • Pass shared pointers by constant reference, if no more shared ownership will be added;
  • Pass shared pointers by copy, if more shared ownership will be added

Passing shared pointers by copy feels dull, but you can actually move it to its destination, avoiding references counting updates as you store it.

segunda-feira, 19 de fevereiro de 2018

Controlling public methods access without using friends

Programming is a hard task that can become overwhelming as systems grows and more dependencies and different libraries, and internal and external code are used together to execute the many tasks needed by the resulting software. In order to reduce this complexity, there are many coding guidelines to help us – which one of them is “make your API easy to use correctly, hard to use incorrectly”. Careful planning and functionalities “blocking” can make a project to proceed smoothly, where it would be a nuclear insanity reactor otherwise.

There are many techniques and idioms to try to make a class hard to misuse in C++ (and many other languages), but the focus of this post is on a specific concept: controlling who can access the private methods of which classes. I’ll talk about one way of achieving this.

This private access control can be really useful. Let’s say, for example, that you have a class that can be publicly used. However, for reasons like instances tracking or resources management, you want it to be instantiated only by a specific Factory and consumed only by a certain type. This can be achieved by making the constructor private, and then using friend methods or classes.

class Medicine
{
    friend class MedicineFactory;
    friend class SickPerson;
public:
    ~Medicine();
    std::string GetName();
    
private:
    explicit Medicine(std::string name);
    void Consume();
    
    std::string m_Name;
};

In the above example, we have the medicine class. It’s constructor and Consume methods are both private, so they’re accessible only to both friend classes: MedicineFactory and SickPerson. No other classes can instantiate a medicine or consume it. But there is a catch: since they’re friend classes, it is then possible that, by accident or misinformation, a MedicineFactory end up accidentally consuming a medicine or, even worse, a SickPerson to home brew medicine.

What we want to do here is to make sure that only MedicineFactory instantiates medicine, and only SickPerson consumes it. Of course, a solution that wouldn’t get in the way of helping methods and classes such as std::make_unique or std::make_shared is a plus. There are ways to handle this situation, but I’ll focus on the Passkey Idiom. This idiom allows us to make methods callable only by instances of classes that can instantiate a given key. Using classes as keys, the Medicine class could be written as:

class Medicine
{
public:
    Medicine(std::string name, const PasskeyIdiom<MedicineFactory>&);
    ~Medicine();
    
    std::string GetName();
    void Consume(const PasskeyIdiom<SickPerson>&);
    
private:
    std::string m_Name;
};

What changed is that now the constructor and Consume method both have a new parameter.As long as we can guarantee that only MedicineFactory can instantiate PasskeyIdiom, then only methods within the factory class will be able to create new instances of Medicine even with the public constructor. Of course, the same applies to the Consume method and SickPerson class. Note that the parameters are constant references to the PasskeyIdiom class. This allows us to bind the parameters to rvalues, shortening the coded needed to call these methods.

The trick lies within the PasskeyIdiom class template:

template <typename T>
class PasskeyIdiom
{
private:
    friend T;

    PasskeyIdiom() = default;
    PasskeyIdiom(const PasskeyIdiom&) = default;
    PasskeyIdiom(PasskeyIdiom&&) = default;

    PasskeyIdiom& operator=(const PasskeyIdiom&) = delete;

    ~PasskeyIdiom() = default;
};

The three constructors, the destructor and the assignment operator are all defaulted on private accessibility. The “friend T” constructor, possible from C++ 11 onwards, makes it so that only instances or static methods of T can instantiate or uses new objects from the idiom, specialized to T itself. It works quite well – even with smart pointers.

Here’s a full code testing the idiom:

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
#include<iostream>
#include<memory>



class Medicine;
class MedicineFactory;
class SickPerson;



template <typename T>
class PasskeyIdiom
{
private:
    friend T;

    // Defaulted on private, to avoid public defaults
    PasskeyIdiom() = default;
    PasskeyIdiom(const PasskeyIdiom&) = default;
    PasskeyIdiom(PasskeyIdiom&&) = default;

    ~PasskeyIdiom() = default;

    PasskeyIdiom& operator=(const PasskeyIdiom&) = delete;
};



class Medicine
{
public:
    Medicine(std::string name, const PasskeyIdiom<MedicineFactory>&)
        : m_Name(name) {}

    void Consume(const PasskeyIdiom<SickPerson>&)
    {
        std::cout << "Medicine " + m_Name + " has been consumed" << std::endl;
    }

private:
    std::string m_Name;
};



class MedicineFactory
{
public:
    std::unique_ptr<Medicine> InstantiateMedicine(std::string name)
    {
        return std::make_unique<Medicine>(name, PasskeyIdiom<MedicineFactory>{});
    }
};



class SickPerson
{
public:
    void ConsumeMedicine(Medicine& medicine)
    {
        medicine.Consume(PasskeyIdiom<SickPerson>{});
    }
};



int main() {
    MedicineFactory medicineFactory{};
    auto medicine = medicineFactory.InstantiateMedicine("Antibiotic");
    
    SickPerson sickPerson{};
    sickPerson.ConsumeMedicine(*medicine);

    // These won't compile

    /*

    // Private constructors and destructors
    PasskeyIdiom<MedicineFactory> medicineFactoryPasskey{};


    class IllegalMedicineFactory
    {
        // Cant use another class as passkey
        std::unique_ptr<Medicine> InstantiateMedicine(std::string name)
        {
            return std::make_unique<Medicine>(name, PasskeyIdiom<MedicineFactory>{});
        }

        // No overloaded constructor on Medicine
        std::unique_ptr<Medicine> InstantiateMedicine(std::string name)
        {
            return std::make_unique<Medicine>(name, PasskeyIdiom<IllegalMedicineFactory>{});
        }
    }

    */

    return 0;
}
All code in this page has been colored by hilite.me.

segunda-feira, 22 de janeiro de 2018

Strong Typed Identifier

Recently, I’ve got into one of these hard-to-track bugs that after a while in debug, you just “ah-hah!” and facepalm at the source reason. In my situation, it was because of two different classes using the same type for identifier types. For example, let’s assume two classes like this:

using CheeseId = unsigned int;
class Cheese
{
public:
    /* public interface */
    
    CheeseId GetId() const;
    
private:
    CheeseId m_CheeseId;
};


using SwordId = unsigned int;
class Sword
{
public:
    /* public interface */
    
    SwordId GetId();
    
private:
    SwordId m_SwordId;
};

The CheeseId and SwordId classes each have their own identifier type set up by the using directive. Since identifiers only make sense if there are different instances over time (as in collections), they could be used, or even stored, by the instances owner. For example, let’s say this manager class:

/* Assume this class is responsible for cheese memory */
class CheeseCollectionManager
{
public:
    /* public interface */
    Cheese* InstantiateCheese();
    Cheese* FindCheese(CheeseId id) const;
    void EatCheese(CheeseId id) const;
    
    /* more stuff */
};

This is a simple example of a manager class that holds unique ownership over instances, and allows some basic operations if the identifiers are known. A Cheese can be created into the world by using InstantiateCheese, and will be destroyed when it is eaten with EatCheese. Now, let’s suppose we have a CheeseEatingGladiator executing his day off actions:

class CheeseEatingGladiator
{
public:
    /* Some Other Code */
    
    void DayOffLunchTime()
    {
        m_CheeseCollectionManager.EatCheese(SwordId); // Oops
        CheeseId = Cheese::NoCheeseid;
    }

private:
    CheeseCollectionManager* m_CheeseCollectionManager;
    SwordId m_EquippedSword;
    CheeseId m_CheeseForLunch;
};

Oops!? When coding, I’ve accidentally passed the SwordId to the EatCheese method. This compiled because both are of unsigned int type, resulting in random behavior. If both identifiers are the same, the code will work correctly – uncareful automatic tests might trip on this. If they are different, some random Cheese will suddenly disappear, and there’ll be a Cheese which no one might ever be able to eat, as the gladiator forgot the identifier right after eating. Worse yet, the SwordId might request for a non-existent Cheese, and the whole world will stop existing because the gladiator has segfault.

The best way to avoid an error in a system, even if caused by its programmers, is to make the error impossible to happen. If the compiler could detect we mixed up the CheeseId with SwordId and show a compile-time error, the error would be immediately detected before even trying to run the code. In other words, the problem is how to make a strong typed identifier. The solution is very simple:

struct CheeseId
{
    unsigned int value;
};

struct SwordId
{
    unsigned int value;
};

Now CheeseId and SwordId can’t be mixed up! It is possible to make the code even safer by making it harder for the programmer to manipulate the value inside the structs. For example:

struct CheeseId
{
    explicit CheeseId(unsigned int value) : m_Value(v) {}
    CheeseId(const CheeseId& other) : m_Value(other.m_value) {}
    
    const CheeseId& operator=(const CheeseId& other)
    {
        m_Value = other.Value;
        return *this;
    }
    
    unsigned int Value() const { return m_value }
    
private:
    unsigned int m_Value;
};

With this, the problem of mixing different types of identifiers won’t happen again, and the risk of using an incorrect unsigned int as the identifier is mostly mitigated.

Problem solved!!!

But not.

Now there’s a new problem: the amount of boilerplate code needed for each type of identifier. If we have on the dozens, the above code would repeat on dozens. But then, when you start needing other functionalities such as hash codes or converting to strings, DRY (Don’t Repeat Yourself) will prove why it is such a good principle. Of course, C++ has a simple way to deal with this… templates! But whenever templates comes up as an alternative, together comes a whole set of possibilities with pros and cons. I chose something like traits. Tag types or other techniques are also possible.

template <typename IdTraits>
struct IdType
{
    using underlying_type = typename IdTraits::underlying_type;

    IdType() {};
    IdType(const IdType& other);
    explicit IdType(underlying_type id);
    
    underlying_type Value() const;
    std::string ToString() const;

    bool operator==(const IdType& right) const;
    bool operator!=(const IdType& right) const;
    
private:
    underlying_type m_Value;
};

I’ve omitted the functions definitions. Creating a new identifier type now is simple:

struct CheeseIdTraits
{
    using underlying_type = unsigned int;
    
    // Called from IdType::ToString
    std::string ToString(underlying_type id) const
    {
        // Logic here
    }
};

using CheeseId = IdType<CheeseId>;

Of course, there are some improvements that could be made, specially with the help of metaprogramming, but as it is, the IdType using type traits seems good enough for my needs. I took this chance to learn a bit more about how to use templates, and the final solution was achieved with the help of amazing people from gamedev forums (on this topic ).

Changing my code to use strong typed identifiers revealed a couple more mistakes. These were harmless, but it is good to solve these before they take their part into a big, hard to track and hard to reproduce bug.

Syntax coloring on this page was made on hilite.me.

domingo, 7 de janeiro de 2018

Updates on the Heldelland project

It’s been, yet again, a long time since my last post. Truly enough, programming a game on free time really goes way slower than I ever thought it would be. Nevertheless, the project is still going on and increasing a little bit on every week. I decided to open the source before releasing the game itself, since the project is for learning purposes. The code can be found on Bitbucket (link).

As of now, you can’t build it since it depends on Suna, a simple lib that I’ll open source it when it becomes the bare minimum to become acceptable to exist. If you want to build it anyway, get in touch that I’ll send the includes and lib file.

What has happened in this last year? The yaml prefab loading is partially done, but then I halted it since it was not my immediate need. I did lots of code refactoring everywhere, to bring back some amount of sanity to the code – I’m gradually starting to believe that I’m following the KISS way of thinking based on a misleaded understanding. There is still a lot of code to refactor remaining…

Now I’m trying to bring some Data-Oriented Design to the game logic, and I’m also studying on how can I use templates, generics and perhaps metaprogramming to my day-to-day free time coding. I wish myself some luck!

quinta-feira, 3 de novembro de 2016

So, I need a prefab system.

For some time now, I’ve been able to load resources from meta files, which allowed me to change my resources without the need of code recompiling. As long as I didn’t need any new kind of resources or attributes, at least. In fact, I do need to recompile when I want to create or change my testing entities, their components or their attributes, and this is getting really annoying.

I could use a scripting language to build my objects on the fly, but in the end, making a prefab loading system seemed a better choice. The reason is simple: I won’t have any early glue dependency with any kind of scripting language, which is something I want right now.

So… where do I start? A prefab system is a whole scary system – that’s why there is the word SYSTEM in there.

As usual, when something is so huge that we can’t easily choose a starting point, and the team (of one) size is small, or available (free) time is too short, a good place to start is deciding on behavior, desired features, and then applying some constraints and compromises. Having said this, here is the rule set I came up with:

  •         [r1]: Prefabs can be loaded from any type of yaml string;
  •         [r2]: A single yaml string must have a single prefab;
  •         [r3]: I must be able to load prefab’s yaml from files. A file must be guaranteed to have only a single prefab;
  •         [r4]: Prefabs can be a hierarchy of entities. There must be a single root entity, and the hierarchy will be built on top of Transform components (warning: transforms are optional components on the entities. A single, transformless root, is valid. Hierarchy without transforms on all entities should be impossible);
  •         [r5]: Prefabs components and entities can only make references to other components of the same prefab;
  •         [r6]: Prefabs can make references to another prefab only if referring to its root entity (components would be nice, but I’m making a compromise here);
  •         [r7]: Any real game entity can only make references to a prefab root entity.
  •         [r8]: Prefabs won’t be manipulated at runtime, and thus can only have “clone entities” instantiated;
  •         [r9]: A prefab must have a special (not yaml) representation in memory. This representation must not be bound to any loading type or persistent storage type / technique. This is the actual “prefab” in memory.
  •         [r10]: When instantiating a “clone entity”, all references must be properly set, and all loading events of the components must be properly called.


Rules r1, r2 and r3 are straightforward in making me dependent of YAML. Limiting a single prefab per yaml “complete” string, and a “single” yaml string per file, I reduce some flexibility of information loading in order to speed up feature development – by means of simplification.

Rule r4 says that I can have prefabs that are actually a hierarchy of one or more entities. However, the topmost entity (the root) must be a single one - so, no two-or-more-headed-prefabs. This allows some flexibility in the system, while the single root constraint will simplify a lot features that are about prefabs referencing, such as rules r6 and r7. By allowing other prefabs and entities to refer only to roots, a lot of the complexity about many special situations is immediately cut out from the system.
Rules r5 and r8 are sanity rules, intending to cut out even more flexibility in order to simplify the development. Prefabs changing on the fly can induce headaches from situations such as roots suddenly missing some components, or having absurd values on attributes. Also, if prefabs had dependency on specific components of other prefabs, the indirect dependency would result in special cases when instancing the actual entities.

Rule r9 is very important, as it will force the prefab system to have its own way of storing the prefab in memory. Think of this as the “core” – the way of loading the prefabs are simply outer layers of this core, and thus I can change the technology without needing to change the prefab system itself. If I succeed in being smart enough, it might be possible to make an internal representation that can itself be changed without affecting the engine.

Finally, r10 is the whole point of doing all this. Looking back, this system sure will need a loooot of planning before going to coding phase. I’ll have to postpone this a bit more, in order to have ideas on how to structure this on classes and, maybe, interfaces. Please, do note, I didn’t make a single rule about “being fast”. I’m new to planning this kind of system from scratch, so it feels like “being fast” would instantly lead to premature optimization.


Hope I don’t overengineer this…

segunda-feira, 17 de outubro de 2016

Hierarchical Transforms

After I made a simple Transform component to handle positions, scales and rotations, I stopped working on it in order to code other things. Then, came the situation where I needed hierarchical transforms, if I wanted to keep other components simple – 9 patches graphics moving around, for example. Basically, the idea is to have a “parent transform” in which “children” will inherit its position, scale and rotation properties.

So, how can that be done?

Searching around, I found out that there are two simple ways of achieving this. One is simply recalculate all children whenever a parent has been changed. It’s creepy. The other way is setting a dirty flag, and then recalculate the parents and children as their information is needed. This is the one I did!

Whenever a transform has one of its properties changed, it sets itself and all children, recursively, as dirty. When something requests information such as position, it will check if the transform itself is dirty. If it is, it requests the parent information so that its own information can be built accordingly to the current hierarchy, and then sets itself to not dirty anymore. This is a recursive behavior.

In order to avoid too many recalculation requests, each transform keeps a copy of it’s current, “resulting” transformation matrix. This increases memory usage and also the chance of cache misses but, right now, it’s very simple to understand and use. One drawback, though, is that children and parents can’t be easily reprocessed in parallel.


So far, performance is acceptable. I mean, I have nothing on my game scene….

quarta-feira, 28 de setembro de 2016

Inversion of Control? Ok! Gonna try!

These past weeks a friend of mine has been sending me lots of links to videos, articles and posts about Dependency Injection and, naturally, inversion of control. It turns out that a week ago, I finished the very, very very minimal code needed to start Suna in c++:

  • A LocalHost class
  • A Channels class
  • An unreliable communication channel class
  • A wanna-be 3way handshake for starting connections on “application level”, by using UDP.


There’s enough stuff in there to start getting lost as I forget the code, but since it IS still small enough, I’ve decided to try to use a few of the concepts from inversion of control. Took a while to refactor nearly everything:
-       
  • ISocket, IEndpoint, IHost, INetworkPacket, Ietcetc. So many interfaces…
  • Constructor arguments, constructor arguments, constructor arguments….
  • Now it’s really easier to change stuff around.

      Overall, I’m liking the results even though I’m hating all the boilerplate code. It became clear that I need some kind of injector to spawn instances of my concepts, so later I’ll write some kind of abstract factory. Suna is meant to be a really small project, so probably a “poor man dependency injection” will be enough.