Implementing New Stuff in AS3

So you need something in AS3 that does not exists already,
like zipping/unzipping things or parsing MIDI files, interpreting some other stuff, etc.

I could just say; “write good code, write more tests” and be done with it
but it is not that simple.

First, we have a tendency to believe already existing libraries are good or correct,
and that’s not necessarily true, dev can make honest mistakes too.

Second, the library simply do not exists already and so, if you really need it, it is on you to implement it from scratch, which is not necessarily that easy.

Third, there are many ways to implement what you need: do you write it all in pure AS3?, do you port code from C/C++/Java/C#/ etc. to AS3, do you reuse some C libraries via crossbridge ? do you create an ANE ? etc.

And finally many parameters to consider, here few examples

  • if I implement it in pure AS3 the performance will be poor
    but can it be good enough?
    (eg. you don’t need perf there)
  • if I’m doing a command-line call, it is ugly it is a hack
    but I could get away with it on that particular case?
    (eg. it does not have to work everywhere)
  • If I do it like that here it will be super fast
    but slow in every other case?
    (eg. there specifically I need perf)
  • etc.

General Advices to take with a grain of salt

Between now and before a lot of things have changed in the AS3 community and the most important one is that you can not rely anymore on other dev to develop on their own time open source libraries that you can reuse.

Before, you could wait, not ask anything to anyone, and then at some time a dev popup a library to zip/unzip stuff, oh great you can reuse that in that and this project to implement that functionality.

I call that opportunity-based functionality, you did not really planed for it but you gladly reuse it because someone else did it and it’s free.

Now, the community has shrinked so much that you will either find already existing libraries that you might need to seriously adapt for your needs and so on your own time/efforts, or it simply does not exists because nobody thought they needed it during the golden era where ActionScript was popular.

Yep, you are mostly on your own when it come to libraries.


But it is not all bad

  • writing your own libraries can help a lot to become a better dev

  • it help you grasp the differences between Application level, Framework level and Library level
    and that can tremendously help you become a better dev

  • it forces you to know what you have and don’t have in the whole AS3 ecosystem
    and so get in greater details of the API available by default to you (the Flash Platform API)

  • the more you do it (writing libs) the more it become easier to isolate abstractions
    and so focus on what you really need to make it work

At the Application level Flash/AIR are great has they come loaded with everything you need to build apps: a strong Flash Platform API that cover most basic things, a default GUI rendering engine (the display list) and events to connect it all at the UI level.

Simply put, you do not need anything else to just build a GUI, other languages/environments do not have that and rely on libraries/frameworks to just be able to do that (either build a GUI in C?).

Now at the Framework level, you had (still have) the official one like Flex or the various MVC thingy, but those are not absolutely essentials, they just help to organise an app, abstract some particular things like how to manage and architecture your app (with various success).

So for examples, PureMVC or RobotLegs will provide rules on how to do things and connect things together, that’s like a default architecture and you build on top of it, I call that lego assembly;

It is not necessarily good or bad, it is there to help you organise stuff if you don’t know any better, but I still say optional because if you know better you can directly design (in code) the architecture you need for your app (eg. build your own MVC/MVP/etc. from the get go).

And finally at the Library level you focus on a specific set of functionalities, like zipping/unzipping stuff for example, it is domain specific.

Also why you would never ever use an MVC framework to build a library, I call that a design mistake, it is possible, it will work but not something I would recommend.

The important thing about a library is that it is pure reusable code that put the dev in control, here you go new functionalities for your app.

A framework will have a tendency to take the control and force you to do things in a certain way with design/abstraction reuse, so you the dev are less in control.

For Flash/AIR specifically there are many things you do not need to implement as a library because it is already there in the API, for example: if you need to read the ID3 tags of some mp3 files, you got the basic covered with flash.media.ID3Info, now if you do need much more like album arts etc. yes then you will have to implement some id3lib to do those specific things.

In other case, like redtamarin, I do need to implement an id3lib no matter what :stuck_out_tongue: because it is simply not there at all.


When you are to the point of writing a library, even if only for your own projects (eg. not open source for everyone else to use), here few things to focus on

  • it should be easy and painless to add
    you do not want a complicated setup to be able to use the library
    drop the library there, import that package then done

    for zipping/unzipping stuff you could have a ziplib.swc
    and the AS3 package libraries.ziplib

  • obvious to the user
    whatever amount of code, classes, packages etc. you wrote
    at the end it should be as easy as using a couple of functions to do specific tasks
    for zipping/unzipping stuff you could have for ex

    import libraries.ziplib.*;
    zip( "path/to/file.zip", "path/to/file1.ext", "path/to/file2.ext",  ... );
    ...
    unzip( "path/to/file.zip", "path/to/extract" );
    

    a great way is to copy how command-line tools do it
    see zip and unzip man pages

  • use-cases and test-cases
    list of cases how the end-user will use the library more often
    by priority, frequency, importances, etc.

    for zipping/unzipping stuff the end-user will most likely want to

    • zip files
    • unzip files
    • etc.

And I would add as optional but nice to have

  • a way to build the library in an automated way
  • at least a one page doc of the main functionalities (like a man page)

Real world example for illustrative purpose

when I started to implement as3-universal-analytics I saw in the spec of the protocol that I needed a CRC32 hash function

on the moment I thought “oh someone must have already done it” and I could just copy/reuse an already existing AS3 lib or some code, or at the very worst port some JAVA / whatever to do a CRC32

because I was also looking at a Google Java implementation of the same protocol, I just saw they were using java.util.zip.CRC32, and when I looked into that CRC-32 implementation in java.util.zip.CRC32 realised that there were many different algorithm implementation of CRC32

so basically that

| name              | digest size | endianness | names, aliases |
|-------------------|-------------|------------|----------------|
| crc32             | 32bits      | little     | CRC-32, CRC-32/ADCCP, PKZIP |
| crc32_bzip2       | 32bits      | big        | CRC-32/BZIP2, CRC-32/AAL5, CRC-32/DECT-B, B-CRC-32 |
| crc32_c           | 32bits      | little     | CRC-32C, CRC-32/ISCSI, CRC-32/CASTAGNOLI |
| crc32_d           | 32bits      | little     | CRC-32D        |
| crc32_k           | 32bits      | big        | CRC-32K        |
| crc32_mpeg2       | 32bits      | big        | CRC-32/MPEG-2  |
| crc32_posix       | 32bits      | big        | CRC-32/POSIX, CKSUM |
| crc32_q           | 32bits      | big        | CRC-32Q        |

it’s all detailed here Catalogue of parametrised CRC algorithms

but still with the question which one to use?
and then you found out the sources of that famous Java java.util.zip.CRC32
with those comments

Computes CRC32 data checksum of a data stream. The actual CRC32 algorithm is described in RFC 1952 (GZIP file format specification version 4.3). Can be used to get the CRC32 over a stream if used with checked input/output streams.

so then you go check RFC-1952: GZIP file format specification version 4.3
and then in the appendix you read about Sample CRC Code etc.

and because I could not find an AS3 implementation I then decided to directly compare the results compiled from the original C sources and check if I obtained the same results on some samples

so I found mx.utils.HashUtil in the Flex SDK, not CRC32, but provide wrong results

and then I started to test in parallel the C source compiled to a very small exe with my AS3 implementation run with redtamarin so I could compare side to side results on the command-line

it resulted in this hashlib Hashing utility functions for ActionScript 3.0, and then I reused the exact CRC32 algorithm needed in as3-universal-analytics

this one here


Which lead me to those final little advices

  • even if a lib already exists, do check for correctness if you really depends on the result to be correct, things like zipping libraries, cryptography libraries, etc.
    you can not cheat correct there, it is the good algorithm or not

  • when starting to write one library you might need to split it in smaller (more focused) libraries
    this is divide and conquer, eg. focus only on zipping/unzipping stuff ignore the rest

  • any library is a good candidate for a command-line tool
    comparing your own zipping/unzipping lib made into a CLI exe
    to the classic zip/unzip exe can be really useful for compatibility tests etc.

  • referring to a RFC for widely known protocols, formats, etc.
    while implementing a library for such protocols, formats, etc.
    is imho best practice

  • alternatively looking at the long list of RFC can help you find
    what stuff should be implemented as a library

  • for AS3 specifically, do not be shy to make such libraries open source
    this can really help the community at large

1 Like