Implement sidenav

This commit is contained in:
2024-07-05 16:00:03 -04:00
parent da79ad94fc
commit bbada68dcd
2 changed files with 266 additions and 117 deletions

View File

@@ -3,17 +3,87 @@
<head>
<title>dumpster.baby - A Blog</title>
<meta charset="UTF-8">
<style>
html { color:#ffffff; }
h1, h2, h3, h4, h5, h6 { color:#d1d1d1; font-family: "Roboto", sans-serif }
p { color:#bbbbbb; font-family: "Roboto", sans-serif }
.shitpost { background-color:#222222; padding-left:10px; padding-right:10px; padding-top:5px; }
a { color: #aaaaff;}
</style>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="style.css">
<script>
function openNav() {
document.getElementById("mySidenav").style.width = "350px";
document.getElementById("myMain").style.marginRight = "360px";
}
function closeNav()
{
document.getElementById("mySidenav").style.width = "0";
document.getElementById("myMain").style.marginRight = "0";
}
</script>
</head>
<body style="background-color:#282a36;">
<div id="mySidenav" class="sidenav">
<h4><a href="javascript:void(0)" class="closebtn" onclick="closeNav()">&times;</a></h4>
<br>
<ul>
<li><h4><a href="#FuckGitea">Fragile Dependency Management</a></h4>
<p>Ahmed Allen - 2024-07-05</p>
</li>
<li>
<h4><a href="#FuckDocker">Fuck Docker</a></h4>
<p>Dead Babe - 2024-07-05</p>
</li>
<li>
<h4><a href="#IGotFired">Getting Fired Ain't So Bad</a></h4>
<p>Ahmed Allen - 2024-07-05</p>
</li>
<li>
<h4><a href="#PrototypeVR">Don't Work With Children</a></h4>
<p>Ahmed Allen - 2024-07-05</p>
</li>
<li>
<h4><a href="#CaveGamePostMortem">CaveGame Post Mortem</a></h4>
<p>Ahmed Allen - 2024-07-05</p>
</li>
<li>
<h4><a href="#WhileWaitDo">The "While-Wait-Do" Idiom</a></h4>
<p>Mathhew "CntKillMe" - September 2018</p>
</li>
</ul>
</div>
<div id = "myMain" class="main">
<h1> dumpster.baby - The Aborted Fetuses of the Industry. </h1>
<h4> A blog on software failures. </h4>
<a onclick="openNav()">See All Articles</a>
<div class="articles">
<div id="FuckGitea" class="shitpost">
<h3><a href="#FuckGitea">Fragile Dependency Management</a></h3>
<p>Ahmed Allen 2024-07-05</p>
<p>When starting our C++ journey, we tested most of the industry-standard dependency management solutions like vcpkg, conan, github submodules, and several others.</p>
<p>We found all of these solutions to be fragile, unwieldy, or otherwise in bad taste. So we eventually found CMake Package Manager.</p>
<p>It's straightforward, a single script you add to your CMakeLists which allows pulling from our self-hosted git repositories. It allows us to link to specific releases to prevent versioning conflicts.</p>
<p>After several months of seamless and productive work with our technology stack, we've encountered the strangest issue.</p>
<p>Out of seemingly nowhere, Gitea changed it's behavior in regards to releases.</p>
<p>We publish releases for our projects, and gitea generates an archived zip file that can be directly downloaded. We use CPM in our projects to automatically pull these dependencies and build them.</p>
<p>However, a CPM call given a package url like "https://git.redacted.cc/maxi/mcolor/archive/Prerelease-1.zip", will expect to download a file with the name Prerelease-1.zip. This is obvious. At some point, the format changed. The file it actually downloads has the package name prefixed to it, i.e. "mcolor-Prerelease-1.zip".</p>
<p> What's the problem, you may be asking? It's a simple filename change, how hard can it be to accommodate?</p>
<p>Unfortunately, there is no straightforward way to specify a custom archive name, and there is no apparent way to set the format gitea uses to create the zip archives.</p>
<p>EDIT:</p>
<p>While writing this article, the issue seems to have disappeared. What the fuck? At least it works now.</p>
</div>
<div id="FuckDocker" class="shitpost">
<h3><a href="#FuckDocker">Fuck Docker</a></h3>
@@ -48,6 +118,7 @@
<h3><a href="#IGotFired">On Getting Fired - Losing A Job Ain't So Bad</a></h3>
<p> Ahmed Allen 2024-07-03 </p>
</div>
<div id="PrototypeVR" class="shitpost">
<h3><a href="#PrototypeVR">Don't work with children.</a></h3>
<p> Ahmed Allen 2024-07-03 </p>
@@ -56,6 +127,7 @@
<p> Then came the spark - watching an older brother bring over his PlayStation2, later an XBox360. Hitman, Call of Duty, GTA, you know them all already. The child was intensely fascinated with how a plastic box could make interactive games appear on the TV. But the details and capability to do so eluded the 6-year-old for some time. He resigned himself to sketching map concepts on graph paper. </p>
<p> Later on, that child gets a laptop for his 10th birthday. Immediately he takes an interest in building games, and rather obviously, stumbles upon this thing called ROBLOX. </p>
</div>
<div id="CaveGamePostMortem" class="shitpost">
<h3><a href="#CaveGamePostMortem">The CaveGame Post Mortem</a></h3>
<p> Ahmed Allen 2024-07-03 </p>
@@ -64,72 +136,75 @@
</div>
<div id="WhileWaitDo" class="shitpost">
<h3><a href="#WhileWaitDo">The "While-Wait-Do" Idiom</a> </h3>
<p style="">Matthew I. (CntKillMe)</p>
<p>Written September 2018</p>
<h4>Introduction</h4>
<p>&emsp;First and foremost, this is a document about a Roblox-specific concept that plagues experienced and inexperienced developers alike. If you don't do scripting within Roblox, this article is probably not going to be useful.</p>
<p>&emsp;It is very popular among the community to "shorthand" while loops by expressing the condition of the while loop with (or containing, typically as part of a conjunction) a function call to wait. At first glance, this seems rather innocent: an extra line is usually saved and the code is often just as readable. However, the drawbacks of such an idiom completely dominate all assumed (often inaccurately) benefits and can result in illogical coding habits.</p>
<p>&emsp;Not following this idiom has become almost a stigma in Roblox. There will always be a group of people telling you that you can and should be calling wait within the conditional portion of the while statement as opposed to in the body. The "apparent" benefits to this typically masks the problems encouraging such an idiom results in. Newcomers are taught to do this from an early stage and it infects their habits in a somewhat significant way.</p>
<h3><a href="#WhileWaitDo">The "While-Wait-Do" Idiom</a> </h3>
<p style="">Matthew I. (CntKillMe)</p>
<p>Written September 2018</p>
<h4>Introduction</h4>
<p>&emsp;First and foremost, this is a document about a Roblox-specific concept that plagues experienced and inexperienced developers alike. If you don't do scripting within Roblox, this article is probably not going to be useful.</p>
<p>&emsp;It is very popular among the community to "shorthand" while loops by expressing the condition of the while loop with (or containing, typically as part of a conjunction) a function call to wait. At first glance, this seems rather innocent: an extra line is usually saved and the code is often just as readable. However, the drawbacks of such an idiom completely dominate all assumed (often inaccurately) benefits and can result in illogical coding habits.</p>
<p>&emsp;Not following this idiom has become almost a stigma in Roblox. There will always be a group of people telling you that you can and should be calling wait within the conditional portion of the while statement as opposed to in the body. The "apparent" benefits to this typically masks the problems encouraging such an idiom results in. Newcomers are taught to do this from an early stage and it infects their habits in a somewhat significant way.</p>
<h4>Benefit - "Less code is cleaner [or more readable] code"</h4>
<p>&emsp;This is by far the most popular rationale behind why people prefer to use this idiom. I cannot deny that this appears to often be true when taken at face value, but it is really only true when less code results in less complexity, which is not always the case.</p>
<p>&emsp;If we define cleaner in a way that reasonably minimizes line count, then sure, you have an argument. You sometimes save what on average is about 1 line per all applicable while loops (more on this later). However cleaner is best defined as something that is more simple and maintainable (which typically yields more readable code). A few extra lines typically will not affect readability, however abusing the purpose of the conditional portion of a while loop is clearly less simple.</p>
<p>&emsp;When you call wait in the condition for whether the loop should continue, you make the implication that the return value is somehow important in determining whether or not the loop should terminate. Except that in all scenarios where this happens, the return value of wait is irrelevant. The fact that it returns anything at all is irrelevant, we just abuse the fact that wait does return something that is neither false nor nil. This is clearly less simple code, because we introduce an unnecessary test for our condition when we already know it will never be false or nil.</p>
<p>&emsp;The entire purpose of the conditional part of a while loop is to determine when the loop should terminate. When while true do is read, you understand it is as an infinite loop immediately. True is always true, which makes it obvious that the loop does not necessarily have a terminating condition.</p>
<p>&emsp;When while f() do is read, the general idea is the loop will not terminate until f returns a falsy value. while wait() do then, when directly interpreted, means the loop will terminate once wait returns a falsy value. The problem is this idiom alters our perspective and makes an exception to this rule, we no longer treat the terminating condition as a terminating condition when wait is called. We learn to associate while wait() do as a non-terminating loop. Clearly an unnecessary distinction, and one that can be quite confusing for beginners who have not yet come across this idiom. Although the added complexity is quite small, the pitfalls that come about utilizing such an idiom can be quite alarming (more on this later).</p>
<h4>Benefit - "Less code is cleaner [or more readable] code"</h4>
<p>&emsp;This is by far the most popular rationale behind why people prefer to use this idiom. I cannot deny that this appears to often be true when taken at face value, but it is really only true when less code results in less complexity, which is not always the case.</p>
<p>&emsp;If we define cleaner in a way that reasonably minimizes line count, then sure, you have an argument. You sometimes save what on average is about 1 line per all applicable while loops (more on this later). However cleaner is best defined as something that is more simple and maintainable (which typically yields more readable code). A few extra lines typically will not affect readability, however abusing the purpose of the conditional portion of a while loop is clearly less simple.</p>
<p>&emsp;When you call wait in the condition for whether the loop should continue, you make the implication that the return value is somehow important in determining whether or not the loop should terminate. Except that in all scenarios where this happens, the return value of wait is irrelevant. The fact that it returns anything at all is irrelevant, we just abuse the fact that wait does return something that is neither false nor nil. This is clearly less simple code, because we introduce an unnecessary test for our condition when we already know it will never be false or nil.</p>
<p>&emsp;The entire purpose of the conditional part of a while loop is to determine when the loop should terminate. When while true do is read, you understand it is as an infinite loop immediately. True is always true, which makes it obvious that the loop does not necessarily have a terminating condition.</p>
<p>&emsp;When while f() do is read, the general idea is the loop will not terminate until f returns a falsy value. while wait() do then, when directly interpreted, means the loop will terminate once wait returns a falsy value. The problem is this idiom alters our perspective and makes an exception to this rule, we no longer treat the terminating condition as a terminating condition when wait is called. We learn to associate while wait() do as a non-terminating loop. Clearly an unnecessary distinction, and one that can be quite confusing for beginners who have not yet come across this idiom. Although the added complexity is quite small, the pitfalls that come about utilizing such an idiom can be quite alarming (more on this later).</p>
<h4>Benefit - "Less code is faster code"</h4>
<p>&emsp;Most people already know this is false, and admittedly this rationale is not often used as an argument in favor of this idiom. However I have come across quite a few people who believe this to be true. Of course it is not true, the performance difference between the two are beyond negligible that outside noise is likely to make more of an impact. It is unfortunate that people always fall accustom to premature optimization, but it is these people that argue in favor of this idiom just for this reason. If they can be pedantic, so can I. Technically, following this idiom actually results in slower code as the return value of wait must be tested. However Lua does a small optimization when certain truthy constants are used as the condition, no value testing will need to be done and instead it will fall straight through into the loop's body (see luaK_goiftrue in lcode.c). Of course testing a value is quite quick, so for me to tell you to not to use this idiom because it is slower would make me a victim of premature optimization. Truth is, there is practically no difference and it is not even worth thinking about.</p>
<h4>Benefit - "Less code is faster code"</h4>
<p>&emsp;Most people already know this is false, and admittedly this rationale is not often used as an argument in favor of this idiom. However I have come across quite a few people who believe this to be true. Of course it is not true, the performance difference between the two are beyond negligible that outside noise is likely to make more of an impact. It is unfortunate that people always fall accustom to premature optimization, but it is these people that argue in favor of this idiom just for this reason. If they can be pedantic, so can I. Technically, following this idiom actually results in slower code as the return value of wait must be tested. However Lua does a small optimization when certain truthy constants are used as the condition, no value testing will need to be done and instead it will fall straight through into the loop's body (see luaK_goiftrue in lcode.c). Of course testing a value is quite quick, so for me to tell you to not to use this idiom because it is slower would make me a victim of premature optimization. Truth is, there is practically no difference and it is not even worth thinking about.</p>
<h4>Benefit - "Everyone uses it"</h4>
<p>&emsp;This rationale is perhaps the only real benefit. In general, it is a good idea to follow the same conventions everyone else uses to write more consistent and easily-understood code. Unfortunately, not all popular conventions are sound. There is no doubt that many have become accustomed to this idiom, but following it is bad practice. Needlessly increasing the complexity of our code in such a way is just unnecessary and following this idiom almost always redefines what the conditional part of a while loop is even meant to be used for.</p>
<h4>Benefit - "Everyone uses it"</h4>
<p>&emsp;This rationale is perhaps the only real benefit. In general, it is a good idea to follow the same conventions everyone else uses to write more consistent and easily-understood code. Unfortunately, not all popular conventions are sound. There is no doubt that many have become accustomed to this idiom, but following it is bad practice. Needlessly increasing the complexity of our code in such a way is just unnecessary and following this idiom almost always redefines what the conditional part of a while loop is even meant to be used for.</p>
<h4>Non Maintainability</h4>
<p>&emsp;Perhaps the most obvious problem is how the idiom strips our freedom by forcing us to yield at the start of each iteration rather when it may be more appropriate. From a functionality standpoint, this seems to be hardly a problem. However by staying consistent with this convention, the return value of wait will always be lost. Normally that is fine, however in some cases it is very useful to know how long the thread has actually been yielded for. Typically if logic needs to be adjusted precisely over time, the return value of wait can be important to ensure consistent logic across fluctuating yield times. In such a case, the call to wait will be moved into the body. In the worst case, wait is called again within the body because the idiom is too deeply rooted that it becomes impossible to imagine a while loop that does not call wait in its conditional part. As stupid as this might sound, it is a somewhat common mistake that occasionally affects newcomers. By consistently pushing this idiom, beginners see it to be a good convention to follow and stick to it. Before they even fully understand while loops they are writing code that abuses it.</p>
<h4>Non Maintainability</h4>
<p>&emsp;Perhaps the most obvious problem is how the idiom strips our freedom by forcing us to yield at the start of each iteration rather when it may be more appropriate. From a functionality standpoint, this seems to be hardly a problem. However by staying consistent with this convention, the return value of wait will always be lost. Normally that is fine, however in some cases it is very useful to know how long the thread has actually been yielded for. Typically if logic needs to be adjusted precisely over time, the return value of wait can be important to ensure consistent logic across fluctuating yield times. In such a case, the call to wait will be moved into the body. In the worst case, wait is called again within the body because the idiom is too deeply rooted that it becomes impossible to imagine a while loop that does not call wait in its conditional part. As stupid as this might sound, it is a somewhat common mistake that occasionally affects newcomers. By consistently pushing this idiom, beginners see it to be a good convention to follow and stick to it. Before they even fully understand while loops they are writing code that abuses it.</p>
<h4>Bad Habits</h4>
<p>&emsp;Since following this idiom results in a sort of mindset change that makes abusing while loops like this okay, it becomes easy to forget what the purpose of the conditional part even is. All too often code is written in the following manner:</p>
<h4>Bad Habits</h4>
<p>&emsp;Since following this idiom results in a sort of mindset change that makes abusing while loops like this okay, it becomes easy to forget what the purpose of the conditional part even is. All too often code is written in the following manner:</p>
<pre><code>
1. while wait() do
2. if ((p1 - p2).Magnitude <= 100) then
3. break
4. end
5. end
</code></pre>
<pre><code>
1. while wait() do
2. if ((p1 - p2).Magnitude <= 100) then
3. break
4. end
5. end
</code></pre>
<p>instead of in the correct manner:</p>
<p>instead of in the correct manner:</p>
<code><pre>
1. while (p1 - p2).Magnitude > 100 do
2. wait()
3. end
</pre></code>
<code><pre>
1. while (p1 - p2).Magnitude > 100 do
2. wait()
3. end
</pre></code>
<p>&emsp;Actually utilizing while loops correctly instead of sticking with this idiom can easily increase simplicity, readability, maintainability, and (to a miniscule extent) efficiency. This is not just a trivial example, a lot of people write similarly to the first example all the time. I was at one point a "While-Wait-Do Idiom Follower" as well. Time and time again I would see people spouting nonsense like "while true do crashes your place, always do while wait() do instead." Or when people were being convinced to follow this idiom if they have not already because some established group of people (i.e. active forumers and popular developers) were doing so.</p>
<p>&emsp;Actually utilizing while loops correctly instead of sticking with this idiom can easily increase simplicity, readability, maintainability, and (to a miniscule extent) efficiency. This is not just a trivial example, a lot of people write similarly to the first example all the time. I was at one point a "While-Wait-Do Idiom Follower" as well. Time and time again I would see people spouting nonsense like "while true do crashes your place, always do while wait() do instead." Or when people were being convinced to follow this idiom if they have not already because some established group of people (i.e. active forumers and popular developers) were doing so.</p>
<h4>Too Long, Didn't Read</h4>
<h4>Too Long, Didn't Read</h4>
<p>I follow this idiom for:</p>
<ul>
<li><p>Readability reasons: <b>No.</b></p></li>
<li><p>Maintainability reasons: <b>No.</b></p></li>
<li><p>Performance reasons: <b>Read benefit 2.</b></p></li>
<li><p>Conventional reasons: <b>Get over it.</b></p></li>
<li><p>Because I can: <b>Congratulations! You're a bad programmer.</b></p></li>
</ul>
<p>I don't follow this idiom for:</p>
<ul>
<li><p>Readability reasons: <b>Okay.</b></p></li>
<li><p>Maintainability reasons: <b>Yes.</b></p></li>
<li><p>Performance reasons: <b>Read benefit 2.</b></p></li>
<li><p>Conventional reasons: <b>You're a rebel. 🤘</b></p></li>
<li><p>Because I can: <b>Congratulations! No one cares.</b></p></li>
</ul>
<p>I follow this idiom for:</p>
<ul>
<li><p>Readability reasons: <b>No.</b></p></li>
<li><p>Maintainability reasons: <b>No.</b></p></li>
<li><p>Performance reasons: <b>Read benefit 2.</b></p></li>
<li><p>Conventional reasons: <b>Get over it.</b></p></li>
<li><p>Because I can: <b>Congratulations! You're a bad programmer.</b></p></li>
</ul>
<p>I don't follow this idiom for:</p>
<ul>
<li><p>Readability reasons: <b>Okay.</b></p></li>
<li><p>Maintainability reasons: <b>Yes.</b></p></li>
<li><p>Performance reasons: <b>Read benefit 2.</b></p></li>
<li><p>Conventional reasons: <b>You're a rebel. 🤘</b></p></li>
<li><p>Because I can: <b>Congratulations! No one cares.</b></p></li>
</ul>
</div>
<div>
</div>
<p>This work is dedicated to the public domain.</p>
</div>
</body>
</html>

74
style.css Normal file
View File

@@ -0,0 +1,74 @@
html { color:#ffffff; }
h1, h2, h3, h4, h5, h6 { color:#e2e2e2; font-family: "Roboto", sans-serif }
p { color:#bbbbbb; font-family: "Roboto", sans-serif }
body
{
}
#main
{
transition: margin-right 0.5s;
-webkit-transition: margin-right 0.5s;
-moz-transition: margin-right 0.5s;
-ms-transition: margin-right 0.5s;
-o-transition: margin-right 0.5s;
}
.articles {}
.sidenav
{
background-color:#202025;
height:100%;
position: fixed;
z-index:1;
overflow-x: hidden;
top: 0;
right: 0;
width: 0;
min-width: 0;
border-radius:10px;
border:2px #aaaaff solid;
padding-top: 5px;
transition: 0.25s;
-webkit-transition: 0.25s;
-moz-transition: 0.25s;
-ms-transition: 0.25s;
-o-transition: 0.25s;
-webkit-border-radius:10px;
-moz-border-radius:10px;
-ms-border-radius:10px;
-o-border-radius:10px;
margin-top: 10px;
margin-right: 5px;
}
.sidenav .closebtn
{
position: absolute;
top: 0;
right: 25px;
font-size: 36px;
margin-left: 50px;
}
.sidenav p
{
line-height: 0%;
font-size: 12px;
}
.shitpost {
background-color:#202025;
padding-left:10px;
padding-right:10px;
padding-top:5px;
border-radius:10px;
border:2px #aaaaff solid;
margin-bottom:10px;
}
a { color: #aaaaff;}