<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Raviola</title>
    <description>The latest articles on DEV Community by Raviola (@feresr).</description>
    <link>https://dev.to/feresr</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2544%2F9f3ef0a4-be98-49c5-8ac8-1b60017b91fb.jpeg</url>
      <title>DEV Community: Raviola</title>
      <link>https://dev.to/feresr</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/feresr"/>
    <language>en</language>
    <item>
      <title>A case against the MVI architecture pattern</title>
      <dc:creator>Raviola</dc:creator>
      <pubDate>Mon, 12 Apr 2021 16:56:02 +0000</pubDate>
      <link>https://dev.to/feresr/a-case-against-the-mvi-architecture-pattern-1add</link>
      <guid>https://dev.to/feresr/a-case-against-the-mvi-architecture-pattern-1add</guid>
      <description>&lt;p&gt;The opinions in this article are based on my own experience working with different implementations of MVI in both personal projects and at my day job.&lt;/p&gt;

&lt;p&gt;To begin with, let me say I recognise how appealing MVI looks at first sight. It combines battle tested patterns like Command and Observer and makes good use of functional reactive programming techniques. In short, MVI sort of defines a meta-architecture favouring classes instead of functions and where every action the user can take is defined by an &lt;code&gt;Input&lt;/code&gt; class and every state a view can be in must also be defined by a subclass of the &lt;code&gt;State&lt;/code&gt; class. &lt;/p&gt;

&lt;p&gt;I'm assuming you already know how this works, there are more classes like these in MVI including &lt;code&gt;Action&lt;/code&gt;s, &lt;code&gt;Result&lt;/code&gt;s;  among others, depending on each specific implementation. &lt;/p&gt;

&lt;h2&gt;
  
  
  The problem with MVI
&lt;/h2&gt;

&lt;p&gt;My biggest pet peeve with this architecture is &lt;strong&gt;NOT&lt;/strong&gt; how boiler-platy it can get, or how opinionated certain implementations can be. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;My biggest problem with this architecture is how much it hurts overall code readability and in turn, developer happiness.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In my opinion, traditional MVI implementations artificially group ‘unrelated code’ together and encourages ‘related code’ to be spread out among as many different classes as possible (low coupling, high cohesion)&lt;br&gt;
That's a big claim, let me explain what I mean.&lt;/p&gt;

&lt;p&gt;When writing a new piece of code, you only care about the feature you are writing/reading and not much else. If you are fixing a bug, you are usually focused on a specific flow where the bug is happening, trying as hard as you can to reproduce it. &lt;strong&gt;The faster you can build a mental model of how this feature works the faster you'll fix the bug&lt;/strong&gt;. So it helps if the code for the feature grouped together and isolated from any other feature.&lt;/p&gt;

&lt;p&gt;Unfortunately, this is usually how code ends up looking in MVI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;intentToAction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;intent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;HomeIntent&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nc"&gt;HomeAction&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;intent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="nc"&gt;HomeIntent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;LoadAllCharacters&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;HomeAction&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;AllCharacters&lt;/span&gt;
            &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="nc"&gt;HomeIntent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ClearSearch&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;HomeAction&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;AllCharacters&lt;/span&gt;
            &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="nc"&gt;HomeIntent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;SearchCharacter&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;HomeAction&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;SearchCharacters&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;intent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;See how all features are intertwined among other completely unrelated features in that snippet? You probably only care about one single line in that method at a time.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In other words, you are never, &lt;strong&gt;ever&lt;/strong&gt;, going to read that snippet of code from top to bottom (you know, like we usually read things). So why are we writing it like that? It's hard to write, it's hard to read.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You might be thinking "well, that doesn't looks so bad". Now imagine 10 or 20 more lines in the when statement, which basically only perform a trivial mapping from two very similar sounding classes &lt;code&gt;FooInput -&amp;gt; FooAction&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;It doesn't stop there though, in many implementations &lt;code&gt;actions&lt;/code&gt; get mapped to &lt;code&gt;results&lt;/code&gt;, and then &lt;code&gt;results&lt;/code&gt; get mapped to &lt;code&gt;states&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;Result&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Persona&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;gt;.&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;isSearchMode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Boolean&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nc"&gt;HomeState&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="nc"&gt;Result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Success&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;isSearchMode&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nc"&gt;HomeState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ResultSearch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="nc"&gt;HomeState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ResultAllPersona&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="nc"&gt;Result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Error&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;HomeState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;exception&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="nc"&gt;Result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Loading&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;HomeState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Loading&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Take a moment to think how you would follow the code in your head while trying to find that nasty bug. You start from the &lt;code&gt;View&lt;/code&gt;, jump to the &lt;code&gt;ViewModel&lt;/code&gt;, and see the first mapper (&lt;code&gt;inputs&lt;/code&gt; -&amp;gt; &lt;code&gt;actions&lt;/code&gt;). From there there's not clear path to take (or IDE shortcut to use) to jump to where the flow continues (since the architecture usually hides the wiring from the clients). You basically need to do a &lt;code&gt;cmd+f&lt;/code&gt; of the &lt;code&gt;action&lt;/code&gt; name (or &lt;code&gt;cmd+b&lt;/code&gt; to get a list of places where it's used/declared) to try and find where that action is being processed, that's usually in the VM as well, some implementations define a &lt;code&gt;UseCase&lt;/code&gt; class and place the mapper there, it really could be anywhere. &lt;br&gt;
Ok, you found the &lt;code&gt;Actions&lt;/code&gt; -&amp;gt; &lt;code&gt;Results&lt;/code&gt; mapper, you found the one line you care about in that mapper, what now? Well now you jump yet again! this time to the &lt;code&gt;Reducer&lt;/code&gt; and you find... another mapper! At this point you forgot what you where doing entirely.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;MVI makes reading code a very awkward experience. It’s analogous to reading a book where each next word is on a new page. You need to keep flipping pages (going to a different class) to know what comes next. You end up spending more time finding code, than reading code.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm7ua3q0l2ffhmwp6kubs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm7ua3q0l2ffhmwp6kubs.png" alt="arch"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;All this added overhead makes it easy for bugs to hide in plain sight. This gets more tricky when you take into consideration Threading, RxJava/Coroutines, Asynchronous events, Lifecycle scopes, etc.&lt;/p&gt;

&lt;p&gt;I understand where MVI is coming from here though, if multiple &lt;code&gt;Inputs&lt;/code&gt; produce the same &lt;code&gt;Action&lt;/code&gt; then we can simplify things a bit. Unfortunately, in practice this is almost never the case. Your flows won't share &lt;code&gt;Input&lt;/code&gt;s, &lt;code&gt;Action&lt;/code&gt;s, or &lt;code&gt;Result&lt;/code&gt;s`. It's more likely that for every "flow/usecase" in your app, you'll have one of each.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reducer is a &lt;a href="https://en.wikipedia.org/wiki/Leaky_abstraction" rel="noopener noreferrer"&gt;leaky abstraction&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Don't get me wrong. There are valid reasons for extracting code into other classes.&lt;br&gt;
A good example of this are ViewModels. A &lt;code&gt;ViewModel&lt;/code&gt; exists not because a particular architecture requires it, it exists because it has a clear purpose. It serves as an interface from the view to the business logic, separates the rendering view code from non-rendering related code, it signals a larger scope (at least in android the lifecycle-scope of the VM is slightly larger than the scope of the views), facilitates testing, etc. In other words, it has a propose that's beyond the chosen architecture agenda. &lt;br&gt;
In the same way, &lt;code&gt;UseCase&lt;/code&gt; classes exist because UseCases are a reusable component that might be used from different &lt;code&gt;VMs&lt;/code&gt;. Same goes for &lt;code&gt;Repositories&lt;/code&gt;, a repository can stand on its own and serve multiple clients. All these classes exist with a clear goal, scope and purpose. Here, the logic is split sensibly.&lt;/p&gt;

&lt;p&gt;On the other hand, let's look at MVI's &lt;code&gt;Reducer&lt;/code&gt;. A &lt;code&gt;Reducer&lt;/code&gt; is very specific to a particular VM (not reusable). Moreover, the scope of the reducer is the same as the scope of the VM. Why extracting it out out into its own class? &lt;br&gt;
"For testing purposes" I hear you say. That's not a good enough of a reason IMO. &lt;br&gt;
Ask yourself this: "Should I really be extracting &lt;em&gt;private&lt;/em&gt; methods into a separate classes solely to be able to test them?" I personally don't think so, those methods are private for a reason, they are implementation details, they are not meant to be unit tested directly. Otherwise, what's stopping you from extracting every single &lt;code&gt;private&lt;/code&gt; method from every single class in your project and testing those too?.&lt;/p&gt;

&lt;p&gt;**It's perfectly normal to want to simplify your classes when the get too big and complex. But in my opinion, extracting things into different classes needs to be done in a sensible way. &lt;/p&gt;

&lt;p&gt;What I'm trying to say here is, you can come up with all sort of ways of splitting code, but not all of them will be good. &lt;/p&gt;

&lt;p&gt;Splitting your VMs based on functionality/use-case/features is usually better and makes more sense than splitting it by some arbitrary architecture convention. As an example, consider these two classes:&lt;br&gt;
&lt;code&gt;MediaCache: This class handles caching for images and video&lt;/code&gt;&lt;br&gt;
&lt;code&gt;Reducer: This class reduces results to states (huh?)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Here, the Reducer could potentially grow infinitely since it could host logic for any new feature you add to the View/VM. The purpose of the class is very abstract and tied to the architecture. &lt;br&gt;
On the other hand, there are few operations that you can put into &lt;code&gt;MediaCache&lt;/code&gt;, it has a well defined scope based on functionality (what the class does). Sure, you can get very fancy and design a very complex &lt;code&gt;cache&lt;/code&gt; mechanism but all your code will be within scope of caching things. It's not the case with &lt;code&gt;Reducer&lt;/code&gt;s, the scope will grow and grow and as you add more and more new features.&lt;/p&gt;

&lt;p&gt;Extracting implementation logic into trivial classes only for testing proposes also results into simplistic tests that become increasingly meaningless and add a ton of friction to your codebase. If you want to read more about why testing private methods is bad I highly recommend this read: &lt;a href="https://enterprisecraftsmanship.com/posts/unit-testing-private-methods/" rel="noopener noreferrer"&gt;Unit testing private methods&lt;/a&gt; by Vladimir Khorikov&lt;/p&gt;

&lt;p&gt;When you have a class with a single function &lt;code&gt;reduce&lt;/code&gt; and no state, you should ask yourself "why is this a class to begin with?". Just move the function inside your VM, no need to extract it into artificial classes. Then go a step further and get rid of this function altogether, because again, &lt;code&gt;reducing&lt;/code&gt; should happen contextually within the feature and it should not be artificially grouped together in a function.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ending thoughts
&lt;/h2&gt;

&lt;p&gt;There are many other reasons I dislike this architecture, It's very intrusive, it adds a ton of boilerplate, it can be ambiguous, etc. Those are not exclusive to MVI and I could live with some of those drawbacks. I'm sure MVI might fit some applications better than other, but in all cases, readability suffers.&lt;/p&gt;

&lt;p&gt;All in all, MVI looks elegant from a theoretical standpoint but I have yet to see an implementation that actually works and scales well for big projects.&lt;/p&gt;

&lt;p&gt;I'm very happy that Jetpack compose is just around the corner! Up until now I've been using a hierarchy of custom views + view models &lt;a href="https://play.google.com/store/apps/details?id=com.feresr.walpy&amp;amp;hl=en&amp;amp;gl=US" rel="noopener noreferrer"&gt;in my apps&lt;/a&gt; (something that kind of resembles the composable approach that Google is taking with Jetpack Compose). It's nice to know that his approach will soon become more mainstream.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://feresr.github.io" rel="noopener noreferrer"&gt;Website&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://twitter.com/fernandoraviola" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;EDIT:&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;I've been told not all implementations extract the reducer into its own class. I think that's a good thing! Still, most MVI implementations unnecessarily force you to reduce ALL your features in the same function/class (resulting in giant when statements, mixing unrelated features, grouping unrelated code, and making things hard to read overall). &lt;/p&gt;

&lt;p&gt;I was also told that big &lt;code&gt;when statements/mappers&lt;/code&gt; can be prevented by using composable "sub-view-models". IMO, splitting this &lt;code&gt;when statements&lt;/code&gt; into smaller ones does not fix the underlying problem, it only adds more boilerplate. More classes that just redirect you somewhere else. You are still reading code in a perpendicular way as to what you write (one line at a time before jumping somewhere else). And again, you end up spending more time trying to &lt;strong&gt;find&lt;/strong&gt; code than actually &lt;strong&gt;reading&lt;/strong&gt; it. &lt;/p&gt;

&lt;p&gt;Lastly, I've been presented with this architecture: &lt;a href="https://github.com/orbit-mvi/orbit-mvi" rel="noopener noreferrer"&gt;https://github.com/orbit-mvi/orbit-mvi&lt;/a&gt;&lt;br&gt;
Which I haven't tried but I like what I see, it throws away many MVI made up restrictions while keeping the ones that make sense. Feature flows read linearly and the state reduction happens contextually (as opposed to grouped into one big "reducer" function/class).&lt;/p&gt;

</description>
      <category>mvi</category>
      <category>architecture</category>
      <category>android</category>
      <category>kotlin</category>
    </item>
    <item>
      <title>Writing Super Mario Bros in C++</title>
      <dc:creator>Raviola</dc:creator>
      <pubDate>Sat, 30 May 2020 18:36:53 +0000</pubDate>
      <link>https://dev.to/feresr/writing-super-mario-bros-in-c-4726</link>
      <guid>https://dev.to/feresr/writing-super-mario-bros-in-c-4726</guid>
      <description>&lt;p&gt;I decided to learn C++ as step towards understanding more about the fundamentals of computer science, programming languages and graphics programming in general.&lt;/p&gt;

&lt;p&gt;Game development has been a hobby of mine for a long time. writing a game seemed like a fun project to start with. After reading some books on C++ I decided to clone the Italian plumber platformer. &lt;a href="https://github.com/feresr/super-mario-bros" rel="noopener noreferrer"&gt;Find the source code here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this post, I want to talk about aspects I found interesting about learning C++ coming from the JVM world. I also want to shed some light into the process of building a “simple” game using the Entity Component System Architecture. If you are not a game developer I hope my article serves as a general introduction to how simple games like this are put together.&lt;/p&gt;

&lt;h1&gt;
  
  
  Starting out
&lt;/h1&gt;

&lt;p&gt;I love JetBrains IDE’s so the first step for me was downloading CLion. CLion uses CMAKE to build C++ projects by default. CMake is a build system that builds build systems. It’s cross platform and incredibly unintuitive but it’s your best bet if you want your software to run in multiple platforms. It came as a surprise that a language with this much history doesn’t have a more sophisticated solution in place. Coming from the Java (Kotlin) world, I have a newfound appreciation for Gradle.&lt;/p&gt;

&lt;p&gt;I decided to use Simple Direct Media Layer 2 (SDL2) to get access to audio, keyboard, mouse, and graphics hardware. I considered using OpenGL directly, but I think the scope of the project was quickly getting out of hand as it was.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1400%2F1%2A0q-692eaKjS0_pD9JUlYqQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1400%2F1%2A0q-692eaKjS0_pD9JUlYqQ.png" alt="alt"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, I set off to define an architecture for the game. Plain Object Oriented design seems like a perfect fit for games. You have a bunch of objects in your game interacting with each other. You can map those objects to classes and take advantage of inheritance to avoid repeating code. Unfortunately, this naive approach brings with it some problems when building games of relative complexity. I don’t want to get too deep into what those problems are but here’s a quick summary:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Using inheritance usually results in inflexible architectures that sooner or later will lead into the Deadly diamond problem.&lt;/li&gt;
&lt;li&gt;Efficiency. Objects often are scattered around memory and make poor use of CPU cache both in terms of cache coherency and prefetching. (this might not be a huge deal depending on the kind of games you’re trying to make)&lt;/li&gt;
&lt;li&gt;Encapsulation. It’s hard to define where logic should live and what has access to what, resulting in spaghetti code.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I might expand on these points on a following article. For now I want to show you how the architecture I picked works and how it overcomes these problems.&lt;/p&gt;

&lt;h1&gt;
  
  
  The ECS Architecture
&lt;/h1&gt;

&lt;p&gt;I struggled in the past trying to architect my games in a way that they would scale. When I first learned about the Entity-Component-System architecture I immediately wanted to try it out. Let’s start by defining each term on its name.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1400%2F1%2AHCGAr6He83a6AcZd6Z652A.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1400%2F1%2AHCGAr6He83a6AcZd6Z652A.jpeg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Entity
&lt;/h2&gt;

&lt;p&gt;Everything in your game world is represented by an entity. This includes the player, the enemies, sounds, music and and even the camera. &lt;em&gt;An entity is just a bag of components and contains no logic&lt;/em&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1400%2F1%2As6I6PJgvLrQrtgWwqbDAAg.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1400%2F1%2As6I6PJgvLrQrtgWwqbDAAg.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Component
&lt;/h2&gt;

&lt;p&gt;Components are plain old structs that also contain no logic. They are just data holders. Common components you’ll find in most games are PositionComponent, PlayerComponent and TextureComponent.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1400%2F1%2A5xq7LKtacVnhJgCnoHS8zQ.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1400%2F1%2A5xq7LKtacVnhJgCnoHS8zQ.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Notice that some components don’t even hold data (see PlayerComponent for example) they just serve as “labels” that help identify certain entities in the game world.&lt;/p&gt;

&lt;p&gt;Components can be assigned-to and removed from entities at run-time.&lt;/p&gt;

&lt;p&gt;The components above are pretty general, but you will most likely be creating components specific to your game. As an example, a &lt;code&gt;SuperMarioComponent&lt;/code&gt; is assigned to the mario entity whenever he eats a mushroom.&lt;/p&gt;

&lt;h2&gt;
  
  
  System
&lt;/h2&gt;

&lt;p&gt;Lastly, systems are where the action happens. They are very domain specific. They hold logic and keep it encapsulated. I think this will make more sense with some examples of the types of system I defined in my game:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- The render system
- The camera system
- The physics system
- The animation system
- etc.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The system class is not much complicated than the rest of the classes in the architecture. On it most basic form it overrides an update(world* world) function that takes in a game world as a parameter. We’ll talk about the World class next.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1400%2F1%2AQgoKISSoQ-fVp7rB9eHC6w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1400%2F1%2AQgoKISSoQ-fVp7rB9eHC6w.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Take a look at the &lt;a href="https://github.com/feresr/super-mario-bros/blob/master/src/systems/AnimationSystem.cpp" rel="noopener noreferrer"&gt;AnimationSystem&lt;/a&gt; in my game for a simple real example of the logic illustrated above.&lt;/p&gt;

&lt;h1&gt;
  
  
  Putting things together
&lt;/h1&gt;

&lt;p&gt;As hinted above, Systems, Entities and Components interact with each other using the World class.&lt;/p&gt;

&lt;p&gt;As you might have guessed, the world class models our gameworld, and as such, contains all our game Entities. We can define what happens to those entities by registering systems to the gameworld. Both entities and systems can be added/removed at run time.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1400%2F1%2ANFUgVdvIerN3Xkn_g1t-Aw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1400%2F1%2ANFUgVdvIerN3Xkn_g1t-Aw.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The world class is as straightforward as the rest of the classes in the architecture:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1400%2F1%2AMquMrDfcTkl8KPEwqfYGPg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1400%2F1%2AMquMrDfcTkl8KPEwqfYGPg.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I think you can guess what most of these methods do. The first one is just the default constructor. The next two just add/remove Systems to to the world. The following two ones do something similar but for Entities.&lt;/p&gt;

&lt;p&gt;The last method, find(), is perhaps the one that deserves more explanation. It takes care of finding all entities currently in the gameworld that match a specific criteria. That criteria is usually what type of components are assigned to them:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

// Find all entities with Texture and Position data.
auto entities = world-&amp;gt;find&amp;lt;TextureComponent, PositionComponent&amp;gt;();


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Find takes advantage of function templates to define the search. In Java/Kotlin if you want a class or function to operate on a arbitrary class you can make use of generics. Function and class templates are a bit like generics only more powerful. Function templates are instructions to the compiler to write code for you, also known as metaprogramming. This allows us to create a function template whose functionality can be adapted to more than one type or class.&lt;/p&gt;

&lt;p&gt;This is the definition of find in my code:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1400%2F1%2ADnXfZKodhWPhNskzEMyZIA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1400%2F1%2ADnXfZKodhWPhNskzEMyZIA.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There’s a few interesting things going on here. The first one is the use of &lt;code&gt;template&amp;lt;typename… Components&amp;gt;&lt;/code&gt; in the function signature. This is telling the compiler to generate a function called find at compile-time. The compiler will generate such function each time it encounters a distinct invocation of find:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1400%2F1%2AqCfjtc6NJt73DJNIGq3mjA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1400%2F1%2AqCfjtc6NJt73DJNIGq3mjA.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For the code above, the compiler will automatically generate the following for us:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


void find(const std::function&amp;lt;void(Entity*)&amp;gt;&amp;amp; callback) {
   for (auto entity : entities) {
      if (entity-&amp;gt;has&amp;lt;AnimationComponent, TextureComponent&amp;gt;) {       
         callback(entity);
      }
   }
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;As I hinted before this happens at compile time, so there’s no run time penalty. I must admit I didn’t like this C++ feature when I first encounter it. I still don’t, but I understand the performance benefits they bring along. The reason I don’t like them is I think they result in hard to read code. I don’t like weak-typing systems and this looks awfully like it.&lt;/p&gt;

&lt;p&gt;The rest of the function should be relatively easy to follow. Let me know in the comments if this is not the case.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;You should now have a rough understanding ECS works. We no longer rely on inheritance to define behavior, we rely on composition instead. This means we got rid of potentially long and inflexible hierarchies in favor of lightweight reusable components that we can add and remove at runtime.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1400%2F1%2Aho6H7EN_vWmTkZJp4scD0Q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1400%2F1%2Aho6H7EN_vWmTkZJp4scD0Q.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The efficiency problem I mentioned before is also mitigated. Our entities and components are now tightly packed in contiguous memory, so iterating over them makes much better use of CPU caches. There are techniques to improve this even further but I haven’t had the need to implement them for this game.&lt;/p&gt;

&lt;p&gt;Our third problem, encapsulation, is also fixed. It is now very clear where the logic should live, how the different parts our architecture should communicate and what should have access to what. As an example, it makes sense for the RenderSystem to make use of classes such as renderer.cpp or window.cpp, but it would be immediately obvious something is off if those classes are required by systems like the PhysicsSystem.cpp or the SoundSystem.cpp.&lt;/p&gt;

&lt;p&gt;You should know have an idea of how my code is structured. Feel free to poke around and create PR to improve any bug or mistake I might have made. I’m still very new with C++, so I’m sure my code has a lot of room for improvement.&lt;/p&gt;

&lt;p&gt;Learning C++ was a fun experience but I believe I have still a long way to go to feel comfortable using it. Future steps for this project include re-writing it using Rust or Kotlin-native. I would also love to compile this project to WASM to get it to run in a browser, if you have any experience with any that I would love to chat with you!&lt;/p&gt;

&lt;p&gt;Thank you for reading, and Happy coding!&lt;/p&gt;

&lt;p&gt;&lt;a href="http://feresr.github.io/" rel="noopener noreferrer"&gt;Personal website&lt;/a&gt;&lt;br&gt;
&lt;a href="https://twitter.com/fernandoraviola" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;&lt;/p&gt;

</description>
      <category>c</category>
      <category>gamedev</category>
      <category>oop</category>
      <category>ecs</category>
    </item>
    <item>
      <title>Cascade static library link mechanism</title>
      <dc:creator>Raviola</dc:creator>
      <pubDate>Wed, 22 Apr 2020 04:06:21 +0000</pubDate>
      <link>https://dev.to/feresr/cascade-static-library-link-mechanism-1lok</link>
      <guid>https://dev.to/feresr/cascade-static-library-link-mechanism-1lok</guid>
      <description>&lt;p&gt;Hey C++ people, can anyone help answering this SO question?&lt;/p&gt;


&lt;div class="ltag__stackexchange--container"&gt;
  &lt;div class="ltag__stackexchange--title-container"&gt;
    
      &lt;div class="ltag__stackexchange--title"&gt;
        &lt;h1&gt;
          &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7Gn-iPj_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/stackoverflow-logo-b42691ae545e4810b105ee957979a853a696085e67e43ee14c5699cf3e890fb4.svg" alt=""&gt;
            &lt;a href="https://stackoverflow.com/questions/50190871/cascade-static-library-link-mechanism" rel="noopener noreferrer"&gt;
              cascade static library link mechanism
            &lt;/a&gt;
        &lt;/h1&gt;
        &lt;div class="ltag__stackexchange--post-metadata"&gt;
          &lt;span&gt;May  5 '18&lt;/span&gt;
            &lt;span&gt;Comments: 11&lt;/span&gt;
            &lt;span&gt;Answers: 0&lt;/span&gt;
        &lt;/div&gt;
      &lt;/div&gt;
      &lt;a class="ltag__stackexchange--score-container" href="https://stackoverflow.com/questions/50190871/cascade-static-library-link-mechanism" rel="noopener noreferrer"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Y9mJpuJP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/stackexchange-arrow-up-eff2e2849e67d156181d258e38802c0b57fa011f74164a7f97675ca3b6ab756b.svg" alt=""&gt;
        &lt;div class="ltag__stackexchange--score-number"&gt;
          1
        &lt;/div&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wif5Zq3z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/stackexchange-arrow-down-4349fac0dd932d284fab7e4dd9846f19a3710558efde0d2dfd05897f3eeb9aba.svg" alt=""&gt;
      &lt;/a&gt;
    
  &lt;/div&gt;
  &lt;div class="ltag__stackexchange--body"&gt;
    
&lt;p&gt;sdl2-image was built and installed as a static library &lt;code&gt;libSDL2_image.a&lt;/code&gt;, it dependons on another static librarys, like webp, libpng, etc. When I link it like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;add_executable(main main.cpp)
target_link_libraries(main
  SDL2::SDL2-static
  ${SDL2_IMAGE_LIBRARY}
)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It fails, showing error:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;[ 50%] Linking CXX executable main
/usr/local/Cellar/cmake/3.11.1/bin/cmake -E cmake_link_script CMakeFiles/main.dir/link.txt --verbose=1
/Library/Developer/CommandLineTools/usr/bin/c++   -Wl,-search_paths_first -Wl,-headerpad_max_install_names&lt;/code&gt;&lt;/pre&gt;…
    
  &lt;/div&gt;
  &lt;div class="ltag__stackexchange--btn--container"&gt;
    
      &lt;a href="https://stackoverflow.com/questions/50190871/cascade-static-library-link-mechanism" rel="noopener noreferrer"&gt;Open Full Question&lt;/a&gt;
    
  &lt;/div&gt;
&lt;/div&gt;


</description>
    </item>
    <item>
      <title>Can you recommend a good operating System Fundamentals book?</title>
      <dc:creator>Raviola</dc:creator>
      <pubDate>Fri, 21 Dec 2018 23:04:01 +0000</pubDate>
      <link>https://dev.to/feresr/can-you-recommend-a-good-operating-system-fundamentals-book-4f9a</link>
      <guid>https://dev.to/feresr/can-you-recommend-a-good-operating-system-fundamentals-book-4f9a</guid>
      <description>&lt;p&gt;Hey can anyone recommend a good book on Operating system fundamentals?... Currently looking to buy this one: &lt;a href="https://t.co/yZvN8WnukA"&gt;https://t.co/yZvN8WnukA&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  computersience #os #operating #system
&lt;/h1&gt;

</description>
      <category>os</category>
      <category>operating</category>
      <category>system</category>
      <category>book</category>
    </item>
  </channel>
</rss>
