ScreenWeaver HX

Screenweaver HX is the best way to write Haxe Desktop Applications.

With SWHX, you create an application by using two layers :

  • the System layer : written in Haxe and using the Neko API, you can access the local filesystem, databases, network sockets... You can also easily extend its capabilities by writing your own DLL.
  • the Flash layer : written in Haxe or any other technology capable of producing SWF, you can use this layer to display the graphical interface, handle user interactions, play sound and video...

You can communicate synchronously between theses two layers by using Haxe Remoting, as we will explain in the tutorial.

These two layers are both crossplatform and all you need is the SWHX Boot executable that is initializating the application. For additional information on SWHX's inner workings, refer to the screenweaver.org pages.

Install

In order to install SWHX, you need to download and install Haxe (v.1.08 or better). After installing Haxe, run the following command :

haxelib install swhx

This will download and install latest SWHX version for your system.

Samples are located at (swhx path)/samples. Included is an SWHX application (Sampler) for browsing and building the samples. To start the Sampler, issue the following command:

haxelib run swhx

Running an SWHX application is done by running the main .n file with the NekoVM, or by using the SWHX binary executable boot-loader. The latter is located at (swhx path)/tools.

To discover the SWHX install path, you can simply run the following command :

haxelib path swhx

Sources are available on the SWHX SVN Repository.

Known issues


OS-X users, please note that the swhx.app boot loader at
/usr/local/lib/haxe/lib/swhx/1,0,x/tools
does not have executable rights set, unless you have run the Sampler application. Either run the Sampler application: $ haxelib run swhx or issue $ chmod -R 755 swhx.app to correct this.


Temporary Mac OSX getting running instructions
Mac temporary instructions on getting running on OSX


The Flash debug player is not working on Windows at current time.

Tutorial

First let's create a small System Layer using Haxe/Neko :

// App.hx
class App {
    static function main() {
        // initialize ScreenWeaver HX
        swhx.Application.init();
        // create a 400x300 window with title "My Application"
        var window = new swhx.Window("My Application",400,300);
        // create an incoming communication Server
        var context = new haxe.remoting.Context();
        // create a flash object inside this window 
        var flash = new swhx.Flash(window,context);
        // set the HTML attributes of this flash object
        flash.setAttribute("src","ui.swf");
        // activate the Flash object
        flash.start();
        // display the window
        window.visible = true;
        // enter the system event loop (will exit when window is closed)
        swhx.Application.loop();
        // cleanup SWHX properly
        swhx.Application.cleanup();
    }
}

As you can see, it's very easy. You can create several windows but each window can only have one Flash object. You can controll all the Flash attributes as you would do when writing HTML by using the setAttribute method.

Then here's the Flash Layer (also written in Haxe) :

// Flash.hx
class Flash {
    static function main() {
        // draw a red rectangular shape
        var mc = flash.Lib.current;
        mc.moveTo(10,10);
        mc.beginFill(0xFF0000,100);
        mc.lineTo(100,10);
        mc.lineTo(100,100);
        mc.lineTo(10,100);
        mc.endFill();
    }
}

Let's compile these two layers by using a single HXML file :

-main App
-neko app.n
-lib swhx

--next
-main Flash
-swf ui.swf
-swf-header 400:300:20:EEEEFF
-lib swhx

This will create two files: app.n for the System Layer and ui.swf for the Flash Layer. Put the SWHX boot executable (see Install section) in your project directory and run it.

You should now see a window opened with a clear blue background and a red square draw on it. Bravo ! You completed your first Haxe Desktop Application.

Communication

Now that your first sample works, let's call some method between the Flash and System Layer.
Add the following method to both .hx files :

   static function test( a : Int, b : Int ) {
       return a + b;
   }

Then in App.hx, add the following before creating the Flash object :

   // give direct access to our class statics from Flash
   context.addObject("App",App);

and in App.hx, once the SWF is initialized we can perform some call :

flash.onConnected = function() {
   // connect to flash
   var cnx = swhx.Connection.flashConnect(flash);
   // call Flash.test(5,7)
   var r : Int = cnx.Flash.test.call([5,7]);
   // display result
   systools.Dialogs.message("Result","The result is "+r,false);
}

And in Flash.hx, add the following :

    // connect to System
    var cnx = swhx.Connection.desktopConnect();
    // call App.test(5,7)
    var r : Int = cnx.App.test.call([5,7]);
    // display result
    trace("Result = "+r);

Compile again and run the application. You should get a MessageBox from the system layer and a trace on the Flash Screen. You now have two-side communications working.

Flash Player Download

If it's the first time you are starting the application, you should notice a small lag. This is because when the Flash Firefox Plugin is not found in the current directory, the call to swhx.Plugin.update() will retreive it from Internet first, and save it into the file flashplayer.bin.

This way you don't have to redistribute the Flash Player as part of your application. If the plugin is already in the directory, the application will start immediately.

If you know that the player is already installed somewhere, you can pass the complete path to the dll/bundle containing the flash player when calling swhx.Application.init instead of null.

SWHX For ActionScript

Asynchronous communications

The SWHX Distribution contains a sample on how you can use SWHX directly from an ActionScript program with the FSCommand function. You just get these calls as events in the System Layer and you can implement them to perform System operations.

// test.as
// save the text "Hello World!" in "test.txt"
fscommand("save_file","test.txt:Hello World!");

And on the System side :

static function handleFSCommand( cmd : String, params : String ) {
    switch( cmd ) {
    // save a file on the local drive
    case "save_file":
    var p = params.split(":");
    var file = p.shift();
    var f = neko.io.File.write(file,false);
    f.writeString(p.join(":"));
    f.close();
    default:
    throw ("Unknown fscommand: "+cmd);
    }
    return null;
}

and install the callback on your Flash object in your main() function:

flash.onFSCommand = handleFSCommand;

Synchronous communications

If you require more elaborate and synchronous communications, you can use the SWHX Flash API. It is located at <haxelib path swhx>/api/actionscript/AS2 in the SVN source tree. A sample demonstrating its use is at <haxelib path swhx>/samples/6-flash-api. Below are two snippets from the sample, illustrating the front-end and back-end sides:

import swhx.*
// Initialize the Screenweaver HX binding.
// the 'this' argument specifies the base object swhx
// will use on trying to resolve external calls from
// the Haxe back-end.
swhx.Api.init(this);

// Prepare a function that is to be called by our
// back-end:
function hello(x: Number, y: Number) {
    var result = "hello "+ (x + y);
    ...
    return result;
}

// Invoke a method on object 'obj' that lives in our Haxe back-end:
swhx.Api.call("obj.hello",10,20);

And at the back-end side:

class App {

    static function hello( x : Int, y : Int ) {
        return "hello "+(x+y);
    }

    static function main() {
        swhx.Application.init();
        var window = new swhx.Window("My Application",400,300);
        var context = new haxe.remoting.Context();
        context.addObject("obj",App);
        var flash = new swhx.Flash(window,context);
        flash.setAttribute("src","ui.swf");
        flash.onConnected = callTest;
        flash.start();
        window.visible = true;
        swhx.Application.loop();
        swhx.Application.cleanup();
    }

    static function callTest() {
        // call on the function "hello" in Flash:
        var cnx = swhx.Connection.flashConnect(flash);
        trace("hello(4,5) = "+cnx.hello.call([4,5]));
    }

}

If your front-end is in ActionScript 3 (i.e. you're using Flash 9 Alpha or Flex 2) then you should use the AS3 version of the API, which is at <haxelib path swhx>/api/actionscript/AS3.
Refer to <haxelib path swhx>/samples/9-flash-api-as3 for a sample.

More Samples

If you download the SHWX Distribution, you will have more samples available in the samples directory. They will demonstrate how to communicate between the System and the Flash layer, and how to handle events.

Some live projects are already using SWHX, here's a sort list:

How do I ... ?

To see all the current capacities of the SWHX System layer, you can browse the neko package classes from the Haxe API.

Application Distribution

Once your application is compiled, you have a app.n and one or several .swf files plus all the XML or other data files needed by your application. To these files, you need to add the following :

  • the SWHX executable boot (SWHX.exe on Windows,SWHX.app on Mac) that will be needed by people to run your application
  • the SWHX DLL (swhx.ndll on all platforms) that contains the functionalities needed by ScreenWeaver HX.
  • the Neko DLL (neko.dll + gc.dll on Windows, libneko.dynlib on OSX, libneko.so on Linux) that contains the Neko Virtual Machine
  • Neko DLLs (.ndll) required by Screenweaver HX: std.ndll and regexpr.ndll
  • any additionals Neko DLL that you need, depending on the APIs you are using (mysql.ndll for Mysql database, etc.).
  • last, Screenweaver HX needs the Flash player Firefox/Netscape plugin to run. If you don't or can't distribute it with you project, Screenweaver will try to download it automatically upon first application launch.
  • Unless you disable automatic plugin download, you need to distribute "zlib.ndll" as well.
  • .ndll files need to in the working folder of your application, or should be in a folder that's on the system's search path.

More info on the subject is at:
http://screenweaver.org/doku.php?id=tutorials:distribution

Total Size = 430 KB on Windows

Even for a commercial application, you can freely redistribute all theses files since they are covered by the LGPL license.

version #8934, modified 2010-08-02 20:03:35 by JLM