Category Archives: Migration

Adobe Flex 2 running on OpenFL in JavaScript instead of SWF?

Around 15 years ago, Adobe introduced Flex 2.0, ActionScript 3.0, and Flash Player 9. I jump started my career as an expert in building Flex components and apps. Eventually, my experiences with Adobe’s framework led to my creation of Feathers UI — which today runs on OpenFL with the Haxe programming language. OpenFL aims to be an implementation of the Flash Player API — but it can target many platforms, from native mobile and desktop to web browsers with JavaScript (no plugins!). Over the years, I’ve also been a contributor to the Apache Royale compiler — which generates JavaScript from ActionScript 3.0 code. You are probably already seeing where this is going…

Edit: I updated to Flex 3 now

Is there some way to get a Flex application to run on OpenFL instead of Adobe Flash Player? OpenFL can target JavaScript, and Apache Royale can compile ActionScript 3.0 to JavaScript. Can both technologies work together? See for yourself: Demo: Adobe Flex 2 running on OpenFL.

Before you fall too far down the rabbit hole, let me warn you that this is all held together with bandaids, bubble gum, and duct tape.

Yes, it’s using the real ActionScript 3.0 source code included with the Flex 2 SDK, compiled to JavaScript with Apache Royale. It’s not a mockup or another GUI framework made to look like Flex. I had to make a few minor modifications to Flex classes due to slight differences between Flash Player and OpenFL, but most of the code is exactly the same as what Adobe/Macromedia wrote back in the day.

For an example of what I needed to tweak, the parent property of the DisplayObject in OpenFL is not a getter and setter (like it is in Flash Player). It’s a simple variable field instead. So when Flex tries to override the parent property to hide internal implementation details, that doesn’t work very well. I ended up modifying the code to use the internal/private _parent variable in several places to ensure that layouts worked the correct way. A more robust solution would be necessary for a real-world app (maybe a new public uiParent or flexParent property?), but this got things working quickly for my demo. Similarly, I had to tweak Flex’s overrides of some display list APIs, like addChild(), to handle some minor differences where OpenFL needed some extra hints to use only its internal APIs and not overrides. I also had to comment out some ApplicationDomain stuff that really only applies to SWF files loading child SWF files in Flash Player.

If you’re on a high DPI screen on desktop, you may notice that everything is rendering at the proper size, but it’s not blurry! This required adding some new code to Flex to smartly scale the SystemManager root display object. Basically, I just set scaleX/scaleY, and then any calculations in the framework using stage.stageWidth or stage.stageHeight needed to be tweaked to divide the width/height by by its respective scale property. I can’t stand looking at blurry Canvas/WebGL, so I decided to take some extra time to make things look good.

I did only enough work to get the Application, Button, and Alert components working, and that’s it. I’m sure that every Flex component would require at least some superficial tweaks. But I’m also impressed at how much code “just worked” and that I needed to focus on specific areas only. It really shows how well OpenFL emulates the Flash display list and vector drawing.

I had to manually bootstrap some things when the Flex app starts up, similar to the way that the Flex SDK compiler generates code for you automatically (you can see some of this generated code when you use the -keep-generated-actionscript compiler option when using the original Flex SDK compiler). For instance, I had to manually populate Flex’s StyleManager. The Royale compiler compiles CSS to native browser CSS for HTML, so that was never going to work for Flex running on OpenFL in HTML Canvas/WebGL anyway. Flex CSS is a simple subset of browser CSS, so I mainly just did a few Find/Replace commands in my editor to generate ActionScript from parts of defaults.css I copied from the Flex 2 SDK.

MXML only kind of worked. I could create a root component, set some properties, and listen to events, but adding children failed. The Royale compiler actually supports MXML with all of the bells and whistles, but the way that this gets converted to JavaScript isn’t really in the right data format for Flex to understand. With a few tweaks to the Royale compiler, and by adding some some additional parsing code to Flex, it could easily be done, though. For this demo, that wasn’t necessary.

I chose the very old Adobe Flex 2 released in 2006 instead of the newest Apache Flex 4.16 because I figured I would be most likely to find success creating this simple demo with an early version of the framework that hadn’t grown very complex yet. After completing this demo, I still believe that this was the right choice, but I also feel confident that Flex 3 or Flex 4 could also be feasible now that I have experience getting Flex 2 working.

Unfortunately, I’m not sure that I can legally share my code for this demo. Version 2 of Flex was still a commercial product (even if source code was included for customers to read). It was a later version of Flex that Adobe released as an open source project. I don’t think the open source license extends to previous versions. While I doubt Adobe legal cares about a discontinued product that eventually became open source, better safe than sorry. If you really want to see more, you should try to get in touch with me privately.

EDIT: I updated the project to use Adobe Flex 3, which was the first version that Adobe released as an open source project with the Mozilla Public License (MPL). Download the complete source code for this proof-of-concept from Github:

Github repository: openfl-adobe-flex-poc

Anyway, I just wanted to share a bit of nostalgia with you today. Back in the mid 2000s, Adobe Flex was a really great way to build rich applications for the web — an impressive precursor to today’s SPAs/PWAs (single page apps or progressive web apps) built with frameworks like React, Vue, or Angular. I owe much of my early career growth to Flex. Even if I can’t use Flex in my software development anymore, I still try to remember some of its spirit as I work on Feathers UI for OpenFL. That being said, it was ridiculously fun to use the real thing for the first time in a very long time!

Migrating an Apache Flex app to React: Milestone 2

Back in January, I wrote a post about reaching the first milestone in the process of converting my app Logic.ly from Flash Player to plugin-free HTML & JavaScript. That first milestone involved converting a subset of the app (a non-editable view of a simulated circuit) so that I could embed interactive examples inside the help files for Logic.ly. Once I got that finished, it was time to move on to the next, more ambitious, milestone. For the last ten months (roughly two hours a day, four to five days per week), I’ve been working on enabling nearly every feature of the full app. Last week, I replaced the online demo of Logic.ly that was previously using Adobe Flash Player with a fully JavaScript and HTML DOM powered version, built with React and TypeScript.

I thought I’d share some of my thoughts on the libraries, tools, and platform that I’ve immersed myself in throughout 2018, and how it compares to my long experience with Adobe’s Flash platform.

React

I’ve come to enjoy React quite a lot. Especially React combined with TypeScript. React uses JSX, an XML-like way to describe UI that is very similar to MXML in Flex. However, JSX flips things around compared to MXML. Instead of script being embedded in XML, XML is embedded in the script. This makes it really easy to conditionally render parts of the view based on state, or to even loop through arrays to repeat multiple instances of the same type of component. As you can imagine, JSX’s flexibility has the potential to lead to some pretty gnarly spaghetti code. However, with care, JSX feels to me like a superior paradigm to MXML.

React’s ecosystem is very active and full of high quality, custom components and libraries. Reach Router, react-beautiful-dnd, and react-loadable are just three wonderful examples of open source packages that are worth checking out. The only thing that I’ve struggled with is finding the “perfect” UI control library that has a decent number of core components, works on both desktop and mobile, and also offers a robust styling system.

I’m using Semantic UI for the UI Logic.ly, which is generally pretty serviceable. However, like many React UI control libraries that I evaluated, there are a ton of components that I don’t need right now (which isn’t a bad thing), but some more basic components are surprisingly missing (which is kind of weird). For instance, Semantic UI doesn’t offer a slider/range component. In fact, the slider/range is one of the most commonly missing components in various other React UI control libraries that I also evaluated, which has me baffled because it’s such a common piece of UI. In the end, I used the regular HTML <input type="range"> as a fallback, but it feels out of place and requires some hacky styling.

Redux

As you may know, the most popular architecture framework for React is Redux, and that’s what I’m using for Logic.ly. It provides the same kind of structure/organization to a project as many of the MVC frameworks that Flex developers probably encountered over the years — like Robotlegs, Swiz, PureMVC, Cairngorm, and others. Interestingly, it also heavily leans into functional programming concepts, including expecting the data it stores to be immutable.

I’m not a huge fan of Redux, to be honest. It’s better than no framework at all for a big app like Logic.ly, but I hope that something better comes along eventually.  I understand Redux’s benefits, but from a developer experience perspective, I just don’t like the way it feels. Some people claim that it has a lot of boilerplate, but I didn’t feel like that was something that bothered me. Sure, there’s probably some room to streamline things a little, but I think I’m more turned off by reducer concept and immutability requirements. I understand that this type of architecture is a big part of functional programming, but it feels “off” in a UI development environment where things are often more naturally represented with an object-oriented paradigm.

Recently, I saw some people talking about Immer, a library that provides immutability with an API that acts more like mutable data. That’s really interesting to me, and I think that it might improve the Redux experience to be more like what I prefer. Hopefully, I can find some time in the future to check out Immer and give it a test drive.

TypeScript

After years with ActionScript, TypeScript offers many of the same familiar improvements over JavaScript. It also provides a ton of really useful new features that ActionScript doesn’t provide (and won’t be getting in the future). Here are some of my favorites:

More flexible interfaces. You don’t need to create a class to have an object implement an interface in TypeScript. If you have an IPoint interface that has x and y properties, you could set a variable’s type and assign a value like this:

let p: IPoint = { x: 10, y: 15 };

Type inference. A smarter compiler that can figure out a variable’s type from context is probably the biggest advantage of TypeScript over ActionScript, in my opinion. It saves an incredible amount of typing. In the code example below, the compiler is smart enough to figure out that n should be a number and s is a string:

let n = 123;
let s = "Hello";

Proper generics. In ActionScript, we only had the Vector type. In TypeScript, you get the full power of creating your own types that use generics. That means less casting required and better chances that the compiler will catch a mistake.

let map = new Map<string,MyType>();

Arrow functions. Being able to define a local function where this matches the scope of the surrounding method reduces so many headaches. Plus, the shorthand syntax of arrow functions is super slick.

myArray.forEach( item => console.log(item) );

The let keyword. Using var in JavaScript and ActionScript creates a variable in the scope of the local function. Other languages usually create variables in the scope of the nearest block. So, if you created a variable inside the body of an if() statement or a for() loop, you wouldn’t be able to access it outside that block. Using let makes JavaScript and TypeScript variables more like those other languages:

if(someCondition)
{
    let value = false;
)
value = true; //error because value is not in this scope

Performance

Logic.ly isn’t your typical form-based app, and it can potentially display hundreds (or thousands) of objects in the editing surface at the same time. To keep performance high, I needed to customize the update behavior for some components to ensure that React was performing well and not rendering too frequently. This isn’t anything that’s wrong with React. In fact, there are established best practices for my situation, which is a great indicator of maturity.

In some places, I could easily switch to using PureComponent, and here and there, I created some custom shouldComponentUpdate() methods for even more control over rendering. I made heavy use of the React Dev Tools to ensure that my components weren’t rendering too often, and ultimately, all of my work paid off. I haven’t even had the chance to try out the new React Profiler yet, which I expect will improve performance even more.

Many parts of Logic.ly running on top of React and JavaScript are much faster than the old Flex and Flash Player version of the same app. Part of that is probably thanks to the ground-up rewrite. Anytime you start from scratch, you get to drop some of the baggage that you had before, and you can make better architecture choices from the beginning. However, React’s virtual DOM and decreased reliance on events/observers/binding is probably a non-trivial part of it too.

There’s also the fact that JavaScript virtual machines have kept on improving over the last several years, while the ActionScript virtual machine hasn’t evolved since Adobe stopped investing heavily in the platform several years back. There was a time when types in ActionScript gave it a huge advantage. Now, JavaScript VMs do things like create their own internal shadow types to use with dynamic objects behind the scenes, which basically makes JavaScript as fast as ActionScript once interpreted code is converted to bytecode. Combine that with a ton of other JS optimizations, and while I’m sure that Flash Player is still faster here and there, it doesn’t have the major advantage it used to have 10 or more years ago.

One place where switching to JavaScript shines is being able to take advantage of code-splitting. This allows Logic.ly to load only the parts of the code that it actually needs, and load the rest on demand. I’m able to show UI to the user faster than before (so that they can start using the app sooner, instead of waiting for everything to complete loading), and I can ensure that their bandwidth usage is minimized. Flex had the concept of modules, and any SWF can load other SWFs, of course. Additionally, SWFs support preloading the first frame to show some kind of loading screen to keep the user distracted. However, setting up code splitting in JavaScript is significantly easier and more powerful, in my opinion. It happens automatically any time that I reference a module with import(). It’s great! If Flash Player were still a competitive platform for deploying to the web today, I’m sure that Flex would have a smarter automatic module system by now, but as a fading platform, it’s (not unexpectedly) falling behind on things like this.

Limitations of the web platform

Even with all of the great advancements for frontend web developers over the last several years, there are still places where Flash Player still does things better. Here are a couple of places where I ran into trouble or where things felt half-baked.

There’s no JS equivalent to localToGlobal() and globalToLocal() to convert points between different coordinate spaces. Well, that’s not completely true. SVG exposes an API for converting points between the SVG coordinate space and the global coordinate space of the surrounding page, and I guess that’s probably what I’m supposed to use. I found that it’s a little clunky, but I made it work… but only successfully in Chrome and Edge. I discovered that once you use CSS transforms on some elements, such as scaling or rotation, converting points between different coordinate spaces did not work correctly in both Firefox and Safari. This is absolutely necessary in Logic.ly, since the editing surface can be zoomed in and out, so I had to write my own conversion function to handle scaling when trying to position objects in two different coordinate spaces. It was not ideal. I’m actually surprised that this functionality is broken in two major browsers. I’ve made heavy use of localToGlobal() and globalToLocal() in Flash for well over a decade, and I know they’re commonly used in a ton of ActionScript projects, so I would have expected them to be nearly as important to JS developers.

I find it frustrating that there’s no global event dispatching API in JS that anyone can use with their own custom types and objects. The HTML DOM can dispatch events, and other types like XMLHttpRequest can too. This feels like an odd omission. Sure, there are third party libraries, but none of them are completely compatible, so you could end up with a dozen different implementations of events in one app, if you aren’t careful. The EventDispatcher type (and IEventDispatcher interface) in ActionScript powers the Flash display list, networking APIs, and basically everything that’s built-in, and it can also be used by custom ActionScript classes. This helps everything feel more cohesive in the Flash world, and it limits the amount of duplicated work required by developers in the ecosystem. At least the JS world seems to be trying to standardize on Promises for many things now where events were used in the past. However, adoption of promises has been in progress for years, and we’re not anywhere near using them for everything yet. I don’t see this situation improving any time soon, which is unfortunate.

On to the next milestone!

Whew! That was quite a lot for me to bring together. So, what’s next? Well, I still need to migrate the desktop version of Logic.ly to the new codebase. I will probably use Electron when I start working on that. However, I think that I will save that for a bit further in the future because I recently decided that it was time to start thinking about finally bringing Logic.ly to mobile.

Milestone 3 will be updating the Logic.ly online demo to provide a more mobile-friendly UI on Android tablets and iPad. Right now, mobile users get the desktop version with a few very minor tweaks. I knew that migrating to JS/HTML and adding in a mobile UI would be too much to handle all in one step, so I decided to keep it simple for the previous milestone. Finally, in the last couple of weeks, I’ve started working on the mobile UI, and things are moving forward smoothly and rapidly. Soon after I update the online demo for mobile, I’d like to expand the codebase into a full-fledged mobile app that I’ll release on the iOS App Store and Google Play. These new sources of revenue will hopefully enable me to have more time to work on updates to Logic.ly in the future! I plan to look into using Capacitor to build the mobile app.

Migrating an Apache Flex app to React: Milestone 1

Last year, I mentioned that I’m migrating an Apache Flex application to JS/HTML/CSS. At the time, I was still very early in the process. I knew that I’d be using TypeScript and React by that point, but I was still evaluating various UI component libraries. In addition to learning and prototyping, I also had to port a lot of code that wasn’t part of the UI, so I haven’t had much to share about my progress until recently.

Yesterday, I deployed the first bit of code from the new version of my app Logicly to production. The original codebase included something that I call the “Logicly Viewer”, which is a limited version of the project that can be embedded in HTML to load a file in read-only mode. I created it so that I could embed a real circuit simulation into the documentation to help make various concepts more clear. Unlike the main editor, nothing in Logicly Viewer can be added, deleted, or dragged around. However, you can interact with certain components to update the simulation and watch signals propgate. I knew right away that the Logicly Viewer would make a perfect first milestone because I wouldn’t need to implement Logicly in its entirely. All of the work on this milestone will act as a foundation for future milestones, and I get to deploy something to production that real users will be able to see today while I continue to work on the rest of the project. That really helps keep me motivated!

I’ve embedded the Logicly Viewer below, with a simulation of a half adder:

(Click/tap the switches on the left side to see the simulation update)

Logicly simulates logic gates, which are low level constructs in computers and electronics that perform boolean math (operations on 1s and 0s). The simulation keeps track of the current state of a circuit, which includes the signal being output from each logic gate and where that signal gets passed next. It was relative easy to port the simulation from ActionScript to TypeScript, since the languages are so similar. However, I wanted to avoid introducing any bugs, so I ended up writing a ton of automated tests at the same time. The original implementation of the simulation in ActionScript didn’t have any tests, so writing them took a non-trivial amount of time because I had to start from scratch. It was worth it, though, because it caught a few bugs that I had accidentally introduced into the new TypeScript version.

Once the simulation was up and running, I started working on the “wires” that can be dragged between components to connect things in the simulation. You can see them in the embedded viewer above — they’re the bezier curves that are drawn between components. Implementing these as React components was an interesting challenge because it requires more access to the HTML DOM than most people using React typically need. Additionally, React’s typical data flow doesn’t play well when many components need to interact with each other from various levels of the tree. I ended up using Redux so that I could use its Provider component to connect the components with data. As for visuals, I ended up using SVG. It’s really nice to be able to use SVG right alongside HTML with JSX.

The code below basically shows how I use my wires library in React/JSX:

<WiresProvider>
	<WireSurface wireFactory={this.createWireRenderer}/>
	<div>{components}</div>
</WiresProvider>

The WiresProvider is a Redux Provider component with an internal store, and it passes the data down to any components that are interested. The WireSurface is where the wires are drawn. As I mentioned, I implemented the wires as SVG bezier curves, but the WireSurface supports custom implementations that draw wires differently, if needed. The wires get the data about the connections from the WiresProvider. The components added to the <div> that appears after the WireSurface are the logic gates and other components that get displayed by the viewer/editor. These may contain child components called “terminals” where the wires start and end their connections.

The logic gates and other components are also drawn using SVG. I was able to export SVG files from my original vector art created in Adobe Animate CC. I made a few tweaks to simplify the generated SVG, but the output was actually pretty decent overall. Between JSX and CSS, modifying paths and colors in SVG at runtime turned out to be very easy. I’m excited to explore SVG further because I feel like modern web apps could really benefit, but it seems to be underutilized today.

Obviously, the Logicly Viewer needs to be able to open files created by the full version of Logicly. The underlying file format is XML, but it’s also compressed using the deflate algorithm. I ended up using the pako library to inflate the data to get the raw XML string, and I used @rgrove/parse-xml to parse the XML into JS objects. Originally, I had worried that file parsing would be a major pain. However, this ended up being one of the easiest tasks that I worked on in this project! The @rgrove/parse-xml library produced a very easy to understand object tree.

What’s next?

In the next milestone, I will start implementing the full editor with things like drag-and-drop and selection. In fact, I already have some of the drag-and-drop features implemented, since I wanted to be sure that was easy enough to implement with React before I committed. I’ll be using the excellent react-dnd library.

The next thing that I will deploy to production will be the web demo of Logicly that allows people to try the app in their browser. It currently runs on Adobe Flash Player, and #Flash2020 looms ever closer. This web demo doesn’t support saving files, printing, or opening multiple files at the same time, but everything else works the same way as the desktop app. It’ll be more work than the Logicly Viewer, I think, but it’s also another subset that allows me to deploy more to production before the whole project is completed. After that, I’ll start digging into Electron to build desktop apps for Windows, macOS, and Linux. Then, Logicly will be ready for the future, and I can explore new possibilities, like mobile apps, Chromebooks, and more!