<?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: Brooks Patton</title>
    <description>The latest articles on DEV Community by Brooks Patton (@brookzerker).</description>
    <link>https://dev.to/brookzerker</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%2F234464%2F3a174ea8-2dc5-4749-9230-211ce14a77ec.png</url>
      <title>DEV Community: Brooks Patton</title>
      <link>https://dev.to/brookzerker</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/brookzerker"/>
    <language>en</language>
    <item>
      <title>Use Transactions When Manually Accessing SQL Databases</title>
      <dc:creator>Brooks Patton</dc:creator>
      <pubDate>Wed, 02 Oct 2024 22:02:11 +0000</pubDate>
      <link>https://dev.to/brookzerker/use-transactions-when-manually-accessing-sql-databases-40hl</link>
      <guid>https://dev.to/brookzerker/use-transactions-when-manually-accessing-sql-databases-40hl</guid>
      <description>&lt;p&gt;Sometimes we find ourselves in a situation where we need to manually connect to the production database and change something. When we run into these situations we want to decrease the risk of causing problems as much as possible and this article will show you one way to do this: Transactions.&lt;/p&gt;

&lt;p&gt;Normally SQL Transactions are a way to combine a bunch of related queries together into a single, transaction to the database. If any of them fail for any reason then nothing will be committed. We can use this same trick when manually working with a database, allowing us to make our changes, check our work, and only commit when we are sure that things are okay.&lt;/p&gt;

&lt;p&gt;For this example let's set up a new Database. (I'll be using Postgres for this example, but I'll also be using the commands that are standard for SQL, they should work with other SQL based databases as long as they support Transactions). To begin with we'll create two tables as follows.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Species&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Primary Key&lt;/td&gt;
&lt;td&gt;id INT&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;name VARCHAR(10)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Pets&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Primary Key&lt;/td&gt;
&lt;td&gt;id INT&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;name VARCHAR(255)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Foreign Key&lt;/td&gt;
&lt;td&gt;species_id INT&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;We'll create these tables using a Transaction in PSQL (The interactive shell for Postgres) this should work for your choice of interactive shell.&lt;/p&gt;

&lt;p&gt;If you follow along, a couple of things to note. If you have an error with any of the commands in the Transaction, the entire Transaction will fail. You will need to run the &lt;code&gt;ROLLBACK;&lt;/code&gt; command and then try again. We'll explore rolling back shortly.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;postgres=# START TRANSACTION;
START TRANSACTION
postgres=*# CREATE TABLE species (
    id SERIAL PRIMARY KEY,
    name VARCHAR(10)
);
CREATE TABLE
postgres=*# CREATE TABLE pets (
    id SERIAL PRIMARY KEY,
    name VARCHAR(255),
    species_id INT REFERENCES species (id)
);
CREATE TABLE
postgres=*# COMMIT;
COMMIT
postgres=# \dt
          List of relations
 Schema |  Name   | Type  |  Owner
--------+---------+-------+----------
 public | pets    | table | postgres
 public | species | table | postgres
(2 rows)

postgres=#
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that in PSQL we are given a &lt;code&gt;*=&lt;/code&gt; to show us that we aren't in normal mode, but inside a Transaction. &lt;/p&gt;

&lt;p&gt;To finish the transaction and commit the changes to production we use the &lt;code&gt;COMMIT;&lt;/code&gt; command. This immediately commits these changes to the database and are now available for use by other connections.&lt;/p&gt;

&lt;p&gt;Let's try another transaction, but this time we'll make a mistake so that we have to rollback. We'll insert two pet's into our database, Xilbë the cat, and Ranger the dog.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;postgres=# START TRANSACTION;
START TRANSACTION
postgres=*# INSERT INTO species (name) VALUES ('cat');
INSERT 0 1
postgres=*# INSERT INTO species (name) VALUES ('dog');
INSERT 0 1
postgres=*# table species;
 id | name
----+------
  1 | cat
  2 | dog
(2 rows)

postgres=*# INSERT INTO pets (name, species_id) VALUES ('Xilbë', 2);
INSERT 0 1
postgres=*# INSERT INTO pets (name, species_id) VALUES ('Ranger', 2);
INSERT 0 1
postgres=*# table pets;
 id |  name  | species_id
----+--------+------------
  1 | Xilbë  |          2
  2 | Ranger |          2
(2 rows)

postgres=*# SELECT species.name AS species_name, pets.name AS pet_name FROM pets JOIN species on species.id = pets.species_id;
 species_name | pet_name
--------------+----------
 dog          | Ranger
 dog          | Xilbë
(2 rows)

postgres=*# ROLLBACK;
ROLLBACK
postgres=# table species
postgres-# ;
 id | name
----+------
(0 rows)

postgres=# table pets;
 id | name | species_id
----+------+------------
(0 rows)

postgres=#
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All of the commands were successful, but we made a data error that could only be caught by checking our work with a &lt;code&gt;JOIN&lt;/code&gt; query. Running this allows us to catch that Xilbë has been entered as a Dog instead of a Cat. Xilbë would not be pleased so we rolled back the changes and therefore nothing happened in the database.&lt;/p&gt;

&lt;p&gt;This shows the power of using Transactions in a manual setting, we can do our work, and then take time to check it all without having whatever we have done visible to any other connections to the database. Only when we are sure that we are ready do we commit it.&lt;/p&gt;

</description>
      <category>sql</category>
      <category>postgres</category>
      <category>database</category>
    </item>
    <item>
      <title>Learning Programming is Still a Good Idea</title>
      <dc:creator>Brooks Patton</dc:creator>
      <pubDate>Mon, 12 Aug 2024 21:01:06 +0000</pubDate>
      <link>https://dev.to/brookzerker/learning-programming-is-still-a-good-idea-3j8f</link>
      <guid>https://dev.to/brookzerker/learning-programming-is-still-a-good-idea-3j8f</guid>
      <description>&lt;p&gt;Recently, no matter where we go on the internet we'll see claims that it's a terrible idea to begin learning programming. And on the surface it's obvious why such advice is popular to give, AI tools like ChatGPT and CoPilot are gaining popularity and are getting better at writing code themselves. Why wouldn't we want to get ahead of the wave of automation and study something else? However I have my doubts on how good this advice is though. &lt;/p&gt;

&lt;p&gt;A professional programmer in 2024 is expected to be able to do all of the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Write code&lt;/li&gt;
&lt;li&gt;Create automated tests&lt;/li&gt;
&lt;li&gt;Debug code that they wrote AND didn't write&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In addition, programmers are also expected to do more than just programming. They will also be expected to: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Gather requirements from vague sources&lt;/li&gt;
&lt;li&gt;Convert these into User Stories&lt;/li&gt;
&lt;li&gt;Collaborate with technical AND non-technical team members&lt;/li&gt;
&lt;li&gt;Manually test their own code&lt;/li&gt;
&lt;li&gt;Estimate how long complex work will take&lt;/li&gt;
&lt;li&gt;Learn new skills&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These skills are crucial in todays world, where communication is a must when working in a team environment. Ironically, Large Language models like ChatGPT also require strong communication skills when working with them, making this skillset essential for the future as well.&lt;/p&gt;

&lt;p&gt;And, as AI continues to become more present in our daily lives debugging skills will allow us to adapt to new AI model changes faster than our competition (be it other developers trying to get jobs or other companies leveraging AI as part of their products).&lt;/p&gt;

&lt;p&gt;The ability to write code, or at least understand the code that AI writes gives us another edge. We'll be able to run the latest models, play with new technology and customize what is available to run better for us. If we revisit the tools already being used by programmers today I can see where both ChatGPT and Copilot can be customized to work with our coding styles and personalities. Meaning with some effort we can make them work with us a lot better than someone who is just using either tool straight out of the box.&lt;/p&gt;

&lt;p&gt;These tools that we customize could help us by aiding in all of the steps I managed above. For example instead of writing the code the AI could be helping analyze the code that we write and suggest ways we could improve it. This brings the AI from replacement to partner.&lt;/p&gt;

&lt;p&gt;I strongly believe that these are the reasons why learning programming is a great idea. However there is a caveat: if we stop learning, or we get complacent with our skills then we will wake up one day to discover our jobs automated away by tools we don't understand and can't use any better than everyone else.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Give tech layoffs, how long is it taking to hire devs?</title>
      <dc:creator>Brooks Patton</dc:creator>
      <pubDate>Sun, 07 Jul 2024 03:41:39 +0000</pubDate>
      <link>https://dev.to/brookzerker/give-tech-layoffs-how-long-is-it-taking-to-hire-devs-37n6</link>
      <guid>https://dev.to/brookzerker/give-tech-layoffs-how-long-is-it-taking-to-hire-devs-37n6</guid>
      <description>&lt;p&gt;Recently I became curious as to how the job market is for companies hiring developers. I wanted to look into this as I truly believe that it is more cost effective to train devs instead of hiring new ones. But I wanted to gather some data instead of just relying on my feelings (and of course I'm biased too).&lt;/p&gt;

&lt;p&gt;My initial thought was the opposite of what I wanted to find though, that companies would be able to hire new developers quickly (within 3 months of starting the search) due to all the layoffs in the dev world that have been happening recently.&lt;/p&gt;

&lt;p&gt;So I set up some polls asking my followers on LinkedIn, YouTube, and X how long it was taking their companies to hire a dev. I gave three options plus a fun opt-out option for anyone who wanted to answer the poll but not give a real answer. The options were.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&amp;lt; 3 months&lt;/li&gt;
&lt;li&gt;3 - 6 months&lt;/li&gt;
&lt;li&gt;&amp;gt; 6 months&lt;/li&gt;
&lt;li&gt;companies are hiring?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I left the poll running for a week and we now have the results.&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%2Fqj6nu00e2k5ijm9vbnec.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%2Fqj6nu00e2k5ijm9vbnec.png" alt="Image description" width="530" height="399"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I got 117 responders to the poll, but 81 of them chose the &lt;code&gt;companies are hiring?&lt;/code&gt; option, leaving 35 people across the other results.&lt;/p&gt;

&lt;p&gt;Of these 35 people 20 reported that it was taking more than six months to hire a new dev. 10 were able to hire in less than 3 months, and 5 were in the middle. &lt;/p&gt;

&lt;p&gt;I understand that this is a small sample size, and I didn't control to size, type, and/or region of the companies. I would love for someone with a larger audience to run the same poll and see if the numbers correlate. &lt;/p&gt;

&lt;p&gt;That being said, the response is opposite of what I originally thought, which is that it's taking many companies more that 3 months to hire new devs. And we also know that just hiring is only the first step. Once hired devs are going to need to be onboarded into the company and the projects. This could take a long time as well. &lt;/p&gt;

&lt;p&gt;Even with this smaller amount of data I'm more confident in my claim that a company that attempts to train their developers instead of laying them off to hire new developers with a different skillset is going to be cheaper in the short and long runs. &lt;/p&gt;

</description>
    </item>
    <item>
      <title>Observer Pattern in Rust</title>
      <dc:creator>Brooks Patton</dc:creator>
      <pubDate>Mon, 15 Jun 2020 02:57:53 +0000</pubDate>
      <link>https://dev.to/brookzerker/observer-pattern-in-rust-57hl</link>
      <guid>https://dev.to/brookzerker/observer-pattern-in-rust-57hl</guid>
      <description>&lt;p&gt;Recently I've been reading through the book Game Programming Patterns by Robert Nystrom while implementing the patterns into an infinite runner that I wrote in Rust using the GGEZ game engine.&lt;/p&gt;

&lt;p&gt;Before starting the game patterns proper the first part of the book covers some of the classic design patterns in Object Oriented Programming. This includes the Observer pattern. &lt;/p&gt;

&lt;p&gt;As a quick recap, the observer pattern is all about having an event happen in one area of the code, and that event triggering an action in another area of the code. In a traditional object oriented language this could be done by passing instances of objects around. These objects would have to be mutable since the actions that would be triggered almost always affect the objects internal state.&lt;/p&gt;

&lt;p&gt;I have a &lt;a href="https://github.com/brooks-builds/observer_pattern_in_rust/tree/master/oop" rel="noopener noreferrer"&gt;working example&lt;/a&gt; of the code that I'm going to show, you can find it on my &lt;a href="https://github.com/BrooksPatton" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;. I'm using a game of pong (well, more like work-in-progress part of a game that could be pong...eventually) written using &lt;a href="https://crates.io/crates/ggez" rel="noopener noreferrer"&gt;GGEZ&lt;/a&gt;. This example is working, and while it isn't a playable game it does properly use the observer pattern.&lt;/p&gt;

&lt;p&gt;With that, let's go through the code.&lt;/p&gt;

&lt;h1&gt;
  
  
  Sending an Event
&lt;/h1&gt;

&lt;p&gt;Let's begin by examining how we are sending an event. In this case when the ball touches the left or right edge of the screen we'll want to send an event saying that the player or ai scored. I have an enum to cover this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;enum&lt;/span&gt; &lt;span class="n"&gt;GameEvent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;PlayerScored&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;AiScored&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;The ball struct has a update function that is running every frame. It will check if the ball is touching an edge and will use the event system struct to send the event.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="n"&gt;screen_width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;f32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="n"&gt;screen_height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;f32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="n"&gt;event_system&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;EventSystem&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// I have removed the code from this example to move the ball and &lt;/span&gt;
    &lt;span class="c1"&gt;// bounce it off the top of the top and bottom of the screen. You&lt;/span&gt;
    &lt;span class="c1"&gt;// can view the code I removed at &lt;/span&gt;
    &lt;span class="c1"&gt;// https://github.com/brooks-builds/observer_pattern_in_rust/blob/master/oop/src/ball.rs#L25&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.location.x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.radius&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;screen_width&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.velocity.x&lt;/span&gt; &lt;span class="o"&gt;*=&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="n"&gt;event_system&lt;/span&gt;&lt;span class="nf"&gt;.notify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;GameEvent&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;PlayerScored&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.location.x&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.radius&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mf"&gt;0.0&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.velocity.x&lt;/span&gt; &lt;span class="o"&gt;*=&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="n"&gt;event_system&lt;/span&gt;&lt;span class="nf"&gt;.notify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;GameEvent&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;AiScored&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;This example shows that emitting an event doesn't require that the struct be aware that it is being observed. This will make it easy to add a lot of events throughout the code.&lt;/p&gt;

&lt;p&gt;Let's move onto the observer of this event next, the score.&lt;/p&gt;

&lt;h1&gt;
  
  
  Observing an Event
&lt;/h1&gt;

&lt;p&gt;I have the score as a struct that stores the ai and player scores respectively. It is also storing the Text drawables that will be displayed each frame to the screen.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;Score&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// I'm leaving out some of the non-essential information&lt;/span&gt;
    &lt;span class="n"&gt;player&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;ai&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u8&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;I'm also using a trait to mark that this structure is an observable.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;trait&lt;/span&gt; &lt;span class="n"&gt;Observer&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;on_notify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;GameEvent&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;It's a pretty simple trait, and while I could just add the &lt;code&gt;on_notify&lt;/code&gt; function to the Score struct proper, I'm adding it through the trait to make it easier to add onto any structures that I want to turn into observers.&lt;/p&gt;

&lt;p&gt;I've implemented the trait to watch for the events and increment the scores.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="n"&gt;Observer&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;Score&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;on_notify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;GameEvent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nn"&gt;GameEvent&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;PlayerScored&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.player&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.player_text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;Self&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;create_text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.player&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="nn"&gt;GameEvent&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;AiScored&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.ai&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.ai_text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;Self&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;create_text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.ai&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;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;Now the score can do it's own thing and whenever it receives the player scored or ai scored events it will increment the appropriate properties and update the text that will be drawn to the screen.&lt;/p&gt;

&lt;p&gt;We still have the problem of how we are going to have two mutable references to the same score available to the drawing system and the event system at the same time. The answer, of course, is to cheat and use a tool that is meant for something else entirely.&lt;/p&gt;

&lt;h1&gt;
  
  
  Enter Arc and Mutex
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://doc.rust-lang.org/std/sync/struct.Arc.html" rel="noopener noreferrer"&gt;Arcs&lt;/a&gt; and &lt;a href="https://doc.rust-lang.org/std/sync/struct.Mutex.html" rel="noopener noreferrer"&gt;Mutexes&lt;/a&gt; are often used together to allow multiple threads to have a mutable reference to the same instance of a struct. They do reference counting at run-time, so there is a slight performance hit but they guarantee that only one mutable instance will be mutable at a time. This is done using the &lt;code&gt;lock&lt;/code&gt; method where the thread will be blocked until no other function is attempting to mutate the struct contained in the Mutex.&lt;/p&gt;

&lt;p&gt;We're going to have to wrap our score struct in an Arc and Mutex and store it in the arena struct so that we can draw the score to the screen. Because any structs using the score need it to be wrapped, I'm wrapping it up inside the &lt;code&gt;new&lt;/code&gt; static function on the Score struct.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;screen_width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;f32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;GameResult&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;WrappedScore&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;player&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;ai&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;player_text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Score&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;create_text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;player&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;player_text_width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_player_text_height&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;player_text&lt;/span&gt;&lt;span class="nf"&gt;.dimensions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;ai_text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Score&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;create_text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ai&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Arc&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Mutex&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Score&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;player_text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;ai_text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;player_location&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;Point2&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;screen_width&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mf"&gt;2.0&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;player_text_width&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;f32&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mf"&gt;5.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.0&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="n"&gt;ai_location&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;Point2&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;screen_width&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mf"&gt;2.0&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mf"&gt;3.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.0&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="n"&gt;player&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;ai&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;The game arena simply stores the wrapped Score. It does have to unwrap it when it goes to call the draw method on Score though.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;draw&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;GameResult&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.dividing_line&lt;/span&gt;&lt;span class="nf"&gt;.draw&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&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="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.wrapped_score&lt;/span&gt;&lt;span class="nf"&gt;.lock&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="n"&gt;score&lt;/span&gt;&lt;span class="nf"&gt;.draw&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&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;That lock method call is where the Mutex is blocking the thread to make sure that no other threads currently have mutable access to the instance of Score. Since this game is written in one thread we don't have to worry, we know that we will be the only ones that have access mutably or not, and it won't be for very long.&lt;/p&gt;

&lt;p&gt;When we hand a wrapped score to the event system we aren't handing it a clone of Score, we are handing it a clone of the Arc that is holding the Mutex that is holding the Score. In memory, it is the same Score. This is how we can pass around instances of objects back and forth in Rust while maintaining the safety that the borrow checker gives us.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;screen_width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;f32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;screen_height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;f32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;event_system&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;EventSystem&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;GameResult&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Arena&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;wrapped_score&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Score&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;screen_width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="n"&gt;event_system&lt;/span&gt;&lt;span class="nf"&gt;.add_observer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;wrapped_score&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

        &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Arena&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;dividing_line&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;DividingLine&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;screen_width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;screen_height&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;wrapped_score&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;The proceeding code shows the arena creating the score, keeping a copy for itself and also registering a copy with the event system. &lt;/p&gt;

&lt;h1&gt;
  
  
  Handling the Events
&lt;/h1&gt;

&lt;p&gt;Finally, let's take a look at the event system. It is storing the wrapped observers in a Vector, and looping through them to call the on_notify functions on them whenever an event is emitted.&lt;/p&gt;

&lt;p&gt;However we don't want to have to be limited to just storing the Score, or any one struct that is acting as an observer. We want to be able to turn any struct into an observer in the future and have the event system just work. We can do this by using the trait that we added to the Score struct earlier. This will allow us to set the type stored as the trait instead of the struct.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;EventSystem&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;wrapped_observers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;Arc&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Mutex&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;dyn&lt;/span&gt; &lt;span class="n"&gt;Observer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;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;The &lt;a href="https://doc.rust-lang.org/std/keyword.dyn.html" rel="noopener noreferrer"&gt;dyn&lt;/a&gt; keyword is using dynamic dispatch to get a pointer to the struct and then substitute that in at runtime. Of course this has a small runtime cost but it allows us to do what we want.&lt;/p&gt;

&lt;p&gt;That was the last bit of magic to make this work, here is the full event system file in it's entire glory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;sync&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="nb"&gt;Arc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Mutex&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;EventSystem&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;wrapped_observers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;Arc&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Mutex&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;dyn&lt;/span&gt; &lt;span class="n"&gt;Observer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="n"&gt;EventSystem&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;EventSystem&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;EventSystem&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;wrapped_observers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nd"&gt;vec!&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;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;notify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;GameEvent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;wrapped_observer&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.wrapped_observers&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;observer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;wrapped_observer&lt;/span&gt;&lt;span class="nf"&gt;.lock&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="n"&gt;observer&lt;/span&gt;&lt;span class="nf"&gt;.on_notify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;event&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;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;add_observer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;observer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Arc&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Mutex&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;dyn&lt;/span&gt; &lt;span class="n"&gt;Observer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.wrapped_observers&lt;/span&gt;&lt;span class="nf"&gt;.push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;observer&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;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;trait&lt;/span&gt; &lt;span class="n"&gt;Observer&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;on_notify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;GameEvent&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;enum&lt;/span&gt; &lt;span class="n"&gt;GameEvent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;PlayerScored&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;AiScored&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;As&lt;/span&gt; &lt;span class="n"&gt;I&lt;/span&gt; &lt;span class="n"&gt;mentioned&lt;/span&gt; &lt;span class="n"&gt;at&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;beginning&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;you&lt;/span&gt; &lt;span class="n"&gt;want&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;run&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;or&lt;/span&gt; &lt;span class="n"&gt;look&lt;/span&gt; &lt;span class="n"&gt;at&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="n"&gt;all&lt;/span&gt; &lt;span class="n"&gt;at&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;same&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt; &lt;span class="n"&gt;then&lt;/span&gt; &lt;span class="n"&gt;you&lt;/span&gt; &lt;span class="n"&gt;can&lt;/span&gt; &lt;span class="n"&gt;find&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="n"&gt;at&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;https&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="c1"&gt;//github.com/brooks-builds/observer_pattern_in_rust/tree/master/oop/src](https://github.com/brooks-builds/observer_pattern_in_rust/tree/master/oop/src)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;I've been reading through the Game Programming Patterns book and implementing each pattern first in a JavaScript + P5.js infinite runner, and then a Rust + GGEZ infinite runner. If you liked what you read I'd love to hear from you. I'm streaming every weekday morning at 7:am Mountain Time for around an hour on &lt;a href="https://www.twitch.tv/brookzerker" rel="noopener noreferrer"&gt;Twitch&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I also have a &lt;a href="https://www.youtube.com/playlist?list=PLrmY5pVcnuE9eDgLcskszIy7g0Z_hRcwk" rel="noopener noreferrer"&gt;YouTube Playlist&lt;/a&gt; of all the archived streams.&lt;/p&gt;

&lt;p&gt;Thanks for reading and happy coding!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>A Business is Like a Rope</title>
      <dc:creator>Brooks Patton</dc:creator>
      <pubDate>Thu, 26 Sep 2019 01:23:46 +0000</pubDate>
      <link>https://dev.to/denverdevs/a-business-is-like-a-rope-4m9p</link>
      <guid>https://dev.to/denverdevs/a-business-is-like-a-rope-4m9p</guid>
      <description>&lt;p&gt;When I first decided to go about the holistically learning the full-stack of businesses journey I reached out to one of my mentors that have made this journey before me. He gave me a metaphor for how products, and also businesses work that surprised me. Instead of the classic &lt;em&gt;Business is like a house, it needs a good foundation&lt;/em&gt; he used &lt;strong&gt;Business is like a rope&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Let's take an aspect of business that many people focus on, the technical excellence of the product (in this case I'm focusing on software products). If the product or service isn't good, then &lt;strong&gt;snip&lt;/strong&gt;, the rope is cut and it doesn't matter what comes after it. However because its a rope, a new rope can be tied on and we can try again. Maybe our product crashed constantly and corrupted data. We can tie on a new rope by fixing the bugs, creating a CI/CD pipeline to prevent them from occurring in the future, and of course, refusing to deploy when we know it will be a bad experience. The point is that when there is a problem and the rope is cut, we can't tie the next rope on until we fix the problem we are having.&lt;/p&gt;

&lt;p&gt;This should make sense, it feels logical to me. However, my mentor continued to state that a common problem he sees, and I agree with, is that decision-makers in the company focus on areas of the rope that aren't their domain when there is a problem. The quality of the code-base doesn't matter if the rope was cut hight up the chain? &lt;/p&gt;

&lt;p&gt;For example, &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the product designers didn't interview potential clients and development created the wrong application? &lt;strong&gt;snip&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;the market shifted and now our customers want something similar, but not exactly what we provide? &lt;strong&gt;snip&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;There never was any market research and so the company built something that nobody was looking for? &lt;strong&gt;nothing to cut, the rope has been in freefall this entire time!&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Why is this? My mentor's opinion is that many businesses culture is of &lt;em&gt;my life is over if I'm wrong&lt;/em&gt;. Of course, if we cannot be wrong because we'll be fired then we cannot do anything other than defend our decisions...even if we know they are wrong.&lt;/p&gt;

&lt;p&gt;To prevent this I am beginning my rope building adventure by practicing on myself. I'll be searching for the perfect place to put the eye bolt which the first section of rope will be tied to later. My mentor recommended the book &lt;a href="https://www.amazon.com/Lean-Startup-Entrepreneurs-Continuous-Innovation/dp/0307887898/ref=sr_1_3?crid=2AIMQA72NLCTL&amp;amp;keywords=lean+startup&amp;amp;qid=1569191343&amp;amp;sprefix=lean+star%2Caps%2C366&amp;amp;sr=8-3" rel="noopener noreferrer"&gt;The Lean Startup&lt;/a&gt; by Eric Ries to find where that eyebolt should be placed. From what I understand the plan will be to screw in the bolt to random metaphorical boards until one seems to hold.&lt;/p&gt;

&lt;p&gt;This is the second article (you can find the introduction &lt;a href="https://dev.to/denverdevs/what-business-does-a-dev-have-in-business-44mj"&gt;here&lt;/a&gt; about business here, are any of you interested in me continuing this series on Dev.to? Let me know with a comment. I plan to continue the adventure regardless but I also want to make sure I'm not adding noise where no-one is listening.&lt;/p&gt;

</description>
      <category>business</category>
    </item>
    <item>
      <title>What Business Does a Dev Have in Business?</title>
      <dc:creator>Brooks Patton</dc:creator>
      <pubDate>Sun, 22 Sep 2019 22:01:44 +0000</pubDate>
      <link>https://dev.to/denverdevs/what-business-does-a-dev-have-in-business-44mj</link>
      <guid>https://dev.to/denverdevs/what-business-does-a-dev-have-in-business-44mj</guid>
      <description>&lt;p&gt;I've recently taken to thinking about leadership, businesses, and why many of them fail. And having finished the &lt;a href="https://www.amazon.com/Phoenix-Project-DevOps-Helping-Business/dp/1942788290/ref=sr_1_1?crid=VKYYEZY70AHO&amp;amp;keywords=pheonix+project+book&amp;amp;qid=1569187680&amp;amp;sprefix=pheonix+project%2Caps%2C169&amp;amp;sr=8-1" rel="noopener noreferrer"&gt;Phoenix Project&lt;/a&gt; novel about applying a more holistic approach to business towards an IT department I began wondering how to go about creating the utopia that the book seems to end with. If you haven't read The Phoenix Project, I highly recommend it, but if you want the TLDR version, here is a long sentence that doesn't give anything away.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The Phoenix Project is a fictional / how to hybrid novel describing how a company with a deeply flawed culture gap between IT, engineering, and the rest of the company can change how they work and in turn take a failing company to a wildly successful company in a very short time.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Of course, I want to work at a company that sees and treats the engineering department more than just a machine that produces the products that make money. Engineers are a clever bunch, we creatively solve difficult problems for a living. I believe that we could provide so much more value if we were invited to help solve some of the business problems rather than just a room full of MBA's.&lt;/p&gt;

&lt;p&gt;Of course, that's crazy talk, right? Why would we want to step outside of engineering and into the political waters of the C-Suite?&lt;/p&gt;

&lt;p&gt;For one, we might be able to fix the toxic culture that has developers and designers switching jobs every year or two. We might even be able to help more companies survive and thrive in an ever-changing marketplace. We might even build the right product for the customers and change people's lives.&lt;/p&gt;

&lt;p&gt;I've seen far too many companies where danger is approaching, but the direction the company is looking is everywhere but that dark, stormy cloud. What is especially infuriating to me is that oftentimes (every time in my personal experience) the boots on the ground employees see the darkness coming, and even have really good suggestions that go unheard or worse, punished.&lt;/p&gt;

&lt;p&gt;This is why I want to learn the full-stack of business so that I can have a holistic view, speak the language of every team, and hopefully, help some amazing companies succeed and do good to their clients and employees at the same time.&lt;/p&gt;

</description>
      <category>business</category>
    </item>
  </channel>
</rss>
