Developing desktop solutions with Lua
Lua Workshop 2006
Ashwin Hirschi
www.reflexis.com
Introduction
- Ashwin Hirschi
-
- contact: ashwin@reflexis.com
- Reflexis B.V.
-
- company founded 1999
- software development & consultancy
- small-to-medium-to-large-sized customers
- actively using Lua since 2002
Purpose of this talk
Promote Lua-driven "platforms"
by showing some possibilities of
the Reflexis Lite runtime.
Problem? What problem?
Assume you can solve your client's problem
with a few well-placed lines of Lua code.
Now...
Problem? What problem? (2)
- How are you going to deploy your "solution"?
- » Users won't accept a cmdline tool with some scripts
- » Web-based solutions are not always desirable
- How do you create a friendly user experience?
- Will you write a new host app for each solution?
- Does every user's desktop need an install?
- How will you distribute updates?
Reflexis Lite Features
- compact, Lua-driven, Windows platform
- many useful libraries
- open-ended GUI system
- convenient multi-threading
- integrated profiler
- practical deployment
no debugger, though... we never really felt the need
Libraries
- sockets (luasocket)
- database (xtx/xdb or sqlite)
- XML (pieces)
- regex (pcre)
- buffering
- compression (zlib/zip)
Obviously, this list can vary, depending on needs
Special buffer lib is used to efficiently create large strings.
Note everything's statically linked, to ease deployment.
Graphical User Interface
- soft/scripted message handling
- renders using GDI, "cycle-based" object collection
- open DIY widgets ("areas") approach
- double-buffered, for flicker-free rendering
- some highlights:
auto-sizing elements,
virtual (and hybrid!) listboxes,
adaptive font selection & sizing,
schemes
- typical implementation sizes:
statusbar <2k, button 5k, (multi-)text 7k, navbar 9k, listview 16k
Discuss widget rendering/behaving vs standard OS controls?
Graphical User Interface (2)
- "actions" ease mapping of handlers to events
- form definitions based on Lua syntax
- table-based, automatic layouting
- consistent support for: context-menus, tab order, help requests
- booklets (GUI applets) orchestrate front-end handling
- the "scratchpad" booklet acts as console for vanilla Lua scripts
Graphical User Interface (3)
- limitations (by design!): only 1 window, no menu bar
- implementation shortcuts: edit boxes, menus, file dialogs
- missing pieces: handling of viewports, bitmaps, multi-level menus
Regardless...
experiment:
If you can imagine it, you can probably build it
Multi-threading: Boxes
A Lite box consists of:
- a Lua state
- two threads: controller + worker
- a thread-safe message queue
- a name (used as ID)
Multi-threading: Boxes (2)
- Boxes are created and destroyed from the main state only:
- » openbox, loadbox, execbox, closebox, hasbox
- But anyone can send messages to boxes:
- » sendbox
- Messaging is a-synchronous (mostly)
Multi-threading: Boxes (3)
- controller vs worker threads:
- » master – slave, i.e. controller starts worker
- » high – low priority, i.e. controller can/will interrupt worker
- workers can help dealing with "blocking" situations
- threads are suspended/resumed (not created/destroyed)
- dual-threading is optional
Deployment
- typical install = 1 executable + 1 application file (= EXE + ARK)
- the executable is small: typically 200-250 Kb (UPX-compressed)
- auto-configuring: runs from anywhere
- libraries are statically linked
- no external dependencies
- supports Win95 through WinXP
- runs comfortably on old hardware
Deployment (2)
The application file is a zip-archive or (sqlite) database with:
- library scripts, e.g. UI system, DB utilities, Internet protocols
- application scripts
- application "booklets" (GUI-specific logic)
- GUI data, like form definitions, colour schemes
- other application-specific data
- boot script (optional license key file etc.)
Profiler
- fully integrated (i.e. embedded in runtime)
- uses high-frequency performance counters for accurate timings
- a single "profiler" function allows full control:
- » on, off, fetch, state, reset
- can be activated on-demand, e.g. for specific code sections
- timing results can be extracted using callback
Changes
- a home-grown "require" implementation
- » can also support "alternatives", like zip-or-db based setups
- a "compile" primitive
- » based on luac code, to drive in-house tooling etc.
- John Belmonte's weak references patch
- » mainly used for publish-subscribe system
- Fixes & adjustments to LuaSocket
Advantages
- fast, incremental development cycles
- same tooling for initial prototype and final product
- systems are easy to develop/debug/fix (alerts)
- products can evolve, don't build what you don't need (right now)
- new developers are always quickly up to speed
Advantages (2)
- same language across different configurations:
- » clients & servers, desktop & web, products & tools, etc.
- » code re-use saves time and increases quality
- extremely light-weight tooling:
- » no need for high-end dev machines
- » no licensing fuss, etc.
- » overall... much cheaper!
Advantages (3)
- extremely stable runtime, in production use for 4 years
- very responsive UI, also on low-end machines
- much richer user experience than browsers
- easy installs: simply copy to machine or run off shared drive
- updates consist of single files (ARKs)
Disadvantages
I can only think of one issue that really bugs me:
- Lua 4 - Lua 5(.1) breakage
- » table traversal changes break 80% of code base (Yay? NOT!)
Lessons learned
- It pays off to implement as much as possible in Lua:
- » more forgiving & flexible, so easier to evolve/extend/tweak
- » much faster to develop, so more time to focus on product!
- We succeeded because we created a Lua-driven platform!
- Last but not least, Lua is seriously high quality software!
The End?
Any questions?
Comments?
ashwin@reflexis.com