<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>My Universe</title><link>https://www.my-universe.com/</link><description>Recent content on My Universe</description><generator>Hugo -- gohugo.io</generator><language>en-gb</language><lastBuildDate>Fri, 14 Feb 2025 16:54:59 +0100</lastBuildDate><atom:link href="https://www.my-universe.com/index.xml" rel="self" type="application/rss+xml"/><item><title>Pilatus PC-12 X-Plane Wallpaper</title><link>https://www.my-universe.com/2025/02/14/pilatus-pc-12-x-plane-wallpaper/</link><pubDate>Fri, 14 Feb 2025 16:54:59 +0100</pubDate><guid>https://www.my-universe.com/2025/02/14/pilatus-pc-12-x-plane-wallpaper/</guid><description>&lt;p>I was asked to share this wallpaper &amp;ndash; well, here you go. You can download the image
in full resolution here:
&lt;a href="https://www.my-universe.com/2025/02/14/pilatus-pc-12-x-plane-wallpaper/thranda_pc12_2560x1440.png">Thranda PC-12 Wallpaper (2560×1440)&lt;/a>&lt;/p>
&lt;p>Installation for X-Plane 12 is easy: just place the &lt;code>.png&lt;/code> file into the
&lt;code>Output/backgrounds/&lt;/code> folder of your X-Plane installation.&lt;/p></description></item><item><title>Configuration to Go</title><link>https://www.my-universe.com/2024/04/06/configuration-to-go/</link><pubDate>Sat, 06 Apr 2024 00:00:00 +0000</pubDate><guid>https://www.my-universe.com/2024/04/06/configuration-to-go/</guid><description>&lt;p>One of the boilerplate tasks for nearly every (application development) project is the implementation of an application configuration management. In most cases, applications have aspects we want to be configurable, e.g. the port a server listens on, the language an UI starts with or the database connection an application shall use. &lt;a href="https://12factor.net/">The twelve-factor app methodology&lt;/a> propagates using environment variables for this purpose, but what might be a good idea for cloud-deployed web apps won&amp;rsquo;t work equally well for desktop applications or in traditional deployment scenarios. For them, more traditional ways like configuration files or command line flags might be a better choice.&lt;/p></description></item><item><title>Elegant Python Exceptions</title><link>https://www.my-universe.com/2023/10/31/elegant-python-exceptions/</link><pubDate>Tue, 31 Oct 2023 00:00:00 +0000</pubDate><guid>https://www.my-universe.com/2023/10/31/elegant-python-exceptions/</guid><description>&lt;p>Particularly when creating library packages in &lt;a href="https://www.python.org/">Python&lt;/a>, raising exceptions is a great way to let the downstream developer know about problems occuring while executing code from within the library. Python&amp;rsquo;s &lt;a href="https://docs.python.org/3/library/exceptions.html">built-in exceptions&lt;/a> cover a whole host of cases. However, some problems might be library-specific and deserve a custom exception.&lt;/p>
&lt;h4 id="custom-exceptions">Custom Exceptions&lt;/h4>
&lt;p>Creating a &lt;a href="https://docs.python.org/3/tutorial/errors.html#user-defined-exceptions">custom exception&lt;/a> in Python isn&amp;rsquo;t particularly hard when observing a few rules:&lt;/p>
&lt;ul>
&lt;li>Custom exceptions shall be derived from Python&amp;rsquo;s &lt;a href="https://docs.python.org/3/library/exceptions.html#Exception">Exception&lt;/a> class&lt;/li>
&lt;li>By convention, exception names shall end with &amp;ldquo;Error&amp;rdquo;&lt;/li>
&lt;/ul>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-python" data-lang="python">&lt;span style="display:flex;">&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">1&lt;/span>&lt;span>&lt;span style="color:#ff79c6">class&lt;/span> &lt;span style="color:#50fa7b">MyLibError&lt;/span>(Exception):
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">2&lt;/span>&lt;span> &lt;span style="color:#ff79c6">pass&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>In many library packages, you will find exceptions similar to the one shown in the code example above. There&amp;rsquo;s nothing wrong with that; if chosen wisely, the exception name by itself will already tell what went wrong. However, the more details an exception provides about the circumstances it was raised in, the easier to diagnose and debug the problem, and the more appropriate the reaction to an exception.&lt;/p></description></item><item><title>Dataref Caching Revisited</title><link>https://www.my-universe.com/2023/09/27/dataref-caching-revisited/</link><pubDate>Wed, 27 Sep 2023 00:00:00 +0000</pubDate><guid>https://www.my-universe.com/2023/09/27/dataref-caching-revisited/</guid><description>&lt;p>Earlier this year I wrote about &lt;a href="https://www.my-universe.com/2023/04/20/cache-your-datarefs/">caching datarefs&lt;/a>. Back then we only looked at caching single datarefs, which quickly leads to bloated code once applied in a wider context. So here we are again, taking a closer look at caching &lt;em>many&lt;/em> datarefs efficiently.&lt;/p>
&lt;h4 id="what-about-trees">What About Trees&lt;/h4>
&lt;blockquote>
&lt;p>&amp;ldquo;Are we going to leave those poor little Datarefs here in this horrid, dark, dank, tree-infested &amp;mdash; I mean&amp;hellip; charming, quite charming, forest?&amp;rdquo;&lt;/p>
&lt;p>&amp;mdash; unknown dwarf coder&lt;/p></description></item><item><title>Configuration File with XPPL</title><link>https://www.my-universe.com/2023/09/23/configuration-file-with-xppl/</link><pubDate>Sat, 23 Sep 2023 00:00:00 +0000</pubDate><guid>https://www.my-universe.com/2023/09/23/configuration-file-with-xppl/</guid><description>&lt;p>In this blog post we&amp;rsquo;re looking into using &lt;a href="https://github.com/daemotron/xppl/">XPPL&lt;/a> to enhance a plugin with a configuration file. Working with XPPL&amp;rsquo;s configuration module is follows this five-step sequence:&lt;/p>
&lt;ol>
&lt;li>initialize a configuration context&lt;/li>
&lt;li>register configuration properties&lt;/li>
&lt;li>load the configuration file&lt;/li>
&lt;li>access the configuration values&lt;/li>
&lt;li>clean up&lt;/li>
&lt;/ol>
&lt;p>First, we need a configuration context. Since we will need to keep it alive throughout the whole plugin life cycle, we declare it as static, global variable:&lt;/p></description></item><item><title>Introducing XPPL</title><link>https://www.my-universe.com/2023/09/22/introducing-xppl/</link><pubDate>Fri, 22 Sep 2023 00:00:00 +0000</pubDate><guid>https://www.my-universe.com/2023/09/22/introducing-xppl/</guid><description>&lt;p>Are you tired of (re-)writing the same boilerplace code for every &lt;a href="https://www.x-plane.com">X-Plane&lt;/a> plugin project &amp;mdash; over and over again? Well, at least that&amp;rsquo;s how I felt when I started my fourth or fifth plugin. Sure, I reused a lot of my boilerplate code, but with every project, I refined and enhanced it. Backporting those changes to older plugins became a tedious task though; therefore I started the X-Plane Plugin Library (&lt;a href="https://github.com/daemotron/xppl">XPPL&lt;/a>).&lt;/p></description></item><item><title>Cache Your Datarefs</title><link>https://www.my-universe.com/2023/04/20/cache-your-datarefs/</link><pubDate>Thu, 20 Apr 2023 22:20:48 +0200</pubDate><guid>https://www.my-universe.com/2023/04/20/cache-your-datarefs/</guid><description>&lt;p>Nearly every X-Plane plugin accesses one or several of X-Plane&amp;rsquo;s &lt;a href="https://developer.x-plane.com/datarefs/">datarefs&lt;/a> at runtime. It&amp;rsquo;s not uncommon to find code like this:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-c" data-lang="c">&lt;span style="display:flex;">&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">1&lt;/span>&lt;span>&lt;span style="color:#8be9fd">void&lt;/span> &lt;span style="color:#50fa7b">set_data&lt;/span>(&lt;span style="color:#8be9fd">float&lt;/span> value)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">2&lt;/span>&lt;span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">3&lt;/span>&lt;span> XPLMDataRef dref &lt;span style="color:#ff79c6">=&lt;/span> &lt;span style="color:#50fa7b">XPLMFindDataRef&lt;/span>(&lt;span style="color:#f1fa8c">&amp;#34;what/ever/data/ref/we/need&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">4&lt;/span>&lt;span> &lt;span style="color:#50fa7b">XPLMSetDataf&lt;/span>(dref, value);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">5&lt;/span>&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Admittedly this works. However, there are a couple of reasons why the code above is not the best idea, if you&amp;rsquo;re seeking to write a solid and well-performing plugin:&lt;/p></description></item><item><title>Talk to the Log</title><link>https://www.my-universe.com/2023/01/14/talk-to-the-log/</link><pubDate>Sat, 14 Jan 2023 19:51:48 +0100</pubDate><guid>https://www.my-universe.com/2023/01/14/talk-to-the-log/</guid><description>&lt;p>Making an &lt;a href="https://www.x-plane.com/">X-Plane&lt;/a> plugin &amp;ldquo;talk&amp;rdquo; to us is one of the boilerplate tasks when setting up a new plugin project. X-Plane has its own log file, &lt;code>log.txt&lt;/code>, which is found in X-Plane&amp;rsquo;s root folder. The file gets reset every time X-Plane starts, so there&amp;rsquo;s no need to rotate or trim it from time to time. As a plugin author, we have the choice to either write our own log file, or to jump on X-Plane&amp;rsquo;s bandwagon and use its logging system for our purposes. While I can see the benefits of having a dedicated logfile for a plugin, personally I prefer to use X-Plane&amp;rsquo;s built in logging mechanism &amp;ndash; there are technical reasons, but mostly it&amp;rsquo;s a comfort and usability decision: most X-Plane users will immediately think of the central &lt;code>log.txt&lt;/code> file when a developer asks them to provide their log file (e.g. when reporting an issue).&lt;/p></description></item><item><title>CMake Linux Hack</title><link>https://www.my-universe.com/2023/01/11/cmake-linux-hack/</link><pubDate>Wed, 11 Jan 2023 00:16:46 +0100</pubDate><guid>https://www.my-universe.com/2023/01/11/cmake-linux-hack/</guid><description>&lt;p>Beginning with its most recent version (3.25 at the time of writing this post), &lt;a href="https://cmake.org/">CMake&lt;/a> provides the &lt;a href="https://cmake.org/cmake/help/latest/variable/LINUX.html">LINUX&lt;/a> variable, which I used in &lt;a href="https://www.my-universe.com/2023/01/04/x-plane-plugin-boilerplate/">my previous post&lt;/a>. Of course, developers on Linux tend to use the version of CMake they can install from their distribution&amp;rsquo;s package manager. On Ubuntu 22.04 LTS that would be 3.22, and even on the most recent Ubuntu version (22.10) we&amp;rsquo;re at 3.24 &amp;mdash; meaning this variable is not available in these CMake versions.&lt;/p></description></item><item><title>X-Plane Plugin Boilerplate</title><link>https://www.my-universe.com/2023/01/04/x-plane-plugin-boilerplate/</link><pubDate>Wed, 04 Jan 2023 15:28:28 +0100</pubDate><guid>https://www.my-universe.com/2023/01/04/x-plane-plugin-boilerplate/</guid><description>&lt;p>&lt;a href="https://www.x-plane.com">X-Plane&lt;/a> has a well-documented, accessible &lt;a href="https://developer.x-plane.com/sdk/">API&lt;/a>, making it relatively easy to write plugins for the simulator. In this post I&amp;rsquo;m going to demonstrate how a basic plugin boilerplate can look like, and how to build it on different platforms.&lt;/p>
&lt;p>Let&amp;rsquo;s get started with some basics: X-Plane plugins are dynamically linked libraries, which are loaded by X-Plane at runtime. They have to provide an API as defined by the X-Plane SDK, so X-Plane can access the plugin via defined entry points. The &lt;a href="https://developer.x-plane.com/sdk/">API documentation&lt;/a> explains all this, and also provides examples for basic and more advanced plugins. For this post I am going to use a very barebone plugin which does nothing except existing in X-Plane.&lt;/p></description></item><item><title>Reload 2023</title><link>https://www.my-universe.com/2023/01/03/reload-2023/</link><pubDate>Tue, 03 Jan 2023 21:19:03 +0100</pubDate><guid>https://www.my-universe.com/2023/01/03/reload-2023/</guid><description>&lt;p>More than five years without new content &amp;mdash; that&amp;rsquo;s a new sad record, even for me. Time to change things. While originally this site was set up to run with &lt;a href="https://github.com/HubPress/hubpress.io">HubPress&lt;/a>, it never really worked up for as well as it promised in the beginning. Working with HubPress was hit and miss &amp;mdash; for me it frequently lost its session context, losing some work done. Also it was pretty picky which browser it worked with. And finally, in 2019, HubPress got shut down. The GitHub repo is still around (archived, i.e. read-only), so there&amp;rsquo;s no hope the pending issues will ever see a fix.&lt;/p></description></item><item><title>Colours in Django Models</title><link>https://www.my-universe.com/2017/11/08/colours-in-django-models/</link><pubDate>Wed, 08 Nov 2017 00:00:00 +0000</pubDate><guid>https://www.my-universe.com/2017/11/08/colours-in-django-models/</guid><description>&lt;p>Colours are quite a common property to real world objects. So naturally when building web applications, sooner or later one encounters the need to assign a colour attribute to an object. For &lt;a href="https://djangoproject.com">Django&lt;/a> developers, this usually means adding a &lt;code>models.CharField&lt;/code> to their model, ready to capture the colour&amp;rsquo;s &lt;a href="https://en.wikipedia.org/wiki/Web_colors#Hex_triplet">hex code&lt;/a>.&lt;/p>
&lt;p>Technically this works pretty well, as those hex codes can directly be used in HTML style attributes, embedded SVG drawings, etc. However, setting colour values via text input widget is quite tedious. On the frontend side, various libraries offer quite elaborate solutions for integrating nice colour picking widgets. For the Django admin, there is however a quite simple solution: use HTML 5 color inputs!&lt;/p></description></item><item><title>Pythonic Distance Conversion</title><link>https://www.my-universe.com/2017/05/28/pythonic-distance-conversion/</link><pubDate>Sun, 28 May 2017 00:00:00 +0000</pubDate><guid>https://www.my-universe.com/2017/05/28/pythonic-distance-conversion/</guid><description>&lt;p>When dealing with distances or lengths, it&amp;rsquo;s a common problem to convert values between all the different units
available out there. Of course, converting itself is a less than complicated simple floating point division or
multiplication, depending on how values and conversion factors are stored internally. However, maintaining conversion
factors all across a project is a tedious task, and Python has some good means at hand to simplify our life.&lt;/p></description></item><item><title>GitFlow Groundhog Day</title><link>https://www.my-universe.com/2017/05/02/gitflow-groundhog-day/</link><pubDate>Tue, 02 May 2017 00:00:00 +0000</pubDate><guid>https://www.my-universe.com/2017/05/02/gitflow-groundhog-day/</guid><description>&lt;p>Yes, this is all over again the old discussion about what&amp;rsquo;s the best branching
model for projects using &lt;a href="https://git-scm.com/">Git&lt;/a> as their version control
system. I know, there are countless blog posts
(e. g. &lt;a href="https://nvie.com/posts/a-successful-git-branching-model/">1&lt;/a>,
&lt;a href="https://guides.github.com/introduction/flow/">2&lt;/a>, or
&lt;a href="https://barro.github.io/2016/02/a-succesful-git-branching-model-considered-harmful/">3&lt;/a>)
about that topic out there&amp;hellip; yet, I feel most of the discussion is focused on
projects with continuous deployment (i. e. mostly web applications), whereas
classical desktop software with classical release cycles are rather
underrepresented.&lt;/p>
&lt;p>First, some thoughts on what I actually need, before creating any new ideas
others put already in the bin due to being unfit&amp;hellip; When hacking on a desktop
software or an operating system (i. e. something that will be deployed on
many systems, by many people, without me as developer being aware), it all
comes down to releases. People are used to releases, updates etc. being clearly
labelled with a &lt;a href="https://semver.org/">semantic version&lt;/a> designator. This is no
different from what you should do for SAAS web applications &amp;mdash; what&amp;rsquo;s really
different here is that for desktop applications, several supported versions
can exist in parallel. So for me, a good branching model should&lt;/p></description></item><item><title>Reboot</title><link>https://www.my-universe.com/2017/04/30/reboot/</link><pubDate>Sun, 30 Apr 2017 00:00:00 +0000</pubDate><guid>https://www.my-universe.com/2017/04/30/reboot/</guid><description>&lt;blockquote>
&lt;p>I amar prestar aen,&lt;br>
Han mathon ne nen,&lt;br>
Han mathon ne chae&lt;br>
A han noston ned &amp;lsquo;wilith&lt;/p>
&lt;/blockquote>
&lt;p>And again, my world is changing. A bit more than one year ago, I moved from a self-hosted blog built with &lt;a href="https://ghost.org/">Ghost&lt;/a> to a fully managed website using Jimdo&amp;rsquo;s website construction kit. Sure, the effort for maintaining the full stack (server, os, database, web server software, etc.) has gone, and I certainly don&amp;rsquo;t want it back.&lt;/p></description></item></channel></rss>