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
WhileWindowSize
trigger (do things when the window dimensions change) - Improved and extended
DebugAction
for 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
WhileWindowSize
trigger that lets you gate on window dimensions (in points). This element supportsGreaterThan
,LessThan
andEqualTo
, all taking a two component vector (float2). E.g.<WhileWindowSize GreaterThan="640,480" LessThan="1280,720">
- Added
OnKeyPress
trigger taking a Key value - Added
OnBackButton
OnKeyPress extension withBackButton
preset to capture Android back button event
Changes to layout
-
StackPanel
andStackLayout
now handle oversized content differently. It has aContentAlignment
parameter 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.
-
Grid
andGridLayout
have the same change asStackLayout
, though it supports all non-default alignments forContentAlignment
. -
The
Layout
constructor 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
DrawCount
facility -
LimitBoxSizingData
has been removed. The propertiesLimitWidth
andLimitHeight
can now be placed directly on the element. Units use the usual syntax:<Panel LimitWidth="100%"/>
Extended WebView API
-
Added
Source
andBaseUrl
attributes 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
LoadHtml
Action for telling a webview to load html source from a string and a baseurl. -
Added
HTML
node for WebView letting you cdata inline html as such:<WebView> <HTML> <![CDATA[ <h1>Hello world</h1> ]]> </HTML> </WebView>
UX debugging features
-
DebugAction
no longer outputs time and frame by default in addition to its Message. -
DebugAction
can contain certain debug nodes. For now these areDebugProperty
,DebugTime
andDebugFrame
-
DebugTime
outputs the current application time -
DebugFrame
outputs the current total frame count -
DebugProperty
takes aTag
string identifier and aValue
property string (likeChange
andSet
) and prints that current value prefixed with the Tag - A
DebugAction
without aMessage
only prints its child debug nodes if any.
Introducing unstyled TextEdit class
-
TextEdit
is introduced as an unstyled text input type. Most things (ex. triggers) that accepted aTextInput
before now accept aTextEdit
. -
TextInput
is now derived fromTextEdit
- The namespace
Fuse.Controls.TextEdit
is renamedFuse.Controls.FallbackTextEdit
to avoid collision and be clearer as to its purpose
Improved animation system
- The setter
HierarchicalNavigation.ReuseExistingNode
now 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.GetTotalDuration
renamedTriggerAnimation.GetAnimatorsDuration
to avoid conflict/confusion with what it does and a new time scaling feature -
Cycle
gains theWaveform
option. Of particular interest isSawtooth
which animates in one direction in a linear fashion -
Transform
now has an internal constructor. User classes are not supported as it’s important internally to have a controlled list. -
INavigation.ActivePage
added to return the currently active page. This fixes some issues using DirectionNavigation and PageBinding. -
LayoutChanged
has 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 usePreplacement
instead, 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 preview
more 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 expectsarrayType
directly 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
-v
if 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 doctor
replaces StdLibBuilder. Use whenever the package library needs updating. In addition, the--libs
switch can be used onuno build
to update on demand. The redundantunotest
andperformancetest
commands were removed – useuno test
anduno perf-test
instead. -
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
,-vv
or-vvv
when using theuno
command if you need more output. -
uno --version
will 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..#endif
directives will expand to comments containing the disabled code instead of blank lines, when false.
Other fixes
- Setting
Text.TextWrapping=NoWrap
with Native theme will no longer lead to text-wrapping on iOS - Add iOS.BundleVersion project property to set plist property
CFBundleVersion
on 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
Context
vs.NavigationContext
property naming inconsistency. TheNavigationContext
property should now be used on target navigation triggers (WhileCanGoBack
andWhileCanGoForward
). - 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
ref
orout
didn’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
-O0
touno
for unoptimized build when debugging. - iOS: Passing –run to
uno build
now 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.