Commit ca07be8f authored by bbguimaraes's avatar bbguimaraes
Browse files

blog: highlight

parent 0ac82363
......@@ -38,7 +38,7 @@ I remember as if it was today how puzzled I was by that line. As I said, I
didn't know much of the incantations on that list, but this was by far the most
magical. The line goes like this:
</p>
<pre><code>$ seq -f '4/%g' 1 2 9999 | paste -sd-+ | bc
<pre><code>$ seq -f <b>'4/%g'</b> <b>1</b> <b>2</b> <b>9999</b> | paste -sd-+ | bc
-l</code></pre>
<p>
If you like a challenge (as I do), try to figure it out by yourself. A shell
......@@ -49,7 +49,7 @@ and the man pages are your best friends.
If shell (or python) wasn't your first programming language, you were probably
surprised by the way loops are done. It usually goes like this:
</p>
<pre><code>$ for x in 1 2 3 4 5; do echo "$x"; done
<pre><code>$ <b>for</b> x <b>in</b> <b>1</b> <b>2</b> <b>3</b> <b>4</b> <b>5</b>; <b>do</b> <b>echo</b> <b>"$x"</b>; <b>done</b>
    1
    2
    3
......@@ -59,18 +59,18 @@ surprised by the way loops are done. It usually goes like this:
If you have a little experience with shell, you probably learned there is a
more idiomatic way of doing this using the seq command and some shell voodoo:
</p>
<pre><code>$ for x in $(seq 1 5); do echo "$x"; done</code></pre>
<pre><code>$ <b>for</b> x <b>in</b> $(seq <b>1</b> <b>5</b>); <b>do</b> <b>echo</b> <b>"$x"</b>; <b>done</b></code></pre>
<p>
And if you were truly initiated on the dark arts of bash programming, you
probably know this is functionally equivalent to this:
</p>
<pre><code>$ for x in {1..5}; do echo "$x"; done</code></pre>
<pre><code>$ <b>for</b> x <b>in</b> {<b>1..5</b>}; <b>do</b> <b>echo</b> <b>"$x"</b>; <b>done</b></code></pre>
<p>
I won't explain how shell command substitution works, suffice to say seq is a
nice utility to generate sequences (get it?) of numbers. From the first lines
of the man page:
</p>
<pre><code>$ man seq | grep -A 3 SYNOPSIS
<pre><code>$ man seq | grep -A <b>3</b> SYNOPSIS
    SYNOPSIS
           seq [OPTION]... LAST
           seq [OPTION]... FIRST LAST
......@@ -79,12 +79,12 @@ of the man page:
So the main part of the first command on the pipe is no magic: we are
generating numbers from 1 to 9999 with a step of 2:
</p>
<pre><code>$ echo $(seq 1 2 9999 | head -5)
<pre><code>$ <b>echo</b> $(seq <b>1</b> <b>2</b> <b>9999</b> | head -5)
1 3 5 7 9</code></pre>
<p>
There is a useful option to this command to control how the value is output:
</p>
<pre><code>$ seq -f '%02g' 1 3 10
<pre><code>$ seq -f <b>'%02g'</b> <b>1</b> <b>3</b> <b>10</b>
    01
    04
    07
......@@ -101,27 +101,27 @@ There are some commands that do something so simple they seem almost useless:
    paste (1)            - merge lines of files
    paste (1p)           - merge corresponding or subsequent lines of files</code></pre>
<p>Nothing really interesting here, right?</p>
<pre><code>$ paste <(seq 1 3) <(seq 4 6)
<pre><code>$ paste <(seq <b>1</b> <b>3</b>) <(seq <b>4</b> <b>6</b>)
    1       4
    2       5
    3       6
$ seq 1 6 | paste - -
$ seq <b>1</b> <b>6</b> | paste - -
    1       2
    3       4
    5       6</code></pre>
<p>
Well, that is interesting. What if we play with the other options?
</p>
<pre><code>$ paste -sd, <(seq 1 3) <(seq 4 6)
<pre><code>$ paste -sd, <(seq <b>1</b> <b>3</b>) <(seq <b>4</b> <b>6</b>)
1,2,3
4,5,6
$ seq 1 6 | paste -sd,
$ seq <b>1</b> <b>6</b> | paste -sd,
1,2,3,4,5,6</code></pre>
<p>
This simple command is starting to show complex behavior. Maybe there is
something interesting in those old unix books after all... Wait:
</p>
<pre><code>$ seq 1 6 | paste -sd+
<pre><code>$ seq <b>1</b> <b>6</b> | paste -sd+
1+2+3+4+5+6</code></pre>
<p>
Nice, a mathematical expression. If only we had some way of interpreting it...
......@@ -144,7 +144,7 @@ scale = 80
Do you see that <i>\</i> character? It's almost as if it was meant to be used
on a shell...
</p>
<pre><code>$ seq 1 6 | paste -sd+ | bc -l
<pre><code>$ seq <b>1</b> <b>6</b> | paste -sd+ | bc -l
21</code></pre>
<h2 id="interlude-gregory-leibniz">
<a href="#interlude-gregory-leibniz">
......@@ -181,36 +181,36 @@ So here is the challenge: how can we generate and evaluate the terms of this
series? Generating each term, without the sign, can be done easily with seq
and a format string:
</p>
<pre><code>$ seq -f '1/%g' 1 2 9
<pre><code>$ seq -f <b>'1/%g'</b> <b>1</b> <b>2</b> <b>9</b>
1/1
1/3
1/5
1/7
1/9</code></pre>
<p>Remember our useful-where-you-never-imagined friend paste?</p>
<pre><code>$ seq -f '1/%g' 1 2 9 | paste -sd-+
<pre><code>$ seq -f <b>'1/%g'</b> <b>1</b> <b>2</b> <b>9</b> | paste -sd-+
1/1-1/3+1/5-1/7+1/9</code></pre>
<p>
This may take some time to understand, it's ok. Read those man pages! But
once you understand, the only thing left is to evaluate the expression:
</p>
<pre><code>$ seq -f '1/%g' 1 2 9 | paste -sd-+ | bc -l
<pre><code>$ seq -f <b>'1/%g'</b> <b>1</b> <b>2</b> <b>9</b> | paste -sd-+ | bc -l
.83492063492063492064</code></pre>
<p>
Hmm, not much π-like, is it? Right, this is π/4. Ok, we can rearrange the
terms a bit to fit our tools (that is the essential hacker skill). Lets move
the denominator on the right side to the numerator on the left.
</p>
<pre><code>$ seq -f '4/%g' 1 2 9 | paste -sd-+ | bc -l
<pre><code>$ seq -f <b>'4/%g'</b> <b>1</b> <b>2</b> <b>9</b> | paste -sd-+ | bc -l
3.33968253968253968254</code></pre>
<p>
That's more like it! As any infinite series approximation, we can increase the
number of terms to increase accuracy:
</p>
<pre><code>$ seq -f '4/%g' 1 2 9999 | paste -sd-+ | bc -l
<pre><code>$ seq -f <b>'4/%g'</b> <b>1</b> <b>2</b> <b>9999</b> | paste -sd-+ | bc -l
3.14139265359179323814</code></pre>
<p>Now just for the heck of it:</p>
<pre><code>$ seq -f '4/%g' 1 2 999999 | paste -sd-+ | bc -l
<pre><code>$ seq -f <b>'4/%g'</b> <b>1</b> <b>2</b> <b>999999</b> | paste -sd-+ | bc -l
3.14159065358979323855</code></pre>
<p>And there you have it. Enjoy your unix π.</p>
<div class="tags">
......
......@@ -35,12 +35,12 @@ Let's start with a really common operation. You download a tarball, extract,
<pre><code>$ wget http://www.kernel.org/pub/linux/kernel/v3.0/linux-3.7.9.tar.bz2
$ tar -xjf linux-3.7.9.tar.bz2
$ cd linux-3.7.9
$ bob's your uncle</code></pre>
$ <i># bob's your uncle</i></code></pre>
<p>Using the <i>Tab</i> key, you can save a lot of typing:</p>
<pre><code>$ wget http://www.kernel.org/pub/linux/kernel/v3.0/linux-3.7.9.tar.bz2
$ tar -xjf l&lt;TAB&gt;
$ cd l&lt;TAB&gt;
$ bob's your uncle</code></pre>
$ tar -xjf l<i>&lt;TAB&gt;</i>
$ cd l<i>&lt;TAB&gt;</i>
$ <i># bob's your uncle</i></code></pre>
<p>
However, this is highly dependent on the contents of your directory, names in
your path and auto-complete configurations.
......@@ -62,18 +62,18 @@ alternatives: bash (get it?) has a nice feature called substitutions. You may
have come across it before if you ever tried to add an unescaped exclamation
mark (henceforth mentioned using the niftier name "bang"):
</p>
<pre><code>$ echo "Bang!"
<pre><code>$ <b>echo</b> <b>"Bang!"</b>
bash: !": event not found</code></pre>
<p>Or got surprised by it:</p>
<pre><code>$ echo "balrog:!you shall not pass:/nonexistent:/bin/false" >> /etc/passwd
echo "balrog:youtube-dl http://www.youtube.com/watch?v=pLgJ7pk0X-s shall not pass:/nonexistent:/bin/false" >> /tmp/test
<pre><code>$ echo <b>"balrog:!you shall not pass:/nonexistent:/bin/false"</b> &gt;&gt; /etc/passwd
<b>echo</b> "balrog:youtube-dl http://www.youtube.com/watch?v=pLgJ7pk0X-s shall not pass:/nonexistent:/bin/false" &gt;&gt; /tmp/test
$ sleep 3d; grep balrog /etc/passwd
balrog:youtube-dl http://www.youtube.com/watch?v=pLgJ7pk0X-s shall not pass:/nonexistent:/bin/false</code></pre>
<p>
That is because the bang is used to reference previous commands. The simplest
is substitution of the last command:
</p>
<pre><code>$ echo billy
<pre><code>$ <b>echo</b> billy
billy
$ !!
echo billy
......@@ -113,21 +113,21 @@ cat $(cat my_files)
contents_of_file1
contents_of_file2
contents_of_file3
$ perl -e 'bang your head on the keyboard'
$ perl -e <b>'bang your head on the keyboard'</b>
# god only knows
$ echo "!!" > file_to_save_command
$ # This could be done by clever use of Ctrl-x Ctrl-e, but
$ # sometimes you're in a hurry. That's alright, as long as
$ # you <a href="http://tldp.org/LDP/abs/html/escapingsection.html">do it carefully</a>.</code></pre>
$ <b>echo</b> <b>"!!"</b> &gt; file_to_save_command
$ <i># This could be done by clever use of Ctrl-x Ctrl-e, but</i>
$ <i># sometimes you're in a hurry. That's alright, as long as</i>
$ <i># you <a href="http://tldp.org/LDP/abs/html/escapingsection.html">do it carefully</a>.</i></code></pre>
<p>
When <i>!</i> is followed by a number <i>n</i>, it executes the <i>n</i>th
command in the history (which you can check with the <i>history</i> command).
More useful, though, is that, if <i>n</i> is negative, it will execute the last
<i>n</i>th command:
</p>
<pre><code>$ echo some
<pre><code>$ <b>echo</b> some
some
$ echo thing
$ <b>echo</b> thing
thing
$ !-2
echo some
......@@ -145,22 +145,22 @@ scenario:
</p>
<pre><code>$ ls ef
son daughter dog
$ # oh my, ef is a directory
$ cd ef</code></pre>
$ <i># oh my, ef is a directory</i>
$ <b>cd</b> ef</code></pre>
<p>or how about:</p>
<pre><code>$ mv some_directory a_different_name_for_some_directory
$ cd a_different_name_for_some_directory</code></pre>
$ <b>cd</b> a_different_name_for_some_directory</code></pre>
<p>
It is very common to address the same file on multiple, successive commands.
You can, again, save some typing:
</p>
<pre><code>$ ls ef
son daughter dog
$ # oh my, ef is a directory
$ cd !$
$ <i># oh my, ef is a directory</i>
$ <b>cd</b> !$
cd ef
$ mv some_directory a_different_name_for_some_directory
$ cd !$
$ <b>cd</b> !$
cd some_directory a_different_name_for_some_directory</code></pre>
<p>
As you can see, <i>!$</i> is substituted by the last argument of the last
......@@ -184,7 +184,7 @@ them in a different order, or some non-contiguous arguments, just use more than
one substitution:
</p>
<pre><code>$ diff ours theirs
$ # gah
$ <i># gah</i>
$ diff !:2 !:1
diff theirs ours</code></pre>
<p>
......@@ -223,23 +223,23 @@ If you ever got stabbed by not knowing how the bang works (like the examples I
showed in the beginning), you can avoid getting stabbed again by escaping the
bangs, either with a backslash or single quotes:
</p>
<pre><code>$ echo Bang\!
<pre><code>$ <b>echo</b> Bang\!
Bang!
$ echo 'balrog:!you shall not pass:/nonexistent:/bin/false' >> /etc/passwd</code></pre>
$ <b>echo</b> <b>'balrog:!you shall not pass:/nonexistent:/bin/false'</b> &gt;&gt; /etc/passwd</code></pre>
</li>
<li>
<p>
More of a side note, but to get that humongous file name, I discovered a new
(string of) command(s) to get the longest line from a text.
</p>
<pre><code>$ find /sys/ | awk '{print length, $0;}' | sort -nr | head -n 1</code></pre>
<pre><code>$ find /sys/ | awk <b>'{print length, $0;}'</b> | sort -nr | head -n 1</code></pre>
<p>
You can probably do the same thing (although it might be a little slower) using
a while loop and another bash trick: while <i>$variable</i> (or
<i>${variable}</i>) will give you the contents of a variable,
<i>${#variable}</i> will give you the length of that content.
</p>
<pre><code>$ find /sys/ | while read i; do echo "${#i} $i" | sort -nr | head -n 1</code></pre>
<pre><code>$ find /sys/ | <b>while</b> <b>read</b> i; <b>do</b> <b>echo</b> <b>"${#i} $i"</b>; <b>done</b> | sort -nr | head -n 1</code></pre>
<p>
Apparently, Jethro Tull's Too Old to Rock 'n' Roll, Too Old to Die generates
pretty long file names (the title song is the second only to a really long
......
......@@ -31,11 +31,11 @@ to correct it later, I surrounded it with the (pseudo-randomly chosen)
</p>
<pre><code>This is the actual text.
\dots
<b>\dots</b>
This is some text I'll need later.
\ldots
<b>\ldots</b>
This is more of the actual text.</code></pre>
<p>
......@@ -47,11 +47,11 @@ command:
</p>
<pre><code>This is the actual text
\iffalse
<b>\iffalse</b>
This is some text I'll need latex.
\fi
<b>\fi</b>
This is more of the actual text.</code></pre>
<p>
......
......@@ -136,7 +136,7 @@ A script is used in my builds, which is executed once, before the final
its only significant actions are:
</p>
<a class="src-ref" data-hash="a079068db60c13c975173c7c8c4453534bcf8799" href="https://gitlab.bbguimaraes.com/bbguimaraes/nngn/-/blob/master/scripts/emscripten/build.sh">scripts/emscripten/build.sh</a>
<pre><code>patch -Np0 < "$PATCHES_DIR/lua.patch"
<pre><code>patch -Np0 < <b>"$PATCHES_DIR/lua.patch"</b>
pushd src/
emmake make generic ALL=liblua.a</code></pre>
<p>
......@@ -172,11 +172,11 @@ Because of how <code>emscripten</code> builds work, this is also the step where
Lua libraries and scripts (all regular source code text files) are included:
</p>
<a class="src-ref" data-hash="72a7757b61fcc5f4d81137de337ee769ad9bce7f" href="https://gitlab.bbguimaraes.com/bbguimaraes/nngn/-/blob/master/Makefile.am">Makefile.am</a>
<pre><code>nngn_js_LDFLAGS= \
$(nngn_js_CXXFLAGS) -O3 --source-map-base / \
<pre><code><b>nngn_js_LDFLAGS</b> = \
<b>$(nngn_js_CXXFLAGS)</b> -O3 --source-map-base / \
--embed-file $(srcdir)/src/lua/@src/lua \
--embed-file $(srcdir)/src/lson/@src/lson \
# …</code></pre>
<i># …</i></code></pre>
<h2 id="bonus">
<a href="bonus">bonus: console REPL</a>
</h2>
......@@ -196,11 +196,11 @@ between Javascript and the application. The simplest form is via
simple C entry point is included in the program:
</p>
<a class="src-ref" data-hash="eb9fcddd4fd6c1c73cd10384fb3f800e0ff6799a" href="https://gitlab.bbguimaraes.com/bbguimaraes/nngn/-/blob/master/src/main.cpp">src/main.cpp</a>
<pre><code>#ifdef NNGN_PLATFORM_EMSCRIPTEN
extern "C" {
void lua(const char *s) { NNGN_LOG_CONTEXT_F(); p_nngn->lua.dostring(s); }
<pre><code><b>#ifdef</b> NNGN_PLATFORM_EMSCRIPTEN
<b>extern</b> <b>"C"</b> {
<b>void</b> lua(<b>const</b> <b>char</b> *s) { NNGN_LOG_CONTEXT_F(); p_nngn->lua.dostring(s); }
}
#endif</code></pre>
<b>#endif</b></code></pre>
<aside>
<p>For completeness:</p>
<ul>
......@@ -223,11 +223,11 @@ member is the object that wraps the <code>lua_State*</code>.
This function is then exposed as described in the documentation linked above:
</p>
<a class="src-ref" data-hash="72a7757b61fcc5f4d81137de337ee769ad9bce7f" href="https://gitlab.bbguimaraes.com/bbguimaraes/nngn/-/blob/master/Makefile.am">Makefile.am</a>
<pre><code>nngn_js_CXXFLAGS = \
$(AM_CXXFLAGS) \
<pre><code><b>nngn_js_CXXFLAGS</b> = \
<b>$(AM_CXXFLAGS)</b> \
… \
-s EXPORTED_FUNCTIONS='["_main","_lua"]' \
-s EXTRA_EXPORTED_RUNTIME_METHODS='["ccall","cwrap"]' \
-s EXPORTED_FUNCTIONS=<b>'["_main","_lua"]'</b> \
-s EXTRA_EXPORTED_RUNTIME_METHODS=<b>'["ccall","cwrap"]'</b> \
</code></pre>
<p>
And that is it! We now have an application compiled to WebAssembly that has a
......
......@@ -88,40 +88,40 @@ statements are <code>dofile</code>s (Lua's version of <code>#include</code> or
<code>import</code>) which load and execute separate, specialized scripts:
</p>
<a class="src-ref" data-hash="40833fe56c2306e2df2a52289bc7ee7678155107" href="https://gitlab.bbguimaraes.com/bbguimaraes/nngn/-/blob/master/src/lua/all.lua">src/lua/all.lua</a>
<pre><code>dofile "src/lua/init.lua"
dofile "src/lua/limits.lua"
dofile "src/lua/main.lua"
dofile "maps/main.lua"</code></pre>
<pre><code><b>dofile</b> <b>"src/lua/init.lua"</b>
<b>dofile</b> <b>"src/lua/limits.lua"</b>
<b>dofile</b> <b>"src/lua/main.lua"</b>
<b>dofile</b> <b>"maps/main.lua"</b></code></pre>
<p>
Each of these in turn is composed of lower-level pieces:
</p>
<a class="src-ref" data-hash="abed4e12a019e62bd9aa9423b77bf8347af31f34" href="https://gitlab.bbguimaraes.com/bbguimaraes/nngn/-/blob/master/src/lua/init.lua">src/lua/init.lua</a>
<pre><code>dofile "src/lua/path.lua"
require("nngn.lib.compute").init()
require("nngn.lib.graphics").init()
require("nngn.lib.collision").init()
nngn.socket:init("sock")</code></pre>
<pre><code><b>dofile</b> <b>"src/lua/path.lua"</b>
<b>require</b>(<b>"nngn.lib.compute"</b>).init()
<b>require</b>(<b>"nngn.lib.graphics"</b>).init()
<b>require</b>(<b>"nngn.lib.collision"</b>).init()
nngn.socket:init(<b>"sock"</b>)</code></pre>
<a class="src-ref" data-hash="cf0b3a65506344cc77a1e1facda3e19dd725d251" href="https://gitlab.bbguimaraes.com/bbguimaraes/nngn/-/blob/master/src/lua/limits.lua">src/lua/limits.lua</a>
<pre><code>nngn.entities:set_max(1 << 20)
nngn.animations:set_max(1 << 16)
nngn.graphics:resize_textures(16)
nngn.textures:set_max(16)
-- …</code></pre>
<pre><code>nngn.entities:set_max(<b>1</b> &lt;&lt; <b>20</b>)
nngn.animations:set_max(<b>1</b> &lt;&lt; <b>16</b>)
nngn.graphics:resize_textures(<b>16</b>)
nngn.textures:set_max(<b>16</b>)
<i>-- …</i></code></pre>
<a class="src-ref" data-hash="ab5bf80d6445868ec241e4c8418148611454f61b" href="https://gitlab.bbguimaraes.com/bbguimaraes/nngn/-/blob/master/src/lua/main.lua">src/lua/main.lua</a>
<pre><code>local camera = require "nngn.lib.camera"
local entity = require "nngn.lib.entity"
local font = require "nngn.lib.font"
local map = require "nngn.lib.map"
local player = require "nngn.lib.player"
dofile "src/lua/input.lua"
-- …
<pre><code><b>local</b> camera = <b>require</b> <b>"nngn.lib.camera"</b>
<b>local</b> entity = <b>require</b> <b>"nngn.lib.entity"</b>
<b>local</b> font = <b>require</b> <b>"nngn.lib.font"</b>
<b>local</b> map = <b>require</b> <b>"nngn.lib.map"</b>
<b>local</b> player = <b>require</b> <b>"nngn.lib.player"</b>
<b>dofile</b> <b>"src/lua/input.lua"</b>
<i>-- …</i>
camera.reset()
player.set{
"src/lson/crono.lua", "src/lson/link.lua", "src/lson/link_sh.lua",
"src/lson/fairy0.lua", "src/lson/chocobo.lua", "src/lson/null.lua"}
<b>"src/lson/crono.lua"</b>, <b>"src/lson/link.lua"</b>, <b>"src/lson/link_sh.lua"</b>,
<b>"src/lson/fairy0.lua"</b>, <b>"src/lson/chocobo.lua"</b>, <b>"src/lson/null.lua"</b>}
nngn:load_texture()
font.load(32)
nngn.grid:set_dimensions(32.0, 64)</code></pre>
font.load(<b>32</b>)
nngn.grid:set_dimensions(<b>32.0</b>, <b>64</b>)</code></pre>
<h3 id="demos"><a href="#demos">demos</a></h3>
<p>
<a href="/nngn#demos">Demos</a> and other special-purpose cases are scripts
......@@ -132,59 +132,59 @@ camera placement, default parameters for the various sub-systems, etc.) by
loading the appropriate script:
</p>
<a class="src-ref" data-hash="5d48b238abaf1199562d6ca443b6b06059a46ae7" href="https://gitlab.bbguimaraes.com/bbguimaraes/nngn/-/blob/master/demos/demo1.lua">demos/demo1.lua</a>
<pre><code>dofile "src/lua/init.lua"
dofile "src/lua/limits.lua"
dofile "src/lua/main.lua"
-- …
DEMO = {i = 1, stages = {}, data = {}}
<pre><code><b>dofile</b> <b>"src/lua/init.lua"</b>
<b>dofile</b> <b>"src/lua/limits.lua"</b>
<b>dofile</b> <b>"src/lua/main.lua"</b>
<i>-- …</i>
DEMO = {i = <b>1</b>, stages = {}, data = {}}
function DEMO:add_stage(text, f)
-- …
<b>function</b> DEMO:add_stage(text, f)
<i>-- …</i>
table.insert(self.stages, {text, f})
end
<b>end</b>
function DEMO:next()
local i, stages = self.i, self.stages
if i > #stages then return end
local text, f = table.unpack(stages[i])
if f then f() end
textbox.update("nngn", text)
<b>function</b> DEMO:next()
<b>local</b> i, stages = self.i, self.stages
<b>if</b> i &gt; #stages then return end
<b>local</b> text, f = <b>table.unpack</b>(stages[i])
<b>if</b> f <b>then</b> f() <b>end</b>
textbox.update(<b>"nngn"</b>, text)
self.i = i + 1
end
-- …
DEMO:add_stage([[
<b>end</b>
<i>-- …</i>
DEMO:add_stage(<b>[[
The engine has dynamic lighting. At the
moment, only a dim ambient light exists.]],
function()
dofile("maps/wolfenstein.lua")
nngn.lighting:set_shadows_enabled(false)
end)
-- …
moment, only a dim ambient light exists.]]</b>,
<b>function</b>()
<b>dofile</b>(<b>"maps/wolfenstein.lua"</b>)
nngn.lighting:set_shadows_enabled(<b>false</b>)
<b>end</b>)
<i>-- …</i>
input.input:add(
Input.KEY_ENTER, Input.SEL_PRESS,
function() DEMO:next() end)
-- …</code></pre>
<b>function</b>() DEMO:next() <b>end</b>)
<i>-- …</i></code></pre>
<h3 id="benchmarks"><a href="#benchmarks">benchmarks</a></h3>
<p>
Benchmarks are scripts that set up the engine in a similar manner and either
leave the test running or run it for a while and dump the results:
</p>
<a class="src-ref" data-hash="61ffd3ae17460d5a86acb66b874eb2800d69d015" href="https://gitlab.bbguimaraes.com/bbguimaraes/nngn/-/blob/master/demos/colliders.lua">demos/colliders.lua</a>
<pre><code>dofile "src/lua/path.lua"
local entity = require "nngn.lib.entity"
local player = require "nngn.lib.player"
require "src/lua/input"
-- …
local colliders = {
-- …
<pre><code><b>dofile</b> <b>"src/lua/path.lua"</b>
<b>local</b> entity = <b>require</b> <b>"nngn.lib.entity"</b>
<b>local</b> player = <b>require</b> <b>"nngn.lib.player"</b>
<b>require</b> <b>"src/lua/input"</b>
<i>-- …</i>
<b>local</b> colliders = {
<i>-- …</i>
}
-- …
for i = 1, N do
<i>-- …</i>
<b>for</b> i = <b>1</b>, N <b>do</b>
entity.load(nil, nil, {
pos = {rnd(), rnd(), 0},
collider = colliders[nngn.math:rand_int(1, n_col)]})
end
-- …</code></pre>
pos = {rnd(), rnd(), <b>0</b>},
collider = colliders[nngn.math:rand_int(<b>1</b>, n_col)]})
<b>end</b>
<i>-- …</i></code></pre>
<h3 id="integration-tests">
<a href="#integration-tests">
integration tests
......@@ -195,36 +195,36 @@ Integration tests are scripts that set up the engine, exercise some part of it
via the Lua interface, and check the results:
</p>
<a class="src-ref" data-hash="0f59333d712f00d2a80554ed1e2c5f24129deafa" href="https://gitlab.bbguimaraes.com/bbguimaraes/nngn/-/blob/master/demos/cl/vector.lua">demos/cl/vector.lua</a>
<pre><code>dofile "src/lua/path.lua"
local common = require "demos/cl/common"
<pre><code><b>dofile</b> <b>"src/lua/path.lua"</b>
<b>local</b> common = <b>require</b> <b>"demos/cl/common"</b>
nngn:set_compute(Compute.OPENCL_BACKEND, Compute.opencl_params{debug = true})
nngn:set_compute(Compute.OPENCL_BACKEND, Compute.opencl_params{debug = <b>true</b>})
local prog = assert(
<b>local</b> prog = <b>assert</b>(
nngn.compute:create_program(
io.open("demos/cl/vector.cl"):read("a"), "-Werror"))
-- …
local function test_add_numbers()
print("add_numbers:")
local out = exec(
Compute.FLOATV, 2, prog, "add_numbers", Compute.BLOCKING, {8}, {4}, {
<b>io.open</b>(<b>"demos/cl/vector.cl"</b>):read(<b>"a"</b>), <b>"-Werror"</b>))
<i>-- …</i>
<b>local</b> <b>function</b> test_add_numbers()
<b>print</b>("add_numbers:")
<b>local</b> out = exec(
Compute.FLOATV, <b>2</b>, prog, <b>"add_numbers"</b>, Compute.BLOCKING, {<b>8</b>}, {<b>4</b>}, {
Compute.FLOATV, {
0, 1, 2, 3, 4, 5, 6, 7,
8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23,
24, 25, 26, 27, 28, 29, 30, 31,
32, 33, 34, 35, 36, 37, 38, 39,
40, 41, 42, 43, 44, 45, 46, 47,
48, 49, 50, 51, 52, 53, 54, 55,
56, 57, 58, 59, 60, 61, 62, 63},
Compute.LOCAL, 4 * Compute.SIZEOF_FLOAT})
local sum = out[1] + out[2]
print(sum)
if not common.err_check(sum, 64 / 2 * 63, .01) then
error("check failed")
end
end
-- …</code></pre>
<b>0</b>, <b>1</b>, <b>2</b>, <b>3</b>, <b>4</b>, <b>5</b>, <b>6</b>, <b>7</b>,
<b>8</b>, <b>9</b>, <b>10</b>, <b>11</b>, <b>12</b>, <b>13</b>, <b>14</b>, <b>15</b>,
<b>16</b>, <b>17</b>, <b>18</b>, <b>19</b>, <b>20</b>, <b>21</b>, <b>22</b>, <b>23</b>,
<b>24</b>, <b>25</b>, <b>26</b>, <b>27</b>, <b>28</b>, <b>29</b>, <b>30</b>, <b>31</b>,
<b>32</b>, <b>33</b>, <b>34</b>, <b>35</b>, <b>36</b>, <b>37</b>, <b>38</b>, <b>39</b>,
<b>40</b>, <b>41</b>, <b>42</b>, <b>43</b>, <b>44</b>, <b>45</b>, <b>46</b>, <b>47</b>,
<b>48</b>, <b>49</b>, <b>50</b>, <b>51</b>, <b>52</b>, <b>53</b>, <b>54</b>, <b>55</b>,
<b>56</b>, <b>57</b>, <b>58</b>, <b>59</b>, <b>60</b>, <b>61</b>, <b>62</b>, <b>63</b>},
Compute.LOCAL, <b>4</b> * Compute.SIZEOF_FLOAT})
<b>local</b> sum = out[<b>1</b>] + out[<b>2</b>]
<b>print</b>(sum)
<b>if</b> <b>not</b> common.err_check(sum, <b>64</b> / <b>2</b> * <b>63</b>, <b>.01</b>) then
<b>error</b>(<b>"check failed"</b>)
<b>end</b>
<b>end</b>
<i>-- …</i></code></pre>
<h2 id="socket">
<a href="#socket">
<code>socket(2)</code>
......@@ -304,7 +304,7 @@ sort of loop, my preferred approach is to open the file in <code>vim</code>
it, depending on whether a shell or Lua script for that particular case exists
or not:
</p>
<pre><code>:w | !nc -NU sock &lt;&lt;&lt;"…"
<pre><code>:w | !nc -NU sock &lt;&lt;&lt;<b>"…"</b>
:w | !nc -NU sock < script.lua