Vexi PlatformVexi Platform
vexi: easy, extensible, flexible

Thursday, September 20, 2007

Debugging Vexi Applications I

Most scripting languages are very hard to debug, especially as the code becomes complex and the variety of files and structures interacting with eachother becomes somewhat hard to have mapped in the mind.

Fortunately VexiScript has kept some neat features from Java and some features of it's own that make debugging complex Vexi applications fairly easy! For instance, a full stack trace with line numbers always accompanies an exception.

Of course, it may be that you don't want to stop executing code to get an idea of where your code is up to. In VexiScript, we can also throw and more importantly catch exceptions, much like in Java - but in VexiScript these exceptions are really easy to handle - just pass them to a vexi.log function and it will handle the rest.

if (myval != correctval) {
    try { throw "incorrect myval: "+myval; }
    catch(e) { vexi.log.info(e); } // that's it!
}
// and the script continues uninterrupted

It is as easy as that. ;-)

Friday, July 27, 2007

Understanding Event Processing

Understanding how events are propogated throughout the box model can enable you to pull off a lot of neat tricks when implementing more complicated widgets and user interfaces. This basic template is an interactive demonstration. Add extra traps (blocking and non-blocking) to understand exactly how traps and events work together.

<vexi xmlns:ui="vexi://ui">
    <ui:box tag="outer">
        vexi.ui.frame = thisbox;
        <ui:box id="innerbox" tag="inner" />
        
        var showTag = function(v) {
            vexi.log.info(trapee.tag+": "+trapname);
            cascade = v;
        };
        
        $innerbox.Press1 ++= showTag;
        $innerbox.KeyPressed ++= showTag;
        thisbox.Press1 ++= showTag;
        thisbox.KeyPressed ++= showTag;
        $innerbox._Press1 ++= showTag;
        $innerbox._KeyPressed ++= showTag;
        thisbox._Press1 ++= showTag;
        thisbox._KeyPressed ++= showTag;
        
    </ui:box>
</vexi>

Friday, July 20, 2007

Fortress

Fortress is a castle building game written in Vexi which is in the early prototyping stages. The game is isometric so a full isometric display engine is being built in Vexi. This showcases the flexibility of Vexi as well as pushing it's performance, and may lead to a number of new features for Vexi as a platform.

Wednesday, July 11, 2007

Changing Themes

I just made a change to the surface widget that makes theming really really easy should you want a custom widget theme.

<vexi xmlns:ui="vexi://ui" xmlns="vexi.widget">
    <ui:box theme=".path.to.custom.theme" />
    <surface />
    <ui:box>
        // your app starts here
        vexi.ui.frame = thisbox;
    </ui:box>
</vexi>

If you omit the box declaring your theme, vexi.widget.surface will apply a default theme for you. Nice and simple and no hardcoding - and it even opens the door for individual themes per surface with some more clever updates to vexi.widget.surface and the core.

For the curious, the way vexi.widget.surface automatically handles the theming is rather straightforward. If the theme attribute is defined, it applies to as a trap to the namespace vexi.theme, if not it just applies a default theme to that namespace:

// no theme has been specified by the user
if (thisbox.theme == null)
    theme = vexi..org.vexi.theme.win2k;
// set up the theme
vexi..vexi.theme ++= theme;
// apply the theme surface template
vexi..vexi.theme.surface(thisbox);

Fairly easy, eh? The downside is that you must apply vexi.widget.surface for theming to work but the reality is that few (if any) of the widgets will work without it being applied to the root boxes of your applications.

Sunday, July 08, 2007

The Children Trap

New to Vexi3 is the Children property. It replaces the previous notion of ChildAdded and ChildRemoved events, which were rather weak. Now we can completely control how boxes enter and leave as children of a box or template by placing read and write traps on it's Children property. As ever, an example is the best way to show off how this works.

Let's create a basic grid widget. Grids were removed from the core in Vexi2, so this is a useful example - although simplified - of how they are being replaced.

First the basic template structure:

<vexi xmlns:ui="vexi://ui">
    <ui:box>
        <ui:box id="grid" orient="vertical" />
        
        // JS to go here
        
    </ui:box/>
</vexi>

We have to have an inner box - $grid - because we are adding/removing containing rows so this keeps that logic simple, that is we do not have to consider rows in our Children write and read traps. Also $grid has a vertical orient because it is more common to work in rows before columns.

Let's start with the Children write trap which is fired every time thisbox[index] is put to:

thisbox.Children ++= function(v) {
    var i = arguments.trapname;
    var c = i%numcols;
    var r = vexi.math.floor(i/numcols);
    if (i+1 > total) total = i+1;
    while (r > $grid.numchildren - 1)
        $grid[$grid.numchildren] = vexi.box;
    var row = $grid[r];
    while (numcols > row.numchildren - 1) {
        var b = vexi.box;
        b.layout = "absolute";
        row[row.numchildren] = b;
    }
    // remove previous occupant
    if ($grid[r][c][0])
        $grid[r][c][0] = null;
    if (v) $grid[r][c][0] = v;
    return;
}

A few things to notice from the above code:

  • The index is passed as arguments.trapname
  • The child (or null if we are removing a child) is passed as the argument to the function
  • We return at the end because we have already handled the child placement and do not want the core to place the child in the box on which we are trapping
  • This handles non-null puts to an index with existing child in a different way than the core - the core inserts the new child, whereas this example overwrites the old child with the new one
  • We are using absolute layout for the cells here to keep the example simple - if we use a packed layout then the columns are not guarranteed to line up if the content size of any cell is significant

So, now we are handling the destination of child boxes of this template, we want to be able to also control how children are accessed as well. So we place a read trap on the Children property:

thisbox.Children ++= function() {
    var i = arguments.trapname;
    var c = i%numcols;
    var r = vexi.math.floor(i/numcols);
    // if the $grid[r] exists so does $grid[r][c]
    if ($grid[r]) return $grid[r][c][0];
    // otherwise we are out of grid bounds
    return null;
}

Simple enough, eh?

Saturday, July 07, 2007

Vexi Blog Revival

There are too many cool Vexi developments to keep this thing closed, so it's coming back. I'm going to be blocking about all the cool things going on around Vexi and lots of cool tricks you can do in it. Look out for more posts in the near future on vexi.blogspot.com! :-D

Thursday, March 08, 2007

Vexi website migrates to Wordpress

The Vexi website has been migrated to Wordpress. That kinda removes the need for this blog which I will leave purely for archival purposes or in case I want to post things that don't belong on the Vexi website but are related to Vexi.

Go there: http://vexi.sourceforge.net/

Thursday, January 04, 2007

Vexi2 in Full Flow

It's going well. Mike and I are just smoothing over any remaining rough edges. Documentation and demos are online although a bit more sparse than is desirable. Now it's just a case of convincing people to use it.

Anyway check out the Sourceforge website which is holding everything at the moment:

http://sourceforge.net/projects/vexi

Get The Vexi Platform at SourceForge.net. Fast, secure and Free Open Source software downloads Sponsored by WEBenableIT Java Network Member