New in version 0.9.4

Released one year ago

Please remember to uno clean your projects after upgrading Fuse.

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.

Note that ux:Property currently only works for atomic types (e.g. float4 and string) and not for complex class types. This is being improved in an upcoming version.

New triggers
  • Added WhileWindowSize trigger that lets you gate on window dimensions (in points). This element supports GreaterThan, LessThan and EqualTo, 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 with BackButton preset to capture Android back button event
Changes to layout
  • StackPanel and StackLayout now handle oversized content differently. It has a ContentAlignment 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" or ContentAlignment="Left" (depending on Orientation).

    The new defaults are considered to be the correct behaviour and this is considered a bug fix.

  • Grid and GridLayout have the same change as StackLayout, though it supports all non-default alignments for ContentAlignment.

  • 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 properties LimitWidth and LimitHeight can now be placed directly on the element. Units use the usual syntax: <Panel LimitWidth="100%"/>
Extended WebView API
  • Added Source and BaseUrl 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 are DebugProperty, DebugTime and DebugFrame
  • DebugTime outputs the current application time
  • DebugFrame outputs the current total frame count
  • DebugProperty takes a Tag string identifier and a Value property string (like Change and Set) and prints that current value prefixed with the Tag
  • A DebugAction without a Message 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 a TextInput before now accept a TextEdit.
  • TextInput is now derived from TextEdit
  • The namespace Fuse.Controls.TextEdit is renamed Fuse.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 renamed TriggerAnimation.GetAnimatorsDuration to avoid conflict/confusion with what it does and a new time scaling feature
  • Cycle gains the Waveform option. Of particular interest is Sawtooth 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 only Placed. It also does not contain any previous world information, as it was not possible to derive in a consistent fashion. An interested listener must use Preplacement 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 occasional "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, interface look ups are optimized to O(log n) instead of O(n) when calling methods or using the is and as operators.

  • 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 methodOld 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 expects arrayType directly rather than elementType, for better cache usage.

And these methods in Uno/Memory.h:

New methodOld 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 on uno build to update on demand. The redundant unotest and performancetest commands were removed -- use uno test and uno 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 the uno 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)}
  • Renamed C++ specific elements and properties

    The old names will generate a warning when used. Just replace with the new name for silence.

New nameOld name
TypeNameInstanceTypeName
FileExtensionSource.FileExtension
SourceFileBuild.SourceFile
HeaderFileBuild.HeaderFile
PreprocessorDefinitionBuild.PreprocessorDefinition
LinkLibraryBuild.LinkLibrary
LinkDirectoryBuild.LinkDirectory
IncludeDirectoryBuild.IncludeDirectory
Xcode.FrameworkiOS.Build.Framework
Xcode.PrefixHeader.DeclarationiOS.PrefixHeader.Declaration
AssemblyReferenceAssembly
  • Renamed CIL specific properties

    The old names will generate a warning when used. Just replace with the new name for silence.

New nameOld name
AssemblyReferenceAssembly
  • 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. The NavigationContext property should now be used on target navigation triggers (WhileCanGoBack and WhileCanGoForward).
  • 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 or out 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 to unofor 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.