Fuse 0.9.4 is out!
Highlights
- Introducing UX properties to make it easier to create components in pure UX (trust us, you’ll love this)
- Several improvements to the layout and animation system
- Easier to load HTML in a
WebView - New
WhileWindowSizetrigger (do things when the window dimensions change) - Improved and extended
DebugActionfor easier… well, debugging - Android videos now work way better with backgrounding and other apps playing audio
- Lots of improvements to Uno, especially the C++ backend
Introducing ux:Property
The UX-compiler has been improved with a new feature that allows parameterization of ux:Classes. This is done by exposing values as settable properties on the generated class with the ux:Property syntax. This makes it easier to create more powerful reusable components.
Here is a quick example:
<App Theme="Basic" >
<Panel ux:Class="MyButton" ux:Name="self">
<string ux:Property="Text" ux:Value="MyButton" />
<float4 ux:Property="CornerRadius" ux:Value="0" />
<float4 ux:Property="BackgroundColor" ux:Value="#f00" />
<float4 ux:Property="TextColor" ux:Value="#000" />
<Text Alignment="Center" TextColor="{Property self.TextColor}" Value="{Property self.Text}"/>
<Rectangle Layer="Background" CornerRadius="{Property self.CornerRadius}">
<SolidColor Color="{Property self.BackgroundColor}"/>
</Rectangle>
</Panel>
<MyButton CornerRadius="20" Text="MyText" TextColor="#fff"
BackgroundColor="#5C6BC0 " Width="200" Height="50"/>
</App>
In many cases where you would previously use resource- or data-binding as a way of passing data to a ux:Class, you can now use ux:Property to design a nice interface for your components.
New triggers
- Added
WhileWindowSizetrigger that lets you gate on window dimensions (in points). This element supportsGreaterThan,LessThanandEqualTo, all taking a two component vector (float2). E.g.<WhileWindowSize GreaterThan="640,480" LessThan="1280,720"> - Added
OnKeyPresstrigger taking a Key value - Added
OnBackButtonOnKeyPress extension withBackButtonpreset to capture Android back button event
Changes to layout
-
StackPanelandStackLayoutnow handle oversized content differently. It has aContentAlignmentparameter which decides how to align that content, and defaults to match the alignment of the panel itself. (Only alignment in same direction as the orientation of the panel is supported).This means the alignment of some old code could change if the content was too big for the containing panel. The old behaviour was equivalent to
ContentAlignment="Top"orContentAlignment="Left"(depending onOrientation).The new defaults are considered the more correct behaviour and this is considered a bug fix.
-
GridandGridLayouthave the same change asStackLayout, though it supports all non-default alignments forContentAlignment. -
The
Layoutconstructor and several of its functions are now internal. They were not intended to be public before as it is an internal mechanism. The high-level layout specification remains as-is (all UX code remains unaffected). -
removed unused
DrawCountfacility -
LimitBoxSizingDatahas been removed. The propertiesLimitWidthandLimitHeightcan now be placed directly on the element. Units use the usual syntax:<Panel LimitWidth="100%"/>
Extended WebView API
-
Added
SourceandBaseUrlattributes for loading html source via databinding in the context of a base url (use depends on platform though both android and ios webkit views use the same concept). -
Added
LoadHtmlAction for telling a webview to load html source from a string and a baseurl. -
Added
HTMLnode for WebView letting you cdata inline html as such:<WebView> <HTML> <![CDATA[ <h1>Hello world</h1> ]]> </HTML> </WebView>
UX debugging features
-
DebugActionno longer outputs time and frame by default in addition to its Message. -
DebugActioncan contain certain debug nodes. For now these areDebugProperty,DebugTimeandDebugFrame -
DebugTimeoutputs the current application time -
DebugFrameoutputs the current total frame count -
DebugPropertytakes aTagstring identifier and aValueproperty string (likeChangeandSet) and prints that current value prefixed with the Tag - A
DebugActionwithout aMessageonly prints its child debug nodes if any.
Introducing unstyled TextEdit class
-
TextEditis introduced as an unstyled text input type. Most things (ex. triggers) that accepted aTextInputbefore now accept aTextEdit. -
TextInputis now derived fromTextEdit - The namespace
Fuse.Controls.TextEditis renamedFuse.Controls.FallbackTextEditto avoid collision and be clearer as to its purpose
Improved animation system
- The setter
HierarchicalNavigation.ReuseExistingNodenow correctly uses the provided value (previously it just assigned false) - Some parts of the animation system have been marked internal; they were incorrectly marked as public before. They cannot be supported in the manner they were exposed. It’s unlikely to impact any user code.
-
TriggerAnimation.GetTotalDurationrenamedTriggerAnimation.GetAnimatorsDurationto avoid conflict/confusion with what it does and a new time scaling feature -
Cyclegains theWaveformoption. Of particular interest isSawtoothwhich animates in one direction in a linear fashion -
Transformnow has an internal constructor. User classes are not supported as it’s important internally to have a controlled list. -
INavigation.ActivePageadded to return the currently active page. This fixes some issues using DirectionNavigation and PageBinding. -
LayoutChangedhas been removed, leaving onlyPlaced. It also does not contain any previous world information, as it was not possible to derive in a consistent fashion. An interested listener must usePreplacementinstead, but generally this is all part of an internal mechanism that should not be used in user code.
Introducing FuseJS/Environment API
You can now do require("FuseJS/Environment") in JavaScript to get access to platform conditionals.
Lots of C++ improvements
The C++ code generator has more or less been rewritten for this release, and the underlying C++ APIs has been cleaned up along with it. This doesn’t affect regular Uno code or UX markup, but may affect handwritten code using the C++ APIs directly.
However, this rewrite wasn’t just for fun; it also gives us some cool new (advanced) features!
-
Partial reflection support in Uno.Type
Almost 30 new members are introduced in Uno.Type, modelled after System.Type in .NET. This enables runtime generic type support.
-
Runtime parameterization and reflection of generic classes and methods
This gives 100% code sharing between generic parameterizations, reducing the amount of C++ code generated by 30-40% (default Fuse project,
--no-strip, MSVC12)Creation of new type parameterizations at run time will also make the
fuse previewmore robust, as it no longer relies on having parameterizations available at compile-time. This is what have been causing occational “type not found” errors when attempting to animate certain properties.The new C++ APIs powering this are found in the Uno/ObjectModel.h header.
-
General dynamic invoke
Any Uno method can be invoked by function pointer using a single C++ function:
void uInvoke(const void _func, void*_ args, size_t count). To make this possible we’ve changed the calling convention when using function pointers. All function pointers must return void while any parameters and return value is passed by pointer. This allowed us to remove a lot of C++ template clutter, enabling faster compilation and better code. -
Less call stack clutter
Previously nearly all method calls resulted in two entries in the call stack because of wrapping. Now there’s just one entry for common method calls, when not being invoked using a delegate or interface. This should help make the call stacks less deep and easier to navigate. Many generated methods also get cleaner C++ names (
Object::New()vs.Object**New()**).
*** Various runtime performance improvements
Most compiler generated runtime hash look ups have been eliminated. This fixes serious performance problems in some cases, for example in code where string constants are used heavily. In addition, virtual method table look up are now _O(log n)_ instead of _O(n)_, and the `is` and `as` operators have been optimized.
*** **
Use array initializers in generated code
**
**Emit array initializers, e.g. `uArray::Init<int>(Int`**`typeof(), 2, 0, 1)`, instead of unrolling the expression and setting all the elements individually. This makes the generated C++ code smaller and easier to read.
-
Type initializers
Implement runtime support for type initializers, instead of generating code using a compiler transform. This enables support for static generic fields, and generates somewhat cleaner and better behaving code. Static constructors are invoked lazily and are called before accessing a static member on the declaring type, or instantiation an object of the type.
-
Less Xcode warnings are produced when building for iOS and OS X
-
Uno is now aware of keywords and other reserved words in the target language, and will rename identifiers as necessary to avoid conflicts.
C++ API changes
-
Most notably, the following methods were changed in Uno/ObjectModel.h:
| New method | Old method | |----------------------------------------|----------------------------------------| | uArray::New(arrayType, length, [data]) | uNewArray(elementType, length, [data]) | | uString::Ansi(cstr, [length]) | uNewStringAnsi(cstr, [length]) | | uString::Utf8(cstr, [length]) | uNewStringUtf8(cstr, [length]) | | uString::Const(cstr) | uGetStringConst(cstr) | | uAllocCStr(string) | uStringToCStr(string) |
Note that
uArray::New()now expectsarrayTypedirectly rather thanelementType, for better cache usage.And these methods in Uno/Memory.h:
| New method | Old method | |----------------------------------------|----------------------------------------| | uRetain(object) | uRetainObject(object) | | uRelease(object) | uReleaseObject(object) | | uAutoRelease(object) | uAutoReleaseObject(object) |
-
Some fields were given better names. For example,
uArray::_len->_length. -
Xli.h, the all including header, was removed. Include a more specific header instead. For example Xli/Mutex.h. Just ask in #uno on our slack community if you need help.
Test runner improvements
- Added timers, printing how many microseconds (μs) spent running each test, in addition to total time spent building and testing.
- Less verbose output. Only warnings (if any) and STDERR are printed from the build log. Use
-vif you need more output. - Tests are now run in alphabetical order
Smaller installer footprint and stuff™
Platform specific binaries (Xli, V8, FMOD, …) used by Uno packages are no longer included in the installer, but downloaded on demand if needed during build. This enables us to remove some large and not-always-needed binary files from the installer, making the download ~30MB smaller on each platform. This also introduces uno stuff, a simple built-in package manager.
Uno tooling improvements
-
Fix launching Xcode simulator on iPhone 6. Previously only older generations worked
-
Integrated uno doctor, test, perf-test and perf-cmp commands
uno doctorreplaces StdLibBuilder. Use whenever the package library needs updating. In addition, the--libsswitch can be used onuno buildto update on demand. The redundantunotestandperformancetestcommands were removed – useuno testanduno perf-testinstead. -
Append to path arrays in .unoconfig
Personal/project specific .unoconfig files can now append additional paths using
$(LastPathArray). For example:PackageSearchPaths: [ $(LastPathArray) "MyPackages/.build" ] PackageBuildPaths: [ $(LastPathArray) "MyPackages" ] -
The build log now produces minimal output by default. Add
-v,-vvor-vvvwhen using theunocommand if you need more output. -
uno --versionwill now present the correct version. Kinda important we think.
UXL changes
-
Array macros
- Create arrays using
@{ELEMENT_TYPE:Array([ELEMENTS, ...])}or@{ELEMENT_TYPE[]:New(SIZE)} - Access elements using
@{ARRAY:Get(INDEX)}and@{ARRAY:Set(INDEX, VALUE)}
- Create arrays using
-
Renamed C++ specific elements and properties
The old names will generate a warning when used. Just replace with the new name for silence.
| New name | Old name | |---------------------------------|-------------------------------| | TypeName | InstanceTypeName | | FileExtension | Source.FileExtension | | SourceFile | Build.SourceFile | | HeaderFile | Build.HeaderFile | | PreprocessorDefinition | Build.PreprocessorDefinition | | LinkLibrary | Build.LinkLibrary | | LinkDirectory | Build.LinkDirectory | | IncludeDirectory | Build.IncludeDirectory | | Xcode.Framework | iOS.Build.Framework | | Xcode.PrefixHeader.Declaration | iOS.PrefixHeader.Declaration | | AssemblyReference | Assembly |
-
Renamed CIL specific properties
The old names will generate a warning when used. Just replace with the new name for silence.
| New name | Old name |
|---------------------------------|-------------------------------|
| AssemblyReference | Assembly |
-
Preprocessor improvement
#if..#endifdirectives will expand to comments containing the disabled code instead of blank lines, when false.
Other fixes
- Setting
Text.TextWrapping=NoWrapwith Native theme will no longer lead to text-wrapping on iOS - Add iOS.BundleVersion project property to set plist property
CFBundleVersionon iOS - Sending Android apps to the background will now pause/resume any playing Videos.
- Playing a video on Android while other music is playing on the device will now acquire audio focus and stop other audio.
- Fixed the
Contextvs.NavigationContextproperty naming inconsistency. TheNavigationContextproperty should now be used on target navigation triggers (WhileCanGoBackandWhileCanGoForward). - Bitwise operators now have correct return type. This affects the following types: byte, sbyte, short and ushort.
- Fixed a bug where passing a reference field through
reforoutdidn’t work, and some other cases of valid code that didn’t compile. - Generated C++ code built in release by default. Uno code is still built in debug by default. Specify
-O0tounofor unoptimized build when debugging. - iOS: Passing –run to
uno buildnow runs the project directly on a connected device. Adding -adebug brings up the Xcode project as before. - MSVC12: The -adebug flag is also supported on the msvc12 target, opening up Visual Studio for debugging instead of running the executable.