New event syntax in OpenLaszlo

April 10th, 2006

If you follow OpenLaszlo news closely, you may have noticed that a new event syntax is available in OpenLaszlo 3.2 which makes specifying and handing your own events more straightforward. I think the folks at Laszlo Systems made a smart move in adopting the new syntax as it is more intuitive, and will reduce confusion for new developers.

Curiously, the only documentation I found describing the new syntax was in this feature proposal, and in the nightly builds of the reference guide and the developers guide. Somehow the new syntax is missing from the shipping 3.2 docs.

In a nutshell the syntax is:

  • <event name="onMyEvent"/> - Declare an event
  • <handler name="onMyEvent">
    //some code here to handle event
    </handler>
  • onMyEvent.sendEvent() - notify event listeners that the event fired

Kudos to the OpenLaszlo folks for continuing to evolve the language.

OpenLaszlo developer meeting

March 17th, 2006

Clint and I presented Gliffy at the OpenLaszlo meetup last night. I wrote up a quick summary over on the Gliffy Blog.

Let’s spend some money on life instead of death

March 1st, 2006

Let’s pretend you just got elected as president of the USA and it’s budget time. As president, you have to decide how to spend money in the most effective way possible. There are a lot of factors that go into deciding what to spend your money on such as effect on the economy, constituent priorities, etc. In this case, let’s focus on a fundamental aspect of what government should be doing: protecting the people it serves.

Given the following evidence (please don’t click on the links until you read through the whole post):
1) Almost 700,000 people die from this each year
2) Over 500,000 people die from this each year
3) 90,000 people die a year because of this
4) 40,000 people die a year because of this
5) 2752 people died from this in 2001

You’ve got $200 Billion to spend. Where do you spend it? On the stuff that’s causing the most death, right?

This is, of course, a bit of a trick question. The causes of death are as follows: (ok, you can click on the links now)

1) 700,000 - Heart Disease
2) 500,000 - Cancer
3) 90,000 - Death from resistant germs
4) 40,000 - Car accidents
5) 2752 - September 11th terror attacks

I may be a peace-nik from San Francisco, but it just seems wacky to me that we’ll be spending close to $400 Billion dollars in Iraq in the name of fighting terrorism when the reality is that WAY more people are dying from car accidents, Heart Disease, Cancer, etc. For comparrison, The CDC (where money is spent to research/fight health issues like heart disease) had a budget of less than $10 Billion in 2005.

Maybe we need a reality check on our nation’s priorities?

Example of published Gliffy diagram

February 24th, 2006

Clint has been working his butt off on Gliffy while I’ve been doing some consulting work to pay the bills. One of the nifty features in the new version of Gliffy is the publishing feature. Here is a sample (click to enlarge):

If I make a change to this flow chart using the Gliffy diagram editor, the change will instantly be reflected in this blog posting with no additional effort.

Tips for using lazy & resize replication in OpenLaszlo

February 16th, 2006

Here’s the scenario: I want to display 500 items in a scrolling list, but using regular replication causes 500 views to become instantiated, which can take a loooong time. Lazy & resize replication helps out by only instantiating the views that the users can see. Lazy replication then manages copying the relevant data to views that scroll into the clipped area. The dev guide explains the purpose quite well:

“The lazy replication manager creates only enough replicated views necessary to display the data, so there is not a view for each data node. This enables the display of very large datasets.”

This is great because instantiating views is expensive, and we don’t want to make any more of them than we need to. This efficiency gain comes with a price of added complexity however. Here are some tips to hopefully make your experience with lazy & resize replication a little less painful:

  • $path references don’t reliably update in lazily replicated views. Don’t waste your time using them. Use applyData() instead (more on applyData below)
  • Make sure all visual elements that might change in your replicated view are based on the data. Instead of using attributes in the view to keep track of visual information, use attributes in the dataset instead (eg this.datapath.setNodeAttribue(’someKey’,’someValue’). You’ll probably want to use applyData() as a hook into making visual adjustments as needed.
  • applyData() is called in a replicated view whenever the data in that view changes. With lazily replicated views, applyData() is called on replicated views as the user scrolls so that data can be copied into the new LzView that just scrolled into the clipped area. Make sure that the datapath specified on the replicated view points to data that will definitely be there…. otherwise applyData() wont get fired.
  • As a workaround to the $path problem, grab any data that you need from the dataset when applyData() is fired. (e.g. this.datapath.getNodeAttribute(’somedata’))
  • Make sure to use the dataselectionmanager if you want the user to be able to select more than a single replicated item at a time.
  • A replication manager only gets created if the datapath matches multiple nodes the first time. If there is any chance at all that you’ll match a single node, you should first set the datapath to point to a fake dataset that contains 2 or more nodes to ensure a replication manager will be created. (See the example code below)
  • You can use the fake dataset trick described above to instantiate some views upon applciation startup. This will ensure that a user doesn’t have to wait for those views to be instantiated when the real data comes in.
  • If you updated something in the dataset, and your change isn’t being reflected in the replicated views, you can try calling this.cloneManager.runXPath() from a replicated view as a last resort.

Here’s some example code that covers most of what I’ve talked about above:

<canvas>

    <!-- Let's say this is my real dataset.  It could be
         loaded from the server, but we'll make it local
         for this example -->
    <dataset name="people">
        <people>
            <person name="chrisk" sex="m"/>
            <person name="lyla" sex="f"/>
            <person name="clint" sex="m"/>
            <person name="renais" sex="f"/>
            <person name="ron" sex="m"/>
            <person name="terry" sex="f"/>
            <person name="debi" sex="f"/>
            <person name="luke" sex="m"/>
            <person name="jason" sex="m"/>
            <person name="eileen" sex="f"/>
            <person name="henry" sex="m"/>
            <person name="nik nik" sex="f"/>
            <person name="kel" sex="m"/>
            <person name="hu?" sex="f"/>
        </people>
    </dataset>

    <button text="Replcte views!">
        <method event="onclick">
            replicatedParent.datapath.setXPath('people:/people');
        </method>
    </button>

    <view width="100" height="100" clip="true">
        <!-- use this dataset to ensure a
             replciation manager is created, and also
             create some views on applciation startup
             so that the user doesn't have to
             wait when they request the data  -->
        <dataset name="fakeData">
            <people>
                <person/> <person/> <person/> <person/> <person/> <person/>
            </people>
        </dataset>

        <view id="replicatedParent"
              datapath="local:parent.fakeData:/pepople">
            <text>
                <datapath xpath="person/@name"
                          replication="lazy"/>

                    <!-- Is called when a user scrolls the data into view -->
                    <method name="applyData" args="_d">
                        super.applyData(_d); 

                        if( this.datapath.getNodeAttribute('sex') == 'm' ) {
                            this.setBGColor(0xCACAFF);
                        } else {
                            this.setBGColor(0xFFCACA);
                        }
                    </method>
            </text>
        </view>
        <scrollbar/>
    </view>
    <simplelayout axis="y"/>
</canvas>

Gliffy Screenshot posted

January 27th, 2006

Clint posted a screen shot of our upcoming beta release of Gliffy. It’s looking really great!


Gliffy Beta

My Top Laszlo Performance Tips

January 15th, 2006

A customer recently asked if I had a list of Laszlo coding, performance, & style tips. I didn’t, so I thought I’d start by creating a list of performance tips. Anyway, here’s my list (in no particular order)

  • When using constraints, use $once{} as often as possible - Constraints are a great time saver, but they come at a cost. Normal constraints have to have their events registered when the application starts up, so if you have a lot of constraints, this can slow things down. If you don’t need the constraint to update after application startup, use $once{} for an incremental performance improvement.
  • Use short variable names - I believe this was more of an issue with older versions of the Flash player, so I’m not sure how relevant this is, but it is my understanding that because of the nature of Javascript, long variable names actually have a negative performance impact. If you look at any of the Laszlo run time source code, you’ll see most of the variable names are VERY short, to the point that it makes the code hard to read.
  • Use pooling and lazy replication for replicated views as often as possible - Take advantage of the hard work Adam put into making these features work. Pooling reuses previously replicated views, improving the rendering time when a datapath is updated. Lazy replication only replicates the visible views, hence saving lots of time in the event you have a scrolling list of say hundreds of replicated nodes. You’ll likely need to tweak your code to get these two features to work, but the performance gain you get is totally worth it.
  • Minimize the number of views used - Views are expensive to instantiate, so do what you can to minimize the number of views generated. Focus on classes that are constructed often via replication or other means. For example, in our diagram editor every shape contains ‘connection points’ which are represented by little ‘+’ symbols. Originally, we created the ‘+’ with two views (one horizontal, and one vertical). By using a single asset for the ‘+’ symbol, we cut the number of constructed views down substantially for each shape, yielding faster diagram load times.
  • Load images at run-time - If you don’t need to display an image right away, consider loading the image at run time to reduce the initial application download size.
  • Delay instantiation - Delay instantiation on any views that wont be shown right away to improve start-up performance. For example pop up windows, drop down menus, etc.
  • Use local variables when possible - I think this is another issue that is less important with the newer Flash players, but probably worth looking into. Apparently accessing global variables can be slow, so you’re better off creating a local reference to the global variable if you are going to access it a bunch in a loop.
  • Using Debug.write() can slow things down even when the debugger is off - If you want to be fancy, you could do something like if( $debug) Debug.write(’some message’); The compiler is smart enough to remove the $debug statements kind of like a pre-processor.

Did I miss anything? Feel free to clue me in, and I’ll add to the list here.

Help us find Jerry Tang

December 1st, 2005

Jerry Tang Missing Pic

Jerry Tang, a good friend and co-worker, has been missing since Tuesday. Jerry last spoke to his wife Tuesday morning as he left his Cole Valley home to go for a walk. He may have been seen near Fell/Stanyan at the entrance to Golden Gate Park on Wednesday morning. Jerry is 6′1″, about 160 pounds, and is believed to be wearing a dark blue jacket and blue jeans, and may possibly have a light blue umbrella.

For more information, please visit this link

Gliffy Beta Begins

November 17th, 2005

The Gliffy closed beta has begun. We’ll slowly add more user to the beta in the next several weeks/months. Browse on over to http://www.gliffy.com and you can see our new home on the web. In fact, as of today, we are no longer Silver Tie Software, but Gliffy, Inc. Our first application is a diagram editor. Imagine Visio deployed over the web, with instant collaboration features. Interested in joining the beta? Send an email to info@gliffy.com.

A lot of hard work from many people helped to make this happen. A short list:

  • Clint Dickson - Founder - Director of Engineering
  • Lyla Warren - Founder - Creative Director
  • Dana Yobst - Early involvement with Biz Dev and more
  • Andrew D. Toebben and Gundersen Dettmer - Legal
  • Henry Lyne - Helped us build out soon to be defunct http://www.silvertie.com
  • Jason Lee - Helped talk through technical and strategic issues
  • Dennis Yang - Provided us valuable insight early on
  • Jo Ann Promponsatorn - Accounting advice
  • Mom & Dad - I might need a loan from you soon!
  • …and everyone else who listened to me talk non-stop about what we’re doing, providing feedback, etc.

GCDB

November 12th, 2005

My friend Chris Brooks built this nifty little mash-up of google maps and a database of game companies.