tag:blogger.com,1999:blog-58288699562622882832024-03-17T01:08:05.917-07:00if it's not dark, it's not dataBrucehttp://www.blogger.com/profile/12452129679810623214noreply@blogger.comBlogger70125tag:blogger.com,1999:blog-5828869956262288283.post-73161166358343133392017-02-27T10:00:00.000-08:002017-02-27T10:00:49.106-08:00Sorting out Gjs with TypescriptI get why Gnome wants to use javascript. I love the language. The thing is, I don't love Gnome's implementation.<br />
<br />
The syntax is getting out of date, and my experience with other engines doesn't translate well to the Gjs environment. Combine this with a lack of documentation. If Gnome wants to attract javascript developers, this isn't the way to do it. Its not too bad when you are coding a one page demo widget, but try coding an ambitious desktop application. Without relevant api information, I'm coding blindfolded.<br />
<br />
One solution would be to use Typescript. All I need to do is translate the *.gir metadata to *.d.ts format, so I've created a tool<br />
<br />
<a href="https://www.npmjs.com/package/gir2dts">https://www.npmjs.com/package/gir2dts</a><br />
<br />
All I have to do is install with npm, and reference the contained *.d.ts files.<br />
<br />
There are a couple of samples in the example folder at <a href="https://github.com/darkoverlordofdata/gir2dts">https://github.com/darkoverlordofdata/gir2dts</a><br />
<br />
This tool was designed to facillitate the development of another application, so it's a great example of a Gjs/Typescript application: <a href="https://github.com/darkoverlordofdata/bosco-player">https://github.com/darkoverlordofdata/bosco-player</a>Brucehttp://www.blogger.com/profile/12452129679810623214noreply@blogger.com19tag:blogger.com,1999:blog-5828869956262288283.post-36129260462194581892017-02-22T09:52:00.001-08:002017-02-22T09:52:45.165-08:00Just Don't Write Ambigous CodeI've stopped putting semicolons in my javascript, at least for my own projects. It makes code so much easier to read. But wait? Don't we need semicolons in cases where the code is ambigous?<br />
<br />
Sure. But why write ambigous code? Unless you are competing to write the longest one line program, there is no point.<br />
<br />
If I need a semicolon to make my javascript work, then my code isn't clear. And when I come back to it in 6 months, I'm going to be Say What? Semicolons are like a yellow flag saying 'Why are you doing it this way'.<br />
<br />
Actually, like nost best practices, the real best practice is don't blindly follow the best practice, instead you should think.<br />
<br />
There are actually some places I still use a semicolon. For loops for one. And switches:<br />
<br />
<br />
<pre><code>switch(op) {
case 0: doZero(); break
case 1: doOne(); break
...
</code></pre>
<br />
<div>
And of course, if maintaining existing code where the style guide calls for semicolons, please respect it.<br />
<br />
Here is an actually informative posting on the subject: <a href="http://mislav.net/2010/05/semicolons/">http://mislav.net/2010/05/semicolons/</a></div>
Brucehttp://www.blogger.com/profile/12452129679810623214noreply@blogger.com7tag:blogger.com,1999:blog-5828869956262288283.post-45918990765722838032017-02-14T13:49:00.000-08:002017-02-14T13:52:21.633-08:00Gtk and CoffeeScript? Someone reminded me recently that Gnome's official language is GJS. I love javascript, and I would be all over that except for one thing. Standards. What version is it, anyway? It's not ES6. It's not ES5. It reminds me of issues with IE. But we have tools for this - things like Babel, TypeScript, and my favorite, CoffeeScript.<br />
<br />
So, <a href="http://coffeescript.org/">CoffeeScript</a> it is, and the first thing that goes is<br />
<br />
const Lang = imports.lang;<br />
<br />
This is what CoffeeScript replaces. Now we have a real 1st class class statement.<br />
<br />
So here is my port of Gnome's HelloWorld example,<br />
<div>
<a href="https://developer.gnome.org/gnome-devel-demos/stable/hello-world.js.html.en">https://developer.gnome.org/gnome-devel-demos/stable/hello-world.js.html.en</a></div>
<div>
<br /></div>
<pre><code>
Gtk = imports.gi.Gtk
class Application
#create the application
constructor: () ->
@application = new Gtk.Application()
#connect to 'activate' and 'startup' signals to handlers.
@application.connect('activate', @_onActivate)
@application.connect('startup', @_onStartup)
# create the UI
_buildUI: () ->
@_window = new Gtk.ApplicationWindow(application: @application, title: "Hello World!")
@_window.set_default_size(200, 200)
@label = new Gtk.Label(label: "Hello World" )
@_window.add(@label)
# handler for 'activate' signal
_onActivate: () =>
# show the window and all child widgets
@_window.show_all()
# handler for 'startup' signal
_onStartup: () =>
@_buildUI()
#run the application
app = new Application()
app.application.run(ARGV)
</code></pre>
<div>
<br /></div>
<div>
The important thing to note, is that we no longer use Lang.bind:</div>
<div>
<br /></div>
<pre><code>
this.application.connect('activate', Lang.bind(this, this._onActivate));
</code></pre>
<div>
<br />
Instead, the function definition is bound using the fat arrow:<br />
<div>
<br /></div>
<pre><code>
_onActivate: () =>
</code></pre>
<div>
<br /></div>
<br />
The other thing I ran into is shebang support. Coffeescript treats it as a coment and discards it.<br />
So I follow up my compile with a simple fix replacing the coffescript header with shebang.<br />
<div>
<br /></div>
<pre><code>
coffee -c test.coffee
sed -i "s/\/\/ Generated by CoffeeScript 1.11.1/\#\!\/usr\/bin\/env gjs/" test.js
</code></pre>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<br />
<br /></div>
Brucehttp://www.blogger.com/profile/12452129679810623214noreply@blogger.com1tag:blogger.com,1999:blog-5828869956262288283.post-76724727398704767902017-01-29T09:31:00.000-08:002017-01-29T09:50:21.672-08:00Using OOC in VisualStudio CodeIs that Fernando the Wonder Llama in the <a href="https://ooc-lang.org/">Object Oriented C</a> logo?<br />
<br />
You can use yo code to import a textmate bundle. The vscode website has a simple tutorial. <a href="https://code.visualstudio.com/Docs/customization/colorizer">https://code.visualstudio.com/Docs/customization/colorizer</a><br />
Or you can download the one I've just imported:<br />
<br />
$ cd ~/.vscode/extensions<br />
$ git clone git@github.com:darkoverlordofdata/vscode-ooc.git<br />
<br />
You'll also need to configure launch and build tasks. Put the following launch.json & task.json files in the project .vscode folder.<br />
I'm assuming a simple case, where project, folder and executable share the same name:<br />
<br />
project/project.use<br />
project/source/project.ooc<br />
<br />
Install the vscode LLDB plugin to debug c programs. I'm used to using ctrl-b to build, F5 to debug.<br />
<br />
<b>launch.json</b><br />
<div>
<br /></div>
<pre><code>{
"version": "0.2.0",
"configurations": [
{
"name": "Debug",
"type": "lldb",
"request": "launch",
"cwd": "${workspaceRoot}",
"program": "${workspaceRoot}/${workspaceRootFolderName}",
"args": []
}
]
}<span style="font-family: "times new roman";"><span style="white-space: normal;">
</span></span></code></pre>
<div>
<br />
Building ooc is pretty simple. But I ran into a problem with the SDL2 examples, it was unable to find sdl *.h files.<br />
Oh, they are there - both Vala and Nim programs compile just fine.<br />
I think ooc was developed on a mac, and this may be one of those corners where Mac and Ubuntu differ on standards. It is easy to fix in the build task, pointing to the include folder with the -I flag:<br />
<br />
<b>tasks.json</b></div>
<div>
<br /></div>
<pre><code>{
"version": "0.1.0",
"command": "/bin/sh",
"cwd": "${workspaceRoot}",
"isShellCommand": true,
"args": ["-c"],
"showOutput": "always",
"echoCommand": true,
"suppressTaskName": true,
"tasks": [
{
"isBuildCommand": true,
"taskName": "build",
"args": ["rock -I/usr/include/SDL2 -v ${workspaceRootFolderName}.use"]
}
]
}<span style="font-family: "times new roman";"><span style="white-space: normal;">
</span></span></code></pre>
<div>
<br />
Now I am able to run the SDL2 demo's for ooc using VSCode!</div>
<div>
<br /></div>
Brucehttp://www.blogger.com/profile/12452129679810623214noreply@blogger.com2tag:blogger.com,1999:blog-5828869956262288283.post-45428915865705869752016-12-11T21:38:00.003-08:002016-12-11T21:49:14.079-08:00Vala RevisitedThe last time I looked into Vala, I became a bit discouraged. I couldn't find good tooling. The documentation could be better. I wasn't getting good performance. I think a full GObect is too expensive for game components.<br />
<br />
I have found better tooling. There is a Vala plugin for VSCode <a href="https://marketplace.visualstudio.com/items?itemName=thiagoabreu.vala">https://marketplace.visualstudio.com/items?itemName=thiagoabreu.vala</a>. I like vscode. It's fast, easy to use and flexible. I can focus on my code and stop worrying.<br />
<br />
But whan I say Vala, I really mean Genie. Most of my code for valac is written using Genie. So I've started a plugin for Genie <a href="https://github.com/darkoverlordofdata/vscode-genie">https://github.com/darkoverlordofdata/vscode-genie</a>. Along with the LLDB, CMake and C/C++ plugins, I have all I need for quick iterative development.<br />
<br />
Now about GObject. The documentation is unclear. All the examples extend it as a base class. Why do I need it? There are dire warnings that language features like interfaces and properties won't work without it. And then there is a disclaimer that 'In a more recent Vala compiler' this is relaxed. But there are no specifics. Has that version been released? I think I'm better off not reading the documentation.<br />
<br />
So I've factored out GLib.Object to 'try it and see'. All my classes now extend a custom, empty object. In one posting, Gnome calls these 'Non-Object' classes. But, as it turns out, it makes no difference. When I removed GObject, no features were impacted. My performance problems went away, but adding GObject back in doesn't re-introduce them... So where did they come from? What changed?<br />
<br />
Time passes - new computer. New OS. Newer SDL libraries. Newer Vala runtime. Take your pick. But the good news is that it works pretty good now. Comparable to Nim.<br />
<div>
<br /></div>
<div>
<div>
Benchmarking can be tricky. So I've tracked the average time per frame taken up by the update method on my game object. </div>
</div>
<div>
<br /></div>
<div>
<pre> time in ms
nim vala
min 0.00015 0.00019
max 0.00202 0.0035
avg 0.00082 0.0009
</pre>
<br />
<br />
At 60 fps, each frame is .0167ms, and these are all very acceptable times. Vala and Nim seem pretty well tied for performance. </div>
<div>
<br />
Vala project: <a href="https://github.com/darkoverlordofdata/shmupwarz-vala">https://github.com/darkoverlordofdata/shmupwarz-vala</a><br />
Nim: <a href="https://github.com/darkoverlordofdata/shmupwarz-nim">https://github.com/darkoverlordofdata/shmupwarz-nim</a></div>
Brucehttp://www.blogger.com/profile/12452129679810623214noreply@blogger.com2tag:blogger.com,1999:blog-5828869956262288283.post-48693401975914000922016-11-28T09:48:00.001-08:002016-11-28T09:48:45.813-08:00Giving the Devil it's DueThat 'devil' bing Microsoft. I know, <a href="https://blog.darkoverlordofdata.com/2016/03/just-say-no-to-microsoft.html">https://blog.darkoverlordofdata.com/2016/03/just-say-no-to-microsoft.html</a>. But I have to move on, and what's more, I had to buy a new computer.<br />
<br />
My beautiful new ASUS Zenbook came with Windows 10 pre-installed. I of course dual booted it with ElementaryOS, but since then, I'm a bit embarassed to say, most of my time has been spent using Windows 10.<br />
<br />
It used to be when asked why I choose Linux, the answer was easy. But my reasons are mostly technical, and Windows 10 really addresses many of them. There are still many good reasons to choose Linux -<br />
<br />
<br />
<ul>
<li>Windows 10 Desktop is very distracting. I Love ElementaryOS.</li>
<li>Linux fonts are still easier for me to read.</li>
<li>I prefer Geary to MS Mail</li>
<li>Build processes like gradle run faster on Linux - this impacts iterative testing.</li>
<li>The Windows Subsystem for Linux isn't well suited for gui programming.</li>
</ul>
<br />
<br />
But Windows has Visual Studio 2015 and Xamarin with excellent support for MonoGame and FSharp, and a path to put FSharp on Android. This seems preferable to my current path of Android Studio, Scala, and libGDX. And it's a jvm free solution - did I ever mention that I hate the jvm?Brucehttp://www.blogger.com/profile/12452129679810623214noreply@blogger.com0tag:blogger.com,1999:blog-5828869956262288283.post-64973022309600432682016-09-10T17:08:00.000-07:002016-09-10T17:08:00.861-07:00ElementaryOS Loki - The TricksterAfter installing the latest ElementaryOS Loki, I was left sadly unimpressed. It seemed bugy for a release. But I needed a break, and I had found my old Creative ZEN all covered in dust. I was able to pull off some old music videos of The Small Faces that I wanted to see (I'll get to the point...) I hadn't looked at these in years. So I fired up Videos, surely THAT would be non stressful. The video started, but there was no sound. Check - yep sounds are turned on. I must be missing some codecs. I run<br />
<br />
<blockquote class="tr_bq">
sudo apt-get install ubuntu-restricted-extras</blockquote>
<br />
And then I have music. And the light came on. During install, I had connected to the internet and selected to<br />
<br />
<br />
<ul>
<li>load updates while installing</li>
<li>install 3rd party software wich includes MP3</li>
</ul>
<br />
<br />
But apparently it didn't happen. So I clicked on AppCenter and selected Updates, and sure enough, there was a whole slew of updates waiting. The moral of this story is always double check the install.<br />
<br />
After running those updates and rebooting, I found that most of the bugy stuff was gone.<br />
<br />
And now I am suitabley impressed with Loki!Brucehttp://www.blogger.com/profile/12452129679810623214noreply@blogger.com0tag:blogger.com,1999:blog-5828869956262288283.post-52211617360490390052016-09-09T21:17:00.000-07:002016-09-09T21:17:05.374-07:00After Installing ElementaryOS Loki 4I upgraded to ElementaryOS Loki Stable Release today. Installing a new OS is often stressful, but this was worst I've experienced in a few years. Was it worth it? Yep. I'm in love!<br />
I've recorded the steps I went thru to 'get back to normal'<br />
<br />
1) Elementary has hobbled the command line package manager. To restore:<br />
<blockquote class="tr_bq">
sudo dpkg --configure -a<br />sudo apt-get update<br />sudo apt-get install gdebi<br />apt-get install software-properties-common</blockquote>
<br />
2) There is an upgraded version of Elementary Tweaks! Bright desktops give me a headache, I need the dark theme to function:<br />
<blockquote class="tr_bq">
sudo add-apt-repository ppa:philip.scott/elementary-tweaks && sudo apt-get update<br />sudo apt-get install elementary-tweaks</blockquote>
<br />
3) Elementary doesn't allow desktop icons. I don't get why.<br />
<blockquote class="tr_bq">
sudo apt-get install -–no-install-recommends nautilus dconf-tools<br />Here are the instructions I follow to configure the desktop:<br /><a href="http://mylinuxideas.blogspot.com/2015/04/enable-desktop-icons-and-right-click-on.html">http://mylinuxideas.blogspot.com/2015/04/enable-desktop-icons-and-right-click-on.html</a></blockquote>
<br />
4) And I want a show desktop icon. This puts it right on the plank:<br />
<blockquote class="tr_bq">
sudo apt-get install wmctrl<br />cd /tmp && wget https://github.com/png2378/showdesktop/archive/master.zip<br />unzip master.zip && cd showdesktop-master<br />sudo mv showdesktop /usr/local/bin/ && sudo mv showdesktop.desktop /usr/share/applications/ && sudo mv showdesktop.svg /usr/share/icons/elementary/apps/48/<br />mv showdesktop.dockitem ~/.config/plank/dock1/launchers/<br /><a href="http://elementaryos.stackexchange.com/questions/2001/add-icon-to-show-desktop">http://elementaryos.stackexchange.com/questions/2001/add-icon-to-show-desktop</a></blockquote>
<br />
<br />
Finally, I found that Loki still has a couple of quirks.<br />
1) My mouse cursor disappears. To prevent this, I set the power setting 'Turn off display when inactive' to Never.<br />
2) The top bar keeps freezing up. I created a simple desktop icon to fix that when I click on it:<br />
<br />
<blockquote class="tr_bq">
[Desktop Entry]<br />Version=1.0<br />Terminal=false<br />Type=Application<br />Name=Fix Wingpanel<br />Exec=pkill wingpanel<br />Icon=/usr/share/icons/elementary/apps/64/utilities-terminal.svg<br />Comment[en_US]=Fix Frozen Top Bar<br />GenericName[en_US]=Fix Frozen Top Bar</blockquote>
<div>
Save this to ~/Desktop/Fix.desktop then start a terminal and enter:</div>
<blockquote class="tr_bq">
$ chmod +x Desktop/Fix.desktop</blockquote>
And now I click on it about 50 times a day...<br />
Brucehttp://www.blogger.com/profile/12452129679810623214noreply@blogger.com14tag:blogger.com,1999:blog-5828869956262288283.post-70192289605722238622016-06-23T10:46:00.000-07:002016-06-23T10:46:06.299-07:00Using ES6 Modules in CoffeeScriptAs we saw in my last post, <a href="https://blog.darkoverlordofdata.com/2016/06/mixing-globls-with-es6-module.html">https://blog.darkoverlordofdata.com/2016/06/mixing-globls-with-es6-module.html</a>, we can use the TypeScript compiler to transpile import/export statements in our ES6 files. But were not really limited to ES6.<br />
<br />
We can also use CoffeeScript as a pre-processor for the TypeScript compiler. To use modules in CoffeeScript is pretty easy, we can use the tick (`) to escape javascipt. Hopefully this will fully supported soon at the syntax level.<br />
<br />
Suppose I create a module like this:<br />
<div>
<br />
<pre class="prettyprint"><code>`import Batch from 'gdx/graphics/g2d/Batch'`
class SpriteBatch extends Batch
`export default SpriteBatch`
</code></pre>
<br />
and then I compile like this, where my jsconfig.json file references the output from coffee:
<br />
<br />
<pre class="prettyprint"><code>coffee -o src/js -bc src/coffee && tsc -p jsconfig.json
</code></pre>
<br />
And something like this is emitted by typescript into the outpur file:
</div>
<div>
<pre class="prettyprint"><code>
define("gdx/graphics/g2d/SpriteBatch", ["require", "exports", "gdx/graphics/g2d/Batch"], function (require, exports, Batch_1) {
"use strict";
SpriteBatch = (function (superClass) {
extend(SpriteBatch, superClass);
function SpriteBatch() {
return SpriteBatch.__super__.constructor.apply(this, arguments);
}
return SpriteBatch;
})(Batch_1.default);
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = SpriteBatch;
});
```</code></pre>
</div>
<div>
<br />
Using typescript to build my coffescript. Why does that seem so wrong?</div>
Brucehttp://www.blogger.com/profile/12452129679810623214noreply@blogger.com0tag:blogger.com,1999:blog-5828869956262288283.post-18233933110633372842016-06-21T10:09:00.000-07:002016-06-23T10:34:41.313-07:00Mixing Globals with ES6 Module ImplementationTypescript 1.8 adds the new jsconfig.json format. So now, when the compilerOptions.module field is set to 'system' or 'amd' and compilerOptions.outFile is also set, typescript will bundle all of my modules, transpiling import/export polyfills. But it incudes no implementation for those polyfills. I could use SystemJs, but that is another external, and it's overkill - I only need to use module syntax internally, to see other modules in the same bundle.<br />
<br />
My project consumes globals, such as PIXI.js. And to expose my API to scala.js, my library needs to be a global. But within my library, I want to use all the new es6 features, including import and export.<br />
<br />
So my jsconfig.json looks like this:<br />
<br />
{<br />
<pre class="prettyprint"><code> "compilerOptions": {
"target": "es6",
"module": "amd",
"rootDir": "src",
"outFile": "js/app.js"
},
"files": [
"src/define.js",
"src/lib/lib.js",
"src/lib/shapes/Circle.js",
"src/lib/utils/functions.js"
]
}
</code></pre>
<div>
<br /></div>
<div>
Typescript normalizes the interface, so no parameter checking is needed. For amd modules, the define<br />
function is less than 10 lines of code:<br />
After running tsc, the outFile js/app.js:<br />
<br /></div>
<pre class="prettyprint"><code>var define = (function (modules) {
return (name, deps, callback) => {
modules[name] = { id: name, exports: {} };
let args = [(name) => modules[name].exports, modules[name].exports];
for (let i = 2; i < deps.length; i++)
args.push(modules[deps[i]].exports);
callback.apply(modules[name].exports, args);
};
}({}));
define("lib/shapes/Circle", ["require", "exports"], function (require, exports) {
"use strict";
//------ lib.js ------
class Circle {
constructor(radius) {
this.radius = radius;
}
}
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = Circle;
});
define("lib/utils/functions", ["require", "exports"], function (require, exports) {
"use strict";
//------ lib2.js ------
exports.sqrt = Math.sqrt;
function square(x) {
return x * x;
}
exports.square = square;
function diag(x, y) {
return exports.sqrt(square(x) + square(y));
}
exports.diag = diag;
});
define("lib/lib", ["require", "exports", "lib/shapes/Circle", "lib/utils/functions"], function (require, exports, Circle_1, functions) {
"use strict";
/**
* Re-export it all to a namespace-like object hierarchy
*/
window.lib = {
shapes: {
Circle: Circle_1.default
},
utils: {
functions: functions
}
};
});
</code></pre>
<div>
<br /></div>
<div>
Code at <a href="https://github.com/darkoverlordofdata/es6-modules">https://github.com/darkoverlordofdata/es6-modules</a><br />
<br /></div>
Brucehttp://www.blogger.com/profile/12452129679810623214noreply@blogger.com3tag:blogger.com,1999:blog-5828869956262288283.post-50714557392775765732016-05-27T16:09:00.000-07:002016-05-27T16:09:55.563-07:00Using an ECS with Scala.JSI've created an implementation of Entitas ECS in Scala. The source is over on github: <a href="https://github.com/darkoverlordofdata/entitas-scala">https://github.com/darkoverlordofdata/entitas-scala</a>.<br />
<br />
I think the big drawback to using an entity component system is that it takes a lot of boilerplate to get a project up and running. So, I also have a command line tool to help me with that, entitas-cli. Entitas-cli requires nodejs, and uses Liquid templates to generate code from a json configuration file.<br />
<br />
To install entitas-cli: 'npm install -g entitas-cli'<br />
<br />
I will need an existing project, so using the tutorial at <a href="https://www.scala-js.org/tutorial/basic/">https://www.scala-js.org/tutorial/basic/</a>, I've created a basic HelloWorld application. I only followed the first three steps, and then I add my dependencies, so now my build.sbt looks like this:<br />
<div>
<br /></div>
<pre class="prettyprint"><code>scalaJSUseRhino in Global := false
enablePlugins(ScalaJSPlugin)
name := "Scala.js Tutorial"
scalaVersion := "2.11.7" // or any other Scala version >= 2.10.2
libraryDependencies += "org.scala-js" %%% "scalajs-dom" % "0.9.0"
libraryDependencies += "com.darkoverlordofdata" %%% "entitas" % "0.0.0-SNAPSHOT"
resolvers += "Artifactory" at "https://oss.jfrog.org/artifactory/oss-snapshot-local/"
libraryDependencies += "co.technius.scalajs-pixi" %%% "core" % "0.0.1-SNAPSHOT"
jsDependencies += "org.webjars" % "pixi.js" % "3.0.7" / "pixi.js"
jsDependencies += RuntimeDOM
skip in packageJSDependencies := false
persistLauncher in Compile := true
</code></pre>
<div>
<br />
I'll have to reload my sbt configuration. So while it's doing that, I open another terminal window in the project root, and type the following commands :<br />
<div>
<br /></div>
<pre class="prettyprint"><code>entitas init helloworld
entitas create -c Destroy
entitas create -c Player
entitas create -c Position x:Float y:Float
entitas create -c Velocity x:Float y:Float
entitas create -c View sprite:co.technius.scalajs.pixi.Sprite
entitas create -s Destroy IExecuteSystem
entitas create -s Physics IExecuteSystem
entitas create -s Render IInitializeSystem IExecuteSystem
</code></pre>
<div>
<br /></div>
Now I have an ./entitas.json file in my project root.</div>
<div>
<br /></div>
<pre class="prettyprint"><code>
{
"namespace": "helloworld",
"src": "lib/src",
"output": {
"javascript": "web/src/helloworld/generatedExtensions.js",
"typescript": "lib/src/generatedComponents.ts",
"declaration": "lib/ext/helloworld.d.ts"
},
...}
</code></pre>
<div>
<br />
These defaults are for a typescript project, so I make the following changes for scala:<br />
<br />
<pre class="prettyprint"><code> "namespace": "tutorial.webapp",
"src": "src/main/scala",
"output": {
"generated": "components.scala"
},
</code></pre>
<div>
<br /></div>
and generate the output:<br />
<div>
<br /></div>
<pre class="prettyprint"><code>entitas generate -p scala mutable=var</code></pre>
<div>
<br /></div>
This creates all of my components and system classes. Components are regenerated every time I run the tool. Systems are not overwritten.<br />
<br />
I also need some assets. I've downloaded Kenney's SpaceShooterRedux package from <a href="http://opengameart.org/content/space-shooter-redux">http://opengameart.org/content/space-shooter-redux</a><br />
<br />
The main TutorialApp class should load the assets and start the game loop:</div>
<div>
<br /></div>
<pre class="prettyprint"><code>package tutorial.webapp
import co.technius.scalajs.pixi.Container
import co.technius.scalajs.pixi.Pixi
import co.technius.scalajs.pixi.loaders.{ResourceDictionary, Loader}
import com.darkoverlordofdata.entitas.{Systems, Pool}
import tutorial.webapp.systems._
import org.scalajs.dom.document
import org.scalajs.dom.window
import scala.scalajs.js.JSApp
object TutorialApp extends JSApp {
lazy val width = window.innerWidth
lazy val height = window.innerHeight
lazy val renderer = Pixi.autoDetectRenderer(width, height)
lazy val stage = new Container
lazy val pool: Pool = { new Pool(Component.TotalComponents.id) }
lazy val systems: Systems = { new Systems() }
def main(): Unit = {
Pixi.loader
.add("black", "images/black.png")
.add("ship", "images/ship.png")
.load(loaded)
document.body.appendChild(renderer.view)
window.requestAnimationFrame(render)
}
lazy val loaded = (loader:Loader, res:ResourceDictionary) => {
systems
.add(pool.createSystem(new RenderSystem(pool)))
.add(pool.createSystem(new PhysicsSystem(pool)))
.add(pool.createSystem(new DestroySystem(pool)))
systems.initialize()
}
lazy val render: (Double) => Unit = { time =>
systems.execute()
window.requestAnimationFrame(render)
}
}
</code></pre>
<div>
<br />
<br />
Now I just need to fill in the systems and create entities. The full version is here<br />
<a href="https://github.com/darkoverlordofdata/invaders-scala-js">https://github.com/darkoverlordofdata/invaders-scala-js</a><br />
<br />
Try it live here, at <a href="https://darkoverlordofdata.com/invaders-scala-js">https://darkoverlordofdata.com/invaders-scala-js</a>. Be kind, it is just started.<br />
<br /></div>
<div>
<br /></div>
Brucehttp://www.blogger.com/profile/12452129679810623214noreply@blogger.com0tag:blogger.com,1999:blog-5828869956262288283.post-25908987189398030482016-05-04T09:27:00.000-07:002016-05-04T09:27:06.978-07:00You Will Test the Way We Want You to TestThat sounds like a line from Hogan's Heroes. But really it's JUinit. I can't believe the lack of alternatives in the java-sphere. Actually, this extends to Kotlin, too. I've implemented the Entitas api in Kotlin, and it needs to be tested. And all I get is JUint? Actually, there is Spek, but it requires JUnit...<br />
<br />
I suppose that would be OK if I were only calling my Kotlin code from Java. But I'm not, I'm calling from Kotlin, and JUnit can't test idomatic usage. Plus, btw - have I mentioned lately that I hate java? That's why I'm using Kotlin.<br />
<br />
So far, Kotlin's been doing a good job of insulating me from java, and I'd like to keep it that way. So I've written a unit test framework before - I can write one in Kotlin. In fact, I just did, it doesn't take long.<br />
~ here is an example of usage:<br />
<br />
<div>
<pre class="prettyprint"><code>fun main(args: Array<String>) {
var k1 = 0
var k2 = 0
var k3 = 0
TestIt("this is the test suite")
.beforeEach {
k1 += 1
}.afterEach {
k2 += 1
}.onDone {
k3 = k1 + k2
}.run {
it("this is the test") {
it.equals(1, 1)
}
it("this is another test") {
it.equals("fred", 1)
}
}
}
</code></pre>
And, here is the TestIt code, the thing about kotlin is that it's so easy and succinct. The entire framework fits in on file, and is about 80 lines of code.<br />
<div>
<br /></div>
<div>
<pre class="prettyprint"><code>
class TestIt(name:String) {
private var name = name
private var beforeProc = {}
private var afterProc = {}
private var doneProc = {}
private val tests:MutableList<test> = mutableListOf()
data class Test(val name:String, val proc:(assert) -> Unit) {}
object assert {
var result = false
var actual:Any? = null
var expected:Any? = null
fun equals(actual:Any, expected:Any):Boolean {
if (actual.equals(expected)) {
this.result = true
} else {
this.result = false
this.actual = actual
this.expected = expected
}
return this.result
}
}
fun beforeEach(proc:() -> Unit):TestIt {
beforeProc = proc
return this
}
fun afterEach(proc:() -> Unit):TestIt {
afterProc = proc
return this
}
fun onDone(proc:() -> Unit):TestIt {
doneProc = proc
return this
}
fun run(main:(func:(name:String, proc:(assert) -> Unit) -> Unit) -> Unit) {
val fail = "\u001b[31m" /* VT100 RED */
val pass = "\u001b[32m" /* VT100 GREEN */
val reset = "\u001b[0m" /* VT100 RESET */
var passed = 0
var failed = 0
main {name:String, proc:(assert) -> Unit ->
val ignore = tests.add(Test(name, proc))
}
println("\t$name\n---------------------------------")
for (test in tests) {
assert.result = true
beforeProc()
test.proc(assert)
afterProc()
if (assert.result) {
passed++
println("${pass}PASS${reset} <=> ${test.name}")
} else {
failed++
println("${fail}FAIL${reset} <=> ${test.name}")
println(" expected ${fail}[${reset}${assert.expected}${fail}]${reset}")
println(" actual ${fail}[${reset}${assert.actual}${fail}]${reset}")
}
}
doneProc()
println("---------------------------------")
println(" <====> Pass: $passed")
println(" <====> Fail: $failed\n\n")
}
}
</test></code></pre>
<br /></div>
<br /></div>
Brucehttp://www.blogger.com/profile/12452129679810623214noreply@blogger.com0tag:blogger.com,1999:blog-5828869956262288283.post-54316128500751601102016-04-20T09:30:00.000-07:002016-04-20T09:30:52.649-07:00Is Kotlin Really a Better Scala?Disclaimer - I'm not a java coder. In fact, I hate java. Maybe that's too stong. I don't prefer java. But I want to try libGDX, and that means using the jvm. I like programming with FSharp, so I'm checking out scala, which is also based on ocaml, and kotlin, a purported 'better scala'.<br />
<br />
So, to compare them, I ported a simple FSharp shmup game to both scala and kotlin. I found that on Android, the Kotlin version starts stuttering while the Scala version continues fast and steady for as long as I fire bullets. So, for the first round, Scala is the clear winner. Kotlin just does not have the raw performance.<br />
<br />
Next, I upgraded each to include using Overlap2D. This is more realistic, not to mention it's the reason I'm looking into libGDX. Here, I'm using Box2D physics to move objects, and the results are not conclusive, there is not a better performing version. So let's look at the language.<br />
<br />
Kotlin touts interop with java. But I didn't find scala to be any slouch in that area. I think their perspective must be calling Kotlin vs Scala from Java, neither of which I plan on doing.<br />
<br />
Kotlin compiles faster? Only if you don't use SBT (scala build tool).<br />
<br />
Kotlin's syntax is almost identical to Scala's.<br />
It uses the keyword 'fun' rather than 'def' to define methods.<br />
Kotlin uses 'data class' where scala calls it 'case class'<br />
Kotlin changes 'match' to 'when' and removes some functionality.<br />
Kotlin has no 'new' operator. New objects and function calls look the same.<br />
Kotlin exposes synthetic members - getWidth() and setWidth() are replace with a field reference to width.<br />
Kotlin's weak pattern matching has to be replaced with complex if statements and manual destructuring.<br />
<br />
Those may seems like change just to be different, but they actually have a negative impact on readability. New objects dont' stand out. Properties don't match the documetation. Pattern matching is spaghetti.<br />
<br />
It seems to me that the main benefit of Kotlin is the one stated by IntelliJ - it helps them sell their IDE. But it doen't help me write my code. I've decided to go with scala.<br />
<div>
<br /></div>
Brucehttp://www.blogger.com/profile/12452129679810623214noreply@blogger.com1tag:blogger.com,1999:blog-5828869956262288283.post-92073617215509653402016-03-23T10:24:00.000-07:002016-03-23T10:24:47.924-07:00Look, Ma, No Framework! (my first Kotlin project)I like the way that an entity component system (ecs) organizes my code. But I don't always want to use a big framework. Functional languages such as Kotlin can give me much of the benefits of ecs without the overhead.<br />
<br />
Let's start with components:<br />
<br />
<pre class="prettyprint"><code>data class Bounds(val radius: Float)
data class Expires(val value: Float)
data class Health(val current: Int, val maximum: Int)
data class Position(val x: Float, val y: Float)
data class Resource(val path: String)
data class Scale(val x: Float, val y:Float)
data class Size(val w: Float, val h:Float)
data class Sprite(val texture: TextureRegion)
data class Tween(val min:Float, val max:Float, val speed:Float, val repeat:Boolean, val active:Boolean)
data class Velocity(val x: Float, val y: Float)
</code></pre>
<br />
That's it. TextureRegion is defined in LibGDX, and I defined a couple of enums - EntityType and SpriteLayer (<a href="https://github.com/darkoverlordofdata/shmupwarz-libgdx-kotlin">https://github.com/darkoverlordofdata/shmupwarz-libgdx-kotlin</a>) so that we can define our entity:<br />
<br />
<br />
<br />
<br />
<pre class="prettyprint"><code>data class Entity(
val id: Int, /* Unique id */
val name: String, /* Display name */
val active: Boolean, /* In use? */
val entityType: EntityType, /* EntityType Enum */
val layer: SpriteLayer, /* Display Layer Enum
/* C O M P O N E N T S * */
val bounds: Bounds?, /* Radius */
val expires: Expires?, /* Entity expiration timer */
val health: Health?, /* Health counter */
val position: Position?, /* Screen x,y */
val resource: Resource?, /* Sprite asset */
val scale: Scale?, /* Size scale */
val size: Size?, /* Display size */
val sprite: Sprite?, /* Texture */
val tween: Tween?, /* Tweener */
val velocity: Velocity? /* Speed x,y */
)
var uniqueId: Int = 0
fun createEntity(entityType: EntityType, layer : SpriteLayer, name : String):Entity {
uniqueId += 1
return Entity(uniqueId, name, false, entityType, </code>layer, null, null, null, null, null, null, null, null, null, null)
}
</pre>
<div>
<br />
<br />
<br />
Components are initialized to null. I use a factory functions to create a full entities, such as Player:</div>
<div>
<br /></div>
<div>
<br /></div>
<pre class="prettyprint"><code>fun createPlayer(entity:Entity, width: Int, height: Int):Entity {
val name = entity.name
val path = "images/$name.png"
return entity.copy(
active = true,
bounds = Bounds(43.0f),
health = Health(100, 100),
resource = Resource(path),
position = Position(width.toFloat()/2.0f, 100.0f),
sprite = Sprite(TextureRegion(Texture(Gdx.files.internal(path)))),
velocity = Velocity(0.0f, 0.0f)
)
}
</code></pre>
<div>
<br />
<br />
Systems use pattern matching to determine which entities they act upon.</div>
<div>
<br /></div>
<div>
<br /></div>
<pre class="prettyprint"><code>fun movementSystem(entity: Entity, delta: Float): Entity =
when {
(entity.position != null
&& entity.velocity != null) -> {
val position = entity.position
val velocity = entity.velocity
val x = position.x + velocity.x * delta
val y = position.y + velocity.y * delta
entity.copy(position = Position(x, y))
}
else -> entity
}
</code></pre>
<div>
<br />
<br />
From a functional viewpoint, Kotlin's implementation of pattern matching seems a bit lame. Better destucturing would help. I should be able to say:<br />
<br />
<code>val (position, velocity) = entity</code><br />
<br />
But I can't do that either, Kotlin doesn't support adhoc destructuring. Instead I would need to use</div>
<div>
<div>
<br /></div>
<div>
<code>val (id, name, active, entityType, layer, bounds, expires, health, position, resource, scale, size, sprite, tween, velocity) = entity</code></div>
<div>
<br /></div>
<div>
Who thought that was a good idea? You can see why I'm not using it. Oh well. The thing to remember is that pattern matching does work. I think that compared to all of the good features of Kotlin, this is something I can live with, and hope that JetBrains will improve it - after all, this is only version 1.0.1!</div>
<div>
<br /></div>
<div>
Those are the pieces. How do they fit together? There is a joke-</div>
<div>
Q How many Haskell programmers does it take to change a lightbulb</div>
<div>
A None. They build a new house around the new lightbulb.</div>
<div>
<br /></div>
<div>
Well, that's what we're going to do, only in Kotlin. Notice that all of the fields of our components and entities are immutable (val). We cannot change them, only create new ones. Notice in the movement system, where the function returns the original entity or with <code>entity.copy(position=Position(x,y))</code>. <br />
<br />
First, we create an array of all our entities, active or not:</div>
</div>
<div>
<br /></div>
<pre class="prettyprint"><code>fun createLevel(): List<entity> = arrayListOf(
createEntity(EntityType.Enemy, SpriteLayer.ENEMY1, "enemy1"),
...
createEntity(EntityType.Bullet, SpriteLayer.BULLET, "bullet"),
createEntity(EntityType.Bullet, SpriteLayer.BULLET, "bullet"),
createEntity(EntityType.Bullet, SpriteLayer.BULLET, "bullet"),
...
createEntity(EntityType.Player, SpriteLayer.PLAYER, "fighter"),
createEntity(EntityType.Explosion, SpriteLayer.EXPLOSION, "explosion"),
...
)
</entity></code></pre>
<div>
<br />
<br />
Then our main update loop will create a pipeline out of our systems. This is where it all happens. Once each frame, we recalculate our game state, and then display it:<br />
<br />
<br /></div>
<pre class="prettyprint"><code>fun update(delta: Float, mainBatch: SpriteBatch) {
level = collisionSystem(
enemySpawningSystem(level, delta)
.map {inputSystem(it, delta) }
.map {entitySystem(it, delta) }
.map {movementSystem(it, delta) }
.map {tweenSystem(it, delta) }
.map {expiringSystem(it, delta) }
.map {removeOffscreenSystem(it, delta) }, delta)
level.filter { it.active }
.sortedBy { it.layer }
.map {spriteRenderSystem(it, mainBatch)}
}
</code></pre>
<div>
<br />
<br />
You might be tempted to just add your active entities as needed and remove them when you are done. I tried that. After about a minute, the game will grind to a halt due to memory fragmentation.<br />
<br />
I've uploaded the full working project in AndroidStudio to <a href="https://github.com/darkoverlordofdata/shmupwarz-libgdx-kotlin">github</a>. It should run on both desktop and android. I generated the ios version also, but I am unable to test it. </div>
Brucehttp://www.blogger.com/profile/12452129679810623214noreply@blogger.com0tag:blogger.com,1999:blog-5828869956262288283.post-42163636036051727882016-03-18T10:37:00.001-07:002016-03-18T10:37:08.318-07:00Kotlin and FSharp and Scala! Ocaml!After re-writing ShmupWars using idiomatic FSharp, I had my ML epiphany. Immutable is good. But FSharp syntax seems a bit rough, and it's hard to be original in Unity, so I'd like to find an alternative. Another strong cross platform game environment is LibGDX, and the jvm has functional languages. But I have limited experience using the jvm, and find the whole java ecosystem intimidating and confusing.<br />
<br />
<b>So, first up Scala 2.9.</b> Scala is easy to install, and there is a template for LibGDX, it's all here: <a href="http://raintomorrow.cc/post/70000607238/develop-games-in-scala-with-libgdx-getting">http://raintomorrow.cc/post/70000607238/develop-games-in-scala-with-libgdx-getting</a><br />
<br />
Both Scala and FSharp were influenced by OCAML. I can do just about the same things in Scala as in FSharp, but with a cleaner syntax. Moving from FSharp to Scala is straightforward, and in about 3 days I had a working example of <a href="https://github.com/darkoverlordofdata/shmupwarz-libgdx-scala">ShmupWars</a>. I found that sbt, the Scala Build Tool, does a good job of hiding the jvm from me, and I appreciate that. There are Atom plugins for both Scala and SBT, so I can avoid using a big bloated java ide. SBT also allows quick iterative compiles. I like to test continually while I code, and SBT keeps up with me.<br />
<br />
<b>Second, Kotlin 1.0.0.</b> Speaking of big bloated java ide's, Kotlin installs with IntelliJ Community Edition 15. I used Obviam's template <a href="http://obviam.net/index.php/libgdx-and-kotlin/">http://obviam.net/index.php/libgdx-and-kotlin/</a> to get started. I couldn't get it to compile from the ide. LibGDX includes command line build scripts, so I installed the <a href="https://kotlinlang.org/docs/tutorials/command-line.html">kotlinc command line compiler</a>. IntelliJ keeps trying to reconfigure kotlin, and when it succeeds, the compile script is then broken. So, I'm using Atom with the kotlin-language plugin. Compile iteration is slow. I probably don't fit Kotlin's demographic. They are targeting existing java progamers who would know the secret to fix this snafu. Did I mention that I hate java?<br />
<br />
Some Kotlin features I ran into:<br />
* Destructured assignment won't compile unless I list all properties. That's not very convenient if I want just 2 out of 11 properties.<br />
* Pattern matching is 2nd class. No tuples, no destructuring. It's like the Visual Basic Select statement.<br />
* Rather than use an Option wrapper, fields are marked as nullable, and then must checked for null before each use.<br />
* No native immutable linked list.<br />
<br />
In the end, Scala is a more mature ML language. Coverting ML idiom from FSharp to Scala was like falling off a log. I was almost disappointed; I thought this would be more of a challenge. I'm sure I just haven't gotten to that part yet.<br />
<br />
Kotlin, however does not have first class support for ML idiom. Nor does it promise to - Kotlin has it's own idiom. My original FSharp version uses OOP idiom, would that be a better candidate for Kotlin? I'll give it a try.<br />
<br />
<br />
<br />Brucehttp://www.blogger.com/profile/12452129679810623214noreply@blogger.com0tag:blogger.com,1999:blog-5828869956262288283.post-22345422166861132782016-03-11T09:19:00.000-08:002016-03-11T09:19:05.415-08:00Just Say No To MicrosoftI never thought I'd hear myself say that. After all, as some of you know, I worked there for almost 20 years. But they've crossed the line.<br />
<br />
Today, I woke up, and my Windows7 machine had upgraded to Windows10. No warnings. No permission. It just did it. And yes, my files are still there, but none of my dev tools work. While I love Linux, I've always tried to make sure my projects work on Microsoft products as well. No more - Microsoft has seen to that. No CygWin, no Babun, no MinGW. Even stuff made for Microsoft - Unity3d, Cocos2D - none of it is working after the upgrade to Windows 10.<br />
<br />
It would be different, if I has initiated the upgrade. If I had been prepared. If I had reserved the time to deal with it. This isn't about Open Source vs Closed Source. This is about customer service, and Microsoft obviously doesn't give 2 scraps about their customers needs and wants.<br />
<br />
I have a solution. Already had it. I'm selecting a new distro now - I've been meaning to try Fedora. Now is the time. No dual boot needed. There is nothing I need Microsoft for.<br />
<br />
I think the next computer I purchase will probably be an OS/X machine. Thank you Microsoft, for kicking me out of your nest - I can learn to fly without you!Brucehttp://www.blogger.com/profile/12452129679810623214noreply@blogger.com0tag:blogger.com,1999:blog-5828869956262288283.post-64722265101719268532016-03-08T12:21:00.001-08:002016-03-08T12:26:35.179-08:00A Functional ECSI recently changed my distro from Mint Cinnamon to ElementaryOS. My research had reached the conclusion that the issues I was having with Unity3D were due to old kernal. I'm happy to report that it's a success - I can now access the Unity Store. And with the latest 5.3.3 version, some breaking changes have been resolved. All of this allows me to get back to FSharp.<br />
<br />
And so, I've finished up my very basic port of Entitas to FSharp. While converting the demo game, ShmupWarz, I started wondering if my systems could just be functions. And why not use FSharp's built in pattern matching instead of calling a Match api? Could I juse express my ECS directly in FSharp?<br />
<br />
So, for example, I could write the movement system like this:<br />
<br />
<pre class="prettyprint"><code>let MovementSystem (delta:float32) entity =
match entity.Velocity, entity.Position with
| Some(velocity), Some(position) ->
let x = position.X + velocity.X * delta
let y = position.Y + velocity.Y * delta
{ entity with Position = Vector2(float32 x, float32 y)}
| _ -> entity
</code></pre>
<div>
<br /></div>
<div>
Where the oop version looks like this:</div>
<div>
<br /></div>
<pre class="prettyprint"><code>type MovementSystem(world:World) =
let group = world.GetGroup(Matcher.AllOf(Matcher.Position, Matcher.Velocity))
interface IExecuteSystem with
member this.Execute() =
let delta = Time.deltaTime/100.0f
for e in (group.GetEntities()) do
e.position.x <- e.position.x + (e.velocity.x * delta)
e.position.y <- e.position.y + (e.velocity.y * delta)
e.position.z <- e.position.z + (e.velocity.z * delta)
</code></pre>
<div>
<br /></div>
<div>
While reading this post <a href="https://bruinbrown.wordpress.com/2013/10/06/making-a-platformer-in-f-with-monogame/">https://bruinbrown.wordpress.com/2013/10/06/making-a-platformer-in-f-with-monogame/</a> I noticed that the author was using a pattern very similar to en ECS. So I played with it a bit, tweaked the naming convention, and got it working.<br />
<br />
I went ahead and created a full game for a poc. You can see it at <a href="https://github.com/darkoverlordofdata/mono-fsharp-shmupwarz">https://github.com/darkoverlordofdata/mono-fsharp-shmupwarz</a><br />
<br /></div>
<div>
Performance seems just as good, although I'm comparing MonoGame to Unity3D. So my next step is to try to integrate this technique with Unity.</div>
Brucehttp://www.blogger.com/profile/12452129679810623214noreply@blogger.com0tag:blogger.com,1999:blog-5828869956262288283.post-50597529196159789682016-02-24T11:44:00.001-08:002016-02-24T11:44:18.563-08:00You Ain't Seen Nothing Like the Mighty NimNot if you are used to class based oop. Instead, Nim is type based and uses multi-methods. This takes some getting used to. So after a couple of weeks, what are my impressions?<br />
<br />
My last attempt at creating a native game engine using Vala was disappointing - great language, slow run time. I actually considered Nim prior to trying Vala, but I was put off by the 'partial style insensitivity' - this means that 'setValue', 'set_value', and 'setvalue' all refer to the same identifier. I don't see any good reasons for that, just another way to get bugs. Between this and the original name <a href="http://www.urbandictionary.com/define.php?term=nimrod">Nimrod</a> I was convinced that it was done to prevent wide spread acceptance and keep Nim as a hobby language.<br />
<br />
But this isn't a rant. I can live with 'partial insensitivity', and the name was shortened. Nim has a pragmatic style. Nim doesn't have classes, so I don't end up with a complex class hierarchy - this is a good thing. I can use inheritance where it is needed, and composition is easy. With multi methods, I can define a 'class' in more than one file - this is handy if I want to extend an existing class like you can in CSharp. Compared to languages like Java which provide a 'place for everything, everything in it's place', Nim gives you a lot more freedom in organizing your code and files. And definitely requires less boilerplate. Of course, since there is not much structure, you'll need to provide your own.<br />
<br />
After 2 weeks of coding, my proof of concept is running on both Linux and Windows7. Not only that, the performance is better than I anticipated, even exciting. I've done no performance tuning. My entity object uses an array for components, but all other arrays are just sequences, tables and queues - all plain Nim dynamic structures. When I play my test demo, ShmupWarz, I can shoot bullets continuously for minutes, blasting enemy ships, and only once did I notice my frame rate drop below 60 fps.<br />
<br />
I'm sold. I'm continuing on with my project, using Nim<br />
<div>
<br /></div>
Brucehttp://www.blogger.com/profile/12452129679810623214noreply@blogger.com0tag:blogger.com,1999:blog-5828869956262288283.post-15332252691405694632016-02-09T10:01:00.000-08:002016-12-11T21:42:52.757-08:00Six Weeks with ValaUpdate: <a href="https://blog.darkoverlordofdata.com/2016/12/vala-revisited.html">https://blog.darkoverlordofdata.com/2016/12/vala-revisited.html</a><br />
<br />
One concept discussed in functional progamming is 'Reasonablness', which focuses alot on how side effects make it hard to predict what your code is actually doing. In case you're not familiar, here is a great post on the topic <a href="http://fsharpforfunandprofit.com/posts/is-your-language-unreasonable/">http://fsharpforfunandprofit.com/posts/is-your-language-unreasonable/</a><br />
<br />
One thing I like about that post is that the author points out that by their nature, we cannot expect much of this 'reasonableness' from your typical oop language. But I think Vala fares worse on than most.<br />
<br />
Part of it is the ecosystem - it's hard to reasom without information. Documentation is sparse, conflicting, or just missing. Granted that all technology products have this issue to some degree, but it's particularily bad in the case of Vala. I can't get the Gnome toolset working because I'm not using a gnome desktop. If this were Microsoft or Oracle, we'd call it vendor lockin. I'll give Gnome the benefit of doubt and chalk it up to tunnel-vision or not-invented-here-syndrome. But the result is that I am using Atom and command line make, and scratching my head alot while I seach the web for clues.<br />
<br />
But that can be fixed. The real issue I belive is the dependancy on GObject. Remember, GObject was created to compete with Microsoft COM. COM was the object system that backed VB6. It was also the cause of much of VB6 unreasonable behavior. DotNET was created to replace COM. Microsoft wanted a 'pure' object system that would met the requirements of any language. Vala follows the VB6 model of shoe horning the langage to fit the existing object system. And this leaks through the abstracton and results in arbitrary constraints on the language. I continually get compilation errors - things like interfaces and properties sometimes don't compile until I base the class on GObject, resulting in other side effects, requiring more than one ground up redesign. And I still find myself surprised by the results, and not in a good way.<br />
<br />
So, what was I actually able to accomplish in those six weeks of vala? First, I discovered Genie, Vala's whitespaces language. This is a great alternative to Vala's curly braces, and I credit it with speeding up the process. It seems to be designed to provide intelligent defaults, and the overall effect is much less typing, and an easy to read grammer. It is missing a couple of features present in Vala - namely lambda's and multidimemsional arrays - though I can declare them in Vala and then comsume them from Geanie. I will miss Geanie.<br />
<br />
So, after six weeks, I have a prototype shmup game using SLD2 and Bosco.ECS (My ecs inspred by <a href="https://github.com/sschmid/Entitas-CSharp">Entitas</a>). It's a little dissapointing. Performance is not better than Unity. And with Unity, 6 weeks later I had a full game enviromment, with menu, scores, leaderboard, running on Windows, Linux and Android. I still can't get a Vala game to compile on or for Windows 7. Nor have I yet addressed sound or a UI. In case you're interested in Vala, my project is <a href="https://github.com/darkoverlordofdata/shmupwarz-vala">https://github.com/darkoverlordofdata/shmupwarz-vala</a><br />
<br />
I really like Vala and wanted it to work, but its mostly frustrating. And I found that I Genie, the 'other' language compiled by valac, is vastly underrated. Genie could be the next big thing, if Gnome lets it. But I'm moving on to something more fruitful.<br />
<br />
<br />Brucehttp://www.blogger.com/profile/12452129679810623214noreply@blogger.com4tag:blogger.com,1999:blog-5828869956262288283.post-42036655102601280112016-01-29T08:27:00.000-08:002016-01-29T08:27:39.049-08:00Avoiding Unsafe Code in ValaCSharp uses the 'unsafe' keyword to mark sections of code that ignore type safety. Vala doesn't have this, but if it did, if would apply to <a href="https://wiki.gnome.org/Projects/Vala/Tutorial#Variable-Length_Argument_Lists">variable length argument lists</a>.<br />
<br />
What's wrong with variable length arguments? The tutorial shows a great use case:<br />
<pre class="prettyprint"><code>
actor.animate (AnimationMode.EASE_OUT_BOUNCE, 3000, x: 100.0, y: 200.0, rotation_angle_z: 500.0, opacity: 0);
</code></pre>
<br />
Coming from a scripting world, this looks like a friendly idiom. In fact, this example has a bug that causes unpredictable results. See that last parameter 'opacity: 0'? That '0' should be a '0.0', because the receiving method:<br />
<pre class="prettyprint"><code>
double val = l.arg();<span style="font-family: "times new roman";"><span style="white-space: normal;">
</span></span></code></pre>
<br />
is requesting a double. Now the stack is out of alignment. If you are lucky, your program will crash with a segmentation fault. Lucky? Yes, because any other result is unpredictable. In my case, the values of all 4 variables became changed to 0, and the program continued running. But the other part of the example seemed to work correctly:<br />
<br />
<pre class="prettyprint"><code>actor.animate (AnimationMode.EASE_OUT_BOUNCE, 3000, "x", 100.0, "y", 200.0, "rotation-angle-z", 500.0, "opacity", 0);
</code></pre>
<br />
This was giving me the correct results. So I assumed that the problem was with the alternate syntax, which uses a colon. Then I swapped the two, expecting the error to move with it. But it didn't. Now the alternate syntax was working. That should have been my first clue that there was a memory corruption. Instead, seeing that I was using an older version of Vala libraries, I upgraded to the newest. And the problem went away. I thought I'd fixed it. But it wasn't fixed.<br />
<br />
I was wrong. Later the next day, it started doing it again. Sorry stackoverflow, you were right. It's been a long time since I've coded using c.<br />
<br />
That's when I noticed the '0'. I changed that to '0.0' and it started working. This is how a memory bug presents in C - it wants you to pull your hair out. My advice - don't use variable length argument lists. This 'wolf in sheeps clothing' masquerades as a friendly looking idiom but it's not.Brucehttp://www.blogger.com/profile/12452129679810623214noreply@blogger.com0tag:blogger.com,1999:blog-5828869956262288283.post-16708399041665563722016-01-27T08:59:00.000-08:002016-01-27T08:59:05.718-08:00What's up with Vala?The vala landscape is strewn with abandonware. The Gnomite wiki has more dead links than a Gnecrominicon. <a href="https://mail.gnome.org/archives/vala-list/2008-April/msg00002.html">Vala 1.0</a> , the next version afer 0.4 never materialized, and the roadmap this link refers to is now itself just another dead link.<br />
<br />
But something is happening - Geary is built with Vala, as is the ElementaryOS desktop that I currently love. Version 0.30 was release last fall (still no version 1.0). So there must be something to this. Right?<br />
<br />
Maybe - if there were some viable tooling. I spent about a week trying to get various dev tools from Gnome to work. Only 1 would actually install and run - Valama - and it is very unfinished. There is always Geany, but that is so last millenia.<br />
<br />
So I've decided that it's best for me to ignore all of that Gnomite stuff. I'm starting over using Atom. I've installed the language-vala plugin. I'm using my own simple make script, and run it using atom-buil plugin. I modified autocomplete-clang to include vala - <a href="https://github.com/darkoverlordofdata/autocomplete-vala">(You're welcome to try it, but I'll warn you that it, too, is unfinished. But then, the bar is pretty low :))</a> - And I'm just now starting to get productive.<br />
<br />
Now I'm trying to find a unit test that actually works. Honestly - is there any other language whose ecosystem is in such shabby state? It is said that there are 2 kinds of computer languages. The ones that everyone complains about, and the ones that no one uses. Maybe there just haven't been enough complaints about Vala.<br />
<br />Brucehttp://www.blogger.com/profile/12452129679810623214noreply@blogger.com2tag:blogger.com,1999:blog-5828869956262288283.post-63043889294120186612016-01-20T09:46:00.000-08:002016-01-20T11:18:00.728-08:00Order Out Of Chaos - Finding My Desktop in Elementary OS / FreyaI'm becoming a fan of the Elementary design aesthetic. At first I fought it. I replaced Plank with Docky, only to realize that this added no functionality, just distractions. So I've gone back to the minimalistic, focused desktop that Freya delivers.<br />
<br />
In the end, I have only 1 thing I need to change - I need to be able to put files on my desktop. Some 3rd party software will bork without this - try to 'Add to Desktop' in Chrome or create a desktop shortcut in any IntelliJ IDE.<br />
<br />
So, to start with, I just created a ~/Desktop folder. This solves the issues with applications that expect a Desktop folder. But it's still not convenient. I found this excellent article <a href="https://elementaryforums.com/index.php?threads/enable-desktop-icons-and-right-click-in-elementaryos-freya.198/">https://elementaryforums.com/index.php?threads/enable-desktop-icons-and-right-click-in-elementaryos-freya.198/</a> which gives me back my standard desktop.<br />
<br />
But now I have a new problem. When I click on my Home icon, is opens in nautilis, not the native pantheon-files. I end up using 2 different file managers at the same time, and this is the road back to the typical Linux chaos that I'm trying to avoid.<br />
<br />
So, first, lets go back into dconf-editor and roll back one change. Under org->gnome->nautilis->desktop and set the home-icon-visible, network-icon-visible, and trash-icon-visible properties off.<br />
<br />
Next, open scratch, and enter:<br />
<br />
<br />
<pre class="prettyprint"><code>#!/usr/bin/env xdg-open
[Desktop Entry]
Version=1.0
Terminal=false
Type=Application
Name=Bruce
Exec=pantheon-files /home/bruce
Icon=/usr/share/icons/elementary/places/64/user-home.svg
</code></pre>
<br />
Instead of 'bruce', use your own account name. Save it as ~/Desktop/Home.desktop<br />
Make it executable: <br />
<br />
<pre class="prettyprint"><code>$ chmod +x ~/Desktop/Home.desktop
</code></pre>
<br />
Now we have our own custom Home icon. When we click on it, it will open our home folder in the native file manager. We have restored our working desktop and minimized the chaos.<br />
<div>
<br /></div>
Brucehttp://www.blogger.com/profile/12452129679810623214noreply@blogger.com4tag:blogger.com,1999:blog-5828869956262288283.post-1574551989010850422016-01-19T10:35:00.001-08:002016-01-19T10:35:39.962-08:00Using Gmail Inbox Tabs in GearyI'm one of those odd people that likes the Gmail inbox tabs. I don't even customize them, they work just great for me out of the box. Mainly, I just don't like to think about my email. Which is why I'm liking Geary. But it doesn't see my Gmail tabs. Actually, any client will have this problem, not just Geary. Gmail doesn't export the property. But there is a way around this by using filters.<br />
<br />
I'm not going to show you how to create filters - Google has better help than I can give you - just search for 'gmail filters' <a href="https://support.google.com/mail/answer/3055016?hl=en">https://support.google.com/mail/answer/3055016?hl=en</a>.<br />
<br />
So, a filter is basically a saved search, and we can set some rules. By selecting the tab as our search criteria, we can create a filter based on a tab. To create a label for the Forums tab, I set these options:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-pWjNVk2qLJo/Vp6AervzAYI/AAAAAAAAAnA/PDR1Tjefbu0/s1600/Screenshot%2Bfrom%2B2016-01-19%2B09%253A46%253A41.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="212" src="http://4.bp.blogspot.com/-pWjNVk2qLJo/Vp6AervzAYI/AAAAAAAAAnA/PDR1Tjefbu0/s320/Screenshot%2Bfrom%2B2016-01-19%2B09%253A46%253A41.png" width="320" /></a></div>
<br />
<br />
WARNING: This is destructive. When this is working, your tabs will always be empty. But you'll need to leave them active for this to continue working. So Gmail won't look as pretty, cause you'll always have those empty tabs sitting there.<br />
<br />
Do the same for each tab. When you are done, and you click on the tab, it will now be empty. The contents will be auto archived and labeled with the same name as the tab. And now, you can view them as Labels in Geary.<br />
<br />
<br />Brucehttp://www.blogger.com/profile/12452129679810623214noreply@blogger.com11tag:blogger.com,1999:blog-5828869956262288283.post-27129415156963669482016-01-10T09:54:00.000-08:002016-01-10T10:32:11.144-08:00Using Coffee Script for Gnome Desktop ScriptingThe Cinnamon desktop uses javascript for scripting applets and desklets. Specifially, it uses an older version of spidermonkey. I'm not sure which, but it includes only 2 ES6 features - let and const. No other new, more useful ES6 features seem to work. This is troubling, since the semantics for let and const have changed - only slightly, but enough to break some plugins.<br />
<br />
So basically, desktop scripting in Gnome, and therefore Cinnamon, is stuck with a deprecated version of javascript. Since most of my javascript is for the browser, I don't really want to learn how to use it the wrong way. But we know a fix for this - Coffee Script!<br />
<br />
<pre class="prettyprint"><code>Applet = imports.ui.applet
GLib = imports.gi.GLib
Util = imports.misc.util
Gettext = imports.gettext.domain('cinnamon-applets')
_ = Gettext.gettext
class MyApplet
__proto__: base = Applet.IconApplet.prototype
name: 'Gracie'
constructor:(orientation)->
base._init.call(this, orientation);
try
@set_applet_icon_name("gnome-info")
@set_applet_tooltip(_("Say Hello, #{@name}"))
return
catch e
global.logError(e)
return
on_applet_clicked:(evtdata) =>
notification = "notify-send \"Hello #{@name}\" -a TEST -t 10 -u low"
Util.spawnCommandLine(notification)
return
main = (metadata, orientation)-> new MyApplet(orientation)
</code></pre>
<div>
<br /></div>
<div>
Note there is now no need for Lang.Class and Lang.Bind. Insted of coffee's extend, I've set the __proto__ property. You can still use extends for your own class hierarchy, but for a GObject based hierarchy, you'll need to use __proto__.<br />
<div>
</div>
<br />
Compile with the bare flag:<br />
<br />
<pre class="prettyprint"><code>$ coffee -bc applet.coffee
</code></pre>
<br />
And breath some new life into that stale interface!</div>
Brucehttp://www.blogger.com/profile/12452129679810623214noreply@blogger.com0tag:blogger.com,1999:blog-5828869956262288283.post-91755935670525804382015-12-23T10:04:00.000-08:002015-12-23T10:04:29.986-08:00Unit Testing FSharp for Unity3DI'm going to try using FSharp in Unity, and I want to unit test my code before I drop my compiled dll into Unity's Asset folder. Testing is one thing that MonoDevelop is pretty good at. After installing mono-develop, I installed NUnit:<br />
<br />
sudo apt-get install monodevelop-nunit.<br />
<br />
You can also install it from MonoDevelop via the menu: <i>Tools->Add-in Manager</i>.<br />
<br />
So in the project view, I right click on my Solution Items, and select <i>Add->New Project...</i><br />
I don't see any templates for FSharp Unit Testing, so I'll do this from scratch. I create a FSharp Library Project, and name it Test. For Unity compatability, we need to change the taget, so select <i>Project -> Test Options -> Build -> General</i> and change the target framework to Mono/.NET 3.5.<br />
<br />
Next, I install NUnit. Right click on the new project, Test, and select <i>Add Nuget Packages</i>. I'll look for and install NUnit. And here I have a problem. NuGet won't install the correct version for my target (3.5), but it will tell me that it installed the wrong one... and that's why I don't use NuGet.<br />
<br />
So instead, I visit <a href="http://nunit.org/?p=download">http://nunit.org/?p=download</a>, and grab the Previous Release: NUnit 2.6.4. I unzip it to my ~/Applications folder, and then reference the dll in my project: In the project view, right click on References and select <i>Edit References...</i> From here I select the <i>.Net Assemblies</i> tab, and browse for ~/Applications/NUnit-2.6.4/bin/nunit.framework.dll \<br />
<br />
Now I'm ready to write tests, so I create a simple class:<br />
<br />
<div>
<pre class="prettyprint"><code>open System
open NUnit.Framework
open Entitas
[<TestFixture>]
type Tests() =
let world = new World(64)
[<Test>]//1st entity - no components
member this.Test001() =
let e1 = world.CreateEntity("Playerz")
Assert.AreEqual(1, e1.Id)
</code></pre>
</div>
<div>
<br />
Save my work, right click on my Test project, and select <i>Run Item</i> to run my tests. I can also reference Unity data types by referencing the UnityEngine.dll:<br />
<br /></div>
<div>
Right click on References and select <i>Edit References...</i> From here I select the .Net Asseblies tab, and browse (on my system) for /opt/Unity/Editor/Data/Managed/UnityEngine.dll<br />
<br />
Now, I add </div>
<div>
<br /></div>
<pre class="prettyprint"><code>open UnityEngine
...
[<Test>]//2nd test - one conponent
member this.Test002() =
let e2 = world.CreateEntity("Playery")
e2.AddComponent(1, new Vector3(1,0f, 1.0f, 1.0f))
...
</code></pre>
<div>
When I'm satisfied that my basic functionality is working, I move the dll into my Unity projects Asset folder. I do this by selecting my game project (not the testing project) in the project view, go to <i>Project -> Project Options.</i> Select the <i>Build->Output</i> and browse to my Unity project Asset folder. I create a new folder - Assets/Libraries, and select it. Now when I build my game project, the dll is generated directly into my Unity project. I can switch to the Unity Editor, and click on Play to see my code at work.</div>
Brucehttp://www.blogger.com/profile/12452129679810623214noreply@blogger.com1