I finally took the plunge and decided to really give the RTL a makeover. I was supposed to wait until Smart v1.1 with this, but releasing a product only to alter the RTL radically later would be unfair to our customers. Better to put in place a foundation that wont break the codebase later and that we can build on. So for the past 5 days I have edited every single method and class in the RTL’s foundation. But for what you say? Why fix what already works?
An example of just how much extra juice we managed to squeeze out of the browser with this rewrite, can be demonstrated by the “plasma” graphics demo we posted earlier (donated by a tester). Under the older RTL it rendered 120.000 pixels (manually plotted into the HTML5 graphics context via R,G,B,A) at roughly 4 frames per second on an iPhone 4S. That is extremely slow (but considering the amount of calls involved, im surprised we got 4 frames at all). After I ejected the use of tagRef and re-wrote parts of the w3graphics.pas unit, I now get 11 frames per second. Please remember that this extremely fast for a scripting engine, being able to draw 120.000 * 4 bytes eleven times a second. On my iMac it runs at a decent 80 FPS, which is even more impressive.
And this is just for starters. To keep the RTL backwards compatible I have retained the functions in w3system.pas (things like w3_setStyle, w3_setAttrib and so on), which means there are actually thousands of calls being made that are now redundant. It will take a lot of energy to get rid of them by Monday – but when I decide on something I never quit until it’s done.
Following up on Delphi’s introduction of record functions, I have stripped the older functions for making and working with TRect, TRectF, TPoint and TPointF – and instead placed them directly in the record itself. This is much more uniform and leaves little doubt where a function should be (so new users dont have to wonder what unit function X resides in). Here is the interface for TRect as of writing. More and more functions will be added, but this is the “bare bones” i guess:
TRect = Record
function Clip(Const RectToClip:TRect):TRect;
function Compare(Const aRect:TRect):Boolean;
function ContainsRow(Const aRow:Integer):Boolean;
function ContainsCol(Const aCol:Integer):Boolean;
function ContainsRect(Const aRect:TRect):Boolean;
function ContainsPos(Const aLeft,aTop:Integer):Boolean;
function ContainsPoint(Const apoint:TPoint):Boolean;
function Intersect(Const aRect:TRect;var intersection:TRect):Boolean;
function Expose(const aChildRect:TRect):TExposure;
function Make(Const aLeft,aTop,aWidth,aHeight:Integer):TRect;overload;
function Make(Const aWidth,aHeight:Integer):TRect;overload;
function MakeAbs(Const aLeft,aTop,aRight,aBottom:Integer):TRect;
The first version of Smart Mobile is designed exclusively for webkit, which means Safari mobile (iPad, iPod, iPhone), Android and equivalent desktop browsers. So little or no effort has gone into making Smart apps run on Opera or FireFox. But with some tweaks I now have a Sprite3d App running under FireFox as well 🙂
The bootstrap code (the section of code that initializes and starts your application) has been altered to include a browser check. So now it checks what system you are running and cache’s known style-prefixes and other information. The magic function that will make all the difference is called “w3_CSSPrefix”. This will help make your CSS calls “universal”. So where you would previously have written:
You can now make it run on all browsers by changing it to:
Hardware accelerated animations and events are a bit crappy on FireFox at the moment (in terms of commonalities), for instance their “animation end” event don’t fire as it’s supposed to, and it also deviates from the naming convention used elsewhere. So mozAnimationEnd wont do. I’ll have to come up with a solution for that. But full FireFox support wont happen until later. But you can prepare your app for universal support by using the w3_cssPrefix function.
The only way to fully maximize the potential of all platforms is to create a common ground, but one that is rich enough to cater for a browser’s unique features. As such, I have decided to create a driver system to solve the browser compatibility problems once and for all. This is currently being prototyped but should make it into Smart v1.5 probably. In short you have a basic class with functions for getting the correct style names (and more) for the current browser. The driver will also contain functions to examine device capabilities (is camera supported, is database supported, is orientation supported, touch, sound formats, image formats — the whole multimedia spectrum). When your app starts, the browser will be recognized – and the appropriate driver created. The RTL will then reference the driver to get the correct properties to set.
As a bonus, anyone can write a new driver should a different browser appear on the marked. And should there be changes, you simply update the driver rather than every n’th class or method in the RTL.