Monday, February 27, 2017

Sorting out Gjs with Typescript

I get why Gnome wants to use javascript. I love the language. The thing is, I don't love Gnome's implementation.

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.

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

https://www.npmjs.com/package/gir2dts

All I have to do is install with npm, and reference the contained *.d.ts files.

There are a couple of samples in the example folder at https://github.com/darkoverlordofdata/gir2dts

This tool was designed to facillitate the development of another application, so it's a great example of a Gjs/Typescript application: https://github.com/darkoverlordofdata/bosco-player

Wednesday, February 22, 2017

Just Don't Write Ambigous Code

I'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?

Sure. But why write ambigous code? Unless you are competing to write the longest one line program, there is no point.

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'.

Actually, like nost best practices, the real best practice is don't blindly follow the best practice, instead you should think.

There are actually some places I still use a semicolon. For loops for one. And switches:


switch(op) {
 case 0: doZero(); break
 case 1: doOne(); break
...

And of course, if maintaining existing code where the style guide calls for semicolons, please respect it.

Here is an actually informative posting on the subject: http://mislav.net/2010/05/semicolons/

Tuesday, February 14, 2017

Gtk 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.

So, CoffeeScript it is, and the first thing that goes is

const Lang = imports.lang;

This is what CoffeeScript replaces. Now we have a real 1st class class statement.

So here is my port of Gnome's HelloWorld example,


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)

The important thing to note, is that we no longer use Lang.bind:


this.application.connect('activate', Lang.bind(this, this._onActivate));

Instead, the function definition is bound using the fat arrow:


    _onActivate: () =>


The other thing I ran into is shebang support. Coffeescript treats it as a coment and discards it.
So I follow up my compile with a simple fix replacing the coffescript header with shebang.


coffee -c test.coffee
sed -i "s/\/\/ Generated by CoffeeScript 1.11.1/\#\!\/usr\/bin\/env gjs/" test.js





Sunday, January 29, 2017

Using OOC in VisualStudio Code

Is that Fernando the Wonder Llama in the Object Oriented C logo?

You can use yo code to import a textmate bundle. The vscode website has a simple tutorial. https://code.visualstudio.com/Docs/customization/colorizer
Or you can download the one I've just imported:

$ cd ~/.vscode/extensions
$ git clone [email protected]:darkoverlordofdata/vscode-ooc.git

You'll also need to configure launch and build tasks. Put the following launch.json & task.json files in the project .vscode folder.
I'm assuming a simple case, where project, folder and executable share the same name:

project/project.use
project/source/project.ooc

Install the vscode LLDB plugin to debug c programs. I'm used to using ctrl-b to build, F5 to debug.

launch.json

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Debug",
            "type": "lldb",
            "request": "launch",
            "cwd": "${workspaceRoot}",
            "program": "${workspaceRoot}/${workspaceRootFolderName}",
            "args": []
        }
    ]
}

Building ooc is pretty simple. But I ran into a problem with the SDL2 examples, it was unable to find sdl *.h files.
Oh, they are there - both Vala and Nim programs compile just fine.
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:

tasks.json

{
    "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"]
        }
    ]
}

Now I am able to run the SDL2 demo's for ooc using VSCode!