Runtime Shared Libraries with Plain ActionScript

Using RSLs is still a bit of a black art in ActionScript. This is partly due to the fact that documentation on it is sparse, partly because of the complex ActionScript code that mxmlc generates when compiling MXML files, and partly because the process itself is a bit unintuitive. These notes are the result of a few days of research on the topic.

A runtime shared library is simply a SWF file that is loaded into the application at launch. The code and assets in the library are then available for the application to use. This makes it handy when using third-party code libraries, or even your own libraries which are built to a published specification and are not going to change frequently. By making them external to the application, you can also share them between several different applications.

The Flex Way

ActionScript developers working with mxmlc directly outside the Flash Builder IDE may be familiar with the following warning.

/Projects/rsl-demo/Main.as: Warning: This compilation unit did not have a factoryClass specified in Frame metadata to load the configured runtime shared libraries. To compile without runtime shared libraries either set the -static-link-runtime-shared-libraries option to true or remove the -runtime-shared-libraries option.

This warning indicates that the programmer may have overlooked the task of loading external libraries at runtime. The Flash Player will throw a runtime exception and halt further execution of the application if attempts are made to execute code which is not yet loaded.

The solution is to add a Frame metatag at the top of the application class and set its factoryClass attribute to point to a class that will be responsible to load external libraries.

If you were to inspect the output of the mxmlc compiler on a Flex application, you will see hard-coded references to all the RSLs that the application is using in the factoryClass designate. These references come from the configuration options passed on to the compiler through either its command-line parameters or the compiler configuration file.

The class that contains these references is usually a child of the mx.managers.SystemManager class and generated automatically by mxmlc. The SystemManager class provides the infrastructure to load these files along with error handling and progress feedback to the user.

This generated class also contains a reference to the entry point class – the one that extends from the Application class. When all the library files are loaded, the framework instantiates this class and adds it to the display list of the factoryClass designate. This makes the factoryClass the root document class, while the Application-derived class is actually a child of the loader in the display graph.

The programmer still provides the Application-inheriting class as the compiler target. But when the compiler encounters the Frame metatag, it automatically associates the Preloader class with the document root and makes the Application a child of the Preloader.

An ActionScript Implementation

When using ActionScript directly instead of the Flex framework, the developer must manually add the Frame metatag to the top of the application entry point class.

[Frame(factoryClass="Preloader")]
public class Main extends Sprite
{

}

The Preloader Class

The preloading is a straightforward consumption of the flash.display.Loader API. It is implemented here using the Preloader class. This class must fetch every external library file needed by the application. The paths to the libraries are supplied to the Preloader class. When using the Flex framework, the mxmlc compiler bakes in the references to the library files into the code that it generates. The example below also uses the same technique. However, the URLs of library files can also be supplied from any other source such as a web service or external text file. All standard Flash Player APIs are already available to the Preloader class.

public function Preloader()
{
	var loader:Loader = new Loader();
	loader.contentLoaderInfo.addEventListener(Event.COMPLETE, this.loader_completeHandler);
	loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, this.loader_ioErrorHandler);
	var request:URLRequest = new URLRequest("math.swf");
	var context:LoaderContext = new LoaderContext(false, ApplicationDomain.currentDomain);
	loader.load(request, context);
}

It is important to note that the library has to be loaded into the same application domain as the main application. Otherwise, it will not have access to the classes in the library and any attempt to instantiate them will trigger a VerifyError at runtime.

VerifyError: Error #1014: Class com.notadesigner.math::IntegerArithmetic could not be found.

Using the Runtime Shared Library API

After the library has been downloaded, the Preloader class instantiates the application class and adds it to the display list. The developer must use the flash.system.getDefinitionByName API to get a reference to the application class. This is necessary because application class contains a reference to the IntegerArithmetic class. If the Preloader references Main directly, the compiler will pick up the complete chain of references and statically link the IntegerArithmetic class into the application SWF. By deferring to reference the application class until runtime, the compiler is prevented from scanning the dependency chain and statically linking the library classes into the application SWF.

private function loader_completeHandler(event:Event):void
{
	var mainClass:Class = getDefinitionByName("Main") as Class;
	var mainInstance:Main = new mainClass();
	this.addChild(mainInstance);
}

The Main class then continues with its business as normal. In this case, it is instantiating a type declared in the library and calling its method.

public function Main()
{
	var integer:IntegerArithmetic = new IntegerArithmetic(); // Type declared in math.swf
	var operand1:int = 10;
	var operand2:int = 10;
	var result:int = integer.add(operand1, operand2);
}

Deploying Runtime Shared Libraries

The confusing bit about using a runtime shared library is realizing that the SWF has to be extracted from the SWC at the time of deploying the application. This was not immediately obvious and I ended up spending days placing a compiled SWC file in various locations and wondering why the application was unable to load it at runtime. An obscure article on the Adobe website made explicit this particular step and set things straight.

Again, when placing the files, standard path rules apply. The Preloader can refer to relative or absolute paths. If the files are on external domains, the Flash Player attempts to fetch a crossdomain policy file before attempting to download the SWF. The policy file is to be specified as an additional value to the -runtime-shared-library-path parameter to mxmlc.

Sharing Code – Static and Dynamic Libraries in ActionScript

When I was in school, practically nobody had access to the internet. As a result, every student would have two essential items in his toolkit – an encyclopedia and a membership to a library. Homework, projects and supplementary studies were highly dependent on both of them.

Encyclopedias ranged from simple one-book units that specialized in a single subject, to multi-volume tomes spanning practically every topic imaginable (or at least deemed allowably imaginable by its publishers) by a school student. In both cases, the research was already done by someone else. When we were assigned a project on the solar system, nobody expected us to discover the planets in it. The planets remained discovered. All we had to do was read about them and share the information when making a presentation to the class.

Code Libraries

It is heartening to know that somebody creating computer languages took this to heart and invented the concept of code libraries – units of code written by people who are really good in the domain, then shared with the also rans who just wanted to implement their business applications without knowing the mathematics of relational databases or the bit-juggling that network libraries perform.

Libraries are compiled separately from the application that ends up eventually using them. They are linked to the application through a process that maps function calls in the application code with function addresses in the library. This process, predictably, is called linking.

Code stored in statically linked libraries is copied into the application executable at compile time, resulting an individual copy being created for every application that uses the library. Static libraries become an integral part of the application that uses them and cannot be shared with other applications. If the library is modified in any manner, the application must be recompiled and relinked with the new version in order to utilize those changes.

Dynamic libraries are stored in a shared location, and are linked to the application at runtime by the operating system or other environment controller such as a virtual machine. The metaphor falls apart a bit when it comes to sharing dynamic libraries – in a physical library, only one member can borrow a book at a time, whereas any number of programs can concurrently use the code stored in a dynamic library.

With static linking, it is enough to include those parts of the library that are directly and indirectly referenced by the target executable (or target library). With dynamic libraries, the entire library is loaded, as it is not known in advance which functions will be invoked by applications. Whether this advantage is significant in practice depends on the structure of the library.

Other than the obvious benefit of being able to compile units of code separately, either type of libraries offer their own individual benefits also. Statically linked code guarantees that all required code units are present and compatible with the application. Dynamically linked libraries may be of a different version than what the application requires, or not be present at all. Either case either causes a runtime error, or requires defensive code and reduced functionality in the application. Static linking also simplifies product distribution by reducing the number of files to be shipped and installed.

All said and done, both types of libraries are popular and well-worn concepts in computer programming. Many modern languages support either method, usually both.

Code Libraries in the Flash Ecosystem

Adobe’s MXML compiler offers several parameters for programmers to employ libraries – both static and dynamic – in their code.

Static linking is almost identical to how it is used in conventional languages. Dynamic linking works slightly differently from Windows’ Dynamically Linked Libraries and Unix’s Shared Objects due to the browser-based operation of the Flash Player. But these differences are at an implementation level only. The concepts remain the same.

Static Linking

To statically link a library into an application, the compiler offers the library-path and include-libraries directives.

library-path

When a library is specified using the library-path directive, the compiler includes only those assets and classes that are referenced in the application. For example, if the Math library contains IntegerArithmetic and FloatArithmetic for performing arithmetic operations on two separate numeric data types, but the client application only uses integers, the FloatArithmetic class is excluded from the output. This reduces the file size of the application SWF.

mxmlc Main.mxml -output=Main.swf -library-path=math.swc
include-libraries

The include-libraries directive packages the entire library, irrespective of what the compiler thinks is used in the application. This comes in handy in a dynamic language like ActionScript because all method calls do not necessarily get tested for linkages by the compiler.

var classRef:Class = getDefinitionByName("com.notadesigner.math.FloatArithmetic") as Class;
var instance:Object = new classRef();
instance["add"](10.5, 2.5); // Linkage not tested by the compiler

The include-libraries directive is used like this.

mxmlc Main.mxml -output=Main.swf -include-libraries=math.swc
static-link-runtime-shared-libraries

This directive is a convenient shortcut to convert runtime shared libraries into static libraries without significant changes to the compiler configuration files. Simply setting its value to true causes the compiler to embed all RSLs into the application. This is a handy way to investigate library-related problems when debugging the application.

mxml Main.mxml -output=Main.swf -static-link-runtime-shared-libraries=true

Dynamic Linking

A Runtime Shared Library (commonly abbreviated to RSL) is loaded by the application before it begins execution. Loading a RSL is a complicated task if done in plain ActionScript, but is taken care of automatically if the application builds on the Spark or MX Application class.

Adobe-provided framework libraries are the most obvious use case for using RSLs. All Flex-based applications depend upon these files. By caching them after the first time they are downloaded, future applications can be started much faster as they do not need to download the same code again. Custom libraries can also take advantage of the same technique.

Flash libraries are compiled using the compc utility, that ships as part of the Flex SDK. It generates a SWC file which is a compressed archive containing a SWF (named library.swf) and an XML (catalog.xml). To use this library, the developer must manually extract the SWF from the SWC using an archival utility (such as PKZip) and place it where the application can download it at runtime. As a good practice, the SWF is also usually renamed from library.swf to something more meaningful.

runtime-shared-library-path

This directive is used to specify the location of RSL files for the compiler. The compiler requires the names of both, the SWC as well as the extracted SWF, separated by a comma.

mxmlc -o=main.swf -runtime-shared-library-path=libs/math.swc,bin/math.swf Main.mxml

Related Directives

The Flex compiler provides two other directives to externalize the application’s assets and code fragments. The compiler tests linkages against these assets at compile-time, but leaves them out of the application binary. Libraries that contain these assets or classes are required at runtime, and the Flash Player throws a runtime error if they are not available.

These directives are useful when creating modules which are loaded dynamically into an application that they share code with. The application is linked to the requisite RSL, and the module does not need to fetch it again. However, the compiler still needs to test the linkages against the symbols – either against the original source code or a compiled binary. These directives assist in that task.

external-library-path

The compiler uses SWC files specified at these paths to test linkages with the application code, but does not compile the binaries into the application itself.

externs

This directive points to source files containing assets or classes which will be available at runtime. The compiler uses the source files for link testing, but does not compile them into the application binary.

Storing Values with Bit Packing and Unpacking

Bit packing and unpacking is a handy way of consolidating multiple data values into a single variable, thus compressing the amount of data being stored or transmitted. The number of values that can be stored depends upon the width of the data to be stored as well as the type of the value that it is packed into. A simple byte can store up to 8 bits of data. Larger types such as ints can store up to 16, 32 or 64 bits. This is an especially efficient technique for storing several small-width values, often smaller than the smallest width supported by a platform (such as byte or boolean flags) into a single large value such as a 32-bit integer.

Bit flags are commonly used for implementing low-level features, such as storing file access-permissions or packing values into a single value before transmitting across a bus. However, they can be applied with equal ease to higher level tasks such as storing user preferences or choosing which widgets to display from an enumerated list. We will see here how to use bit flags to store font formatting preferences, and apply them later to a label.

Bitwise Operators

There are a couple of operators we need to understand before we can move on to the implementation. Bitwise operators, by definition, work on individual bits inside a value. Since they are implemented directly by the processor itself, they are much faster than arithmetic operators such as division and multiplication. We will use bitwise AND (&), bitwise OR (|) and left shifts (<<) in this exercise.

A bitwise AND operation takes the binary representations of two values and performs a logical AND operation on each bit. The result is 1 in every position where both the bits are 1, and 0 if either or both bits are 0.

    001010
AND 011011
    ------
    001010

Bitwise OR on the other hand, compares two bits in corresponding positions, and sets the result to 1 if either of them is 1, or to 0 if both of them are 0.

    001010
OR  011011
    ------
    011011

Bitwise left shift operator moves individual bits within a single value by the number of places specified in the second operand. The value is padded with 0s on the right, and the left-most bits are dropped off.

    001010 << 1 = 010100

Implementation

We set up a simple Windows Forms project and draw three checkboxes and one label on the form. The aim is to have the checkboxes control three font properties of the label – weight, style and underlining. All checkboxes are given appropriate labels and configured to execute the _changeFormatting method of the form every time the CheckStateChanged event is fired. The code for this method is shown below.

private void ChangeFormatting(object sender, EventArgs e)
{
    byte flags = 0;

    flags = (byte)(
        Convert.ToByte(this.chkUnderline.Checked) << 2 |
        Convert.ToByte(this.chkItalic.Checked) << 1 |
        Convert.ToByte(this.chkBold.Checked)
        );

    Font f = new Font(this.label1.Font.FontFamily, this.label1.Font.Size, (FontStyle)(
        (flags & (byte)FontStyle.Underline) |
        (flags & (byte)FontStyle.Italic) |
        (flags & (byte)FontStyle.Bold)
        ));

    this.label1.Font = f;
}

Packing

In the first statement, the flags variable is populated with the values of each checkbox. We want to store the three flags in the last three bits of a single byte.

PositionSetting
7Unused
6Unused
5Unused
4Unused
3Unused
2Underline
1Italic
0Bold

In order to do so, we take the value of each boolean (either true or false), convert it into a byte, then shift it by an appropriate number of positions. The value of the underline flag is to be stored in the 2nd bit (starting from 0). So we left-shift its value by 2. Similarly, the italic flag is stored in the 1st position, so its boolean value is shifted by 1. The value of the bold flag does not need to be shifted at all.

    00000001 << 2 = 00000100 // Underline
    00000001 << 1 = 00000010 // Italic
    00000001                 // Bold (no shifting required)

A consolidated value can be generated by ORing the three values together.

    00000100
 OR 00000010
 OR 00000001
    --------
    00000111 // Decimal value 7
    00000000
 OR 00000010
 OR 00000001
    --------
    00000011 // Decimal value 3
    00000100
 OR 00000000
 OR 00000001
    --------
    00000101 // Decimal value 5

The decimal value can then be stored in a database or other persistent storage system as an integer or byte. This is better than having to store three boolean fields. This information can transmitted across systems too as a packed unit, to be unpacked later only when the preferences have to be applied to a display element.

In our example, we are unpacking and applying the values immediately for brevity. But a more practical situation would probably involve serializing the value somewhere, then deserializing and applying the font properties later at another location.

Unpacking

In order to apply the font styles on a display element, the individual values of each style parameter must be extracted from the packed value and then applied. The .NET framework defines enumerations for each of these style parameters in the System.Drawing.FontStyle enum. The values for each style parameter are listed below.

SettingDecimal ValueBinary Value
Regular000000000
Bold100000001
Italic200000010
Underline400000100

You will notice that each enumeration is double the value of its predecessor, hence moving the digit 1 by one position leftwards with every increase. This is a key feature of bit flags. Each element differs from the others only in the position of the 1 bit. Thus, the value of a given flag can be extracted from the packed value by ANDing the packed value with the value of the enumeration.

     00000111 // Packed value decimal 7
AND  00000100 // Underline enum decimal 4
     --------
     00000100 // Result - show underlines

This operations shows that the value of the underline flag is true. If the packed value was the decimal 3 instead of 7, then the operation would play out as shown below, resulting in the value 0 for the underline flag.

     00000011 // Packed value
AND  00000100 // Underline enum
     --------
     00000010 // Result - hide underlines

All that is needed then is to convert the result byte into a boolean and apply it wherever required. In our example above, the constructor of the Font class requires the values packed together any way as a FontStyle enum. To do this, each bit is ANDed with its corresponding enum, then all of them are combined together again using an OR operation. The resultant byte is cast into a FontStyle before being passed to the constructor.

The Secret Lives of Timer Objects

One of the better side-effects of working in memory-managed languages is that you don’t have to bother with manually cleaning up references. This removes a huge chunk of busywork for developers who have one less thing to get their heads around. Allocate an object, use it, and forget about it. The garbage collector will get around to it eventually and clean it out.

What could be simpler?

Great Power, Great Responsibility

However, with ActionScript 3, the bar has been raised substantially. This new incarnation adds a slew of APIs that increase its expressiveness and capabilities. Yes siree! ActionScript is no longer a toy language whose primary arsenal is gotoAndPlay(). There’s an extensive library of native classes that can do stuff like drawing on screen, playing audio, fetching text and binary data from all sorts of data sources, or even launching and communicating with other applications.

Take that, Java!

Several of these features mean that its legacy garbage collection techniques have to be replaced with less aggressive methods to identify unused memory. This in turn requires more developer intervention than before to identify which references are no longer required and which ones must be left untouched. The new AS3 garbage collector uses reference counting and mark sweeping (both techniques are covered by Grant Skinner here). And while things are still better than completely manual memory management, building complex or long-running applications requires that the developer have at least a passing understanding of how memory is allocated, references stored, passed around and cleared, and the potential for memory leaks in the midst of all this.

This is where the typical ActionScript programmer stumbles, mainly because people programming in AS3 often do not have a formal background in computer science or programming and have usually learned the language on their own through books or online tutorials. It is not uncommon to find ActionScript developers for whom this is their first taste of programming.

Our Subject for Today

One subtle pitfall is the Timer object which is used to run code on a specific time sequence. This class consolidates the setTimeout and setInterval methods. The API is pretty straightforward – create an instance of the class with its delay and repeat count properties, set up listeners which are triggered at the end of each delay or after the number of delays specified by the repeat count are completed, and finally, call the start() method to begin the countdown.

A Timer object is different from other types of objects because the garbage collector does not clear it unless it is stopped, even if there are no active references to it.

Let’s repeat that.

A Timer object is not cleared by the garbage collector as long as it is running, even when its references are set to null or the variable goes out of scope, and it continues to fire TIMER events as long as it is active.

The only way to clear the object from memory and stop events from being fired is to stop it using the stop() or reset() methods.

The following piece of code illustrates the permanence of Timer objects which haven’t been stopped.

package 
{
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.TimerEvent;
    import flash.utils.Timer;

    public class Main extends Sprite 
    {
        public function Main():void 
        {
             var t:Timer; // Create timer as a local variable

             t = new Timer(1000);
             t.addEventListener(TimerEvent.TIMER, this.m_tick);
             t.start(); // Reference ends here; Timer continues to exist and trigger events
        }

        private function m_tick(e:TimerEvent):void
        {
             trace("tick");
        }
    }
}

This may look like a design flaw in the language to the casual passer-by and elicit a very obvious question.

“Everything else is cleared automatically. Why leave behind timers?”

Some thought on the subject will make you realize that the language designers at Adobe weren’t off their rockers after all. This behaviour is by design. In the example code shown above, ‘t’ is a local variable inside the constructor. When the function ends, the variable goes out of scope and there are no more references to the Timer. If the garbage collector cleared it out, it would not fire any events at all. This would essentially mean that a developer could only assign Timer objects to those variables that remain in scope for as long as it is supposed to run, such as member variables inside a class.

Conversely, a Timer instance which remains active with no way for it to be accessed and stopped is terrible. The object continues to maintain references to listeners and triggers events on them regularly. Listeners can never be garbage collected either because their reference count never goes down to zero. And finally, each active timer occupies a slice of CPU time, bringing the processor down to its knees gradually.

The Timer object always passes a reference to itself in the target property of the TimerEvents it triggers. The listener can use this reference to stop the Timer. When the listener function ends, the event object goes out of scope and is cleared, taking the reference to the Timer object along with it and in turn, making it available for garbage collection.

Here is an example that illustrates how this memory leak can inadvertently occur.

package 
{
    import flash.events.TimerEvent;
    import flash.utils.Timer;

    public class Slideshow
    {
        private var m_timer:Timer;

        private var m_isActive:Boolean;

        /**
         * Example how not to use a timer
         */
        public function Start():void
        {
             this.m_timer = new Timer(5000); // Create and start a new timer
             this.m_timer.addEventListener(TimerEvent.TIMER, this.m_next);
             this.m_timer.start();
        }

        private function Pause(e:TimerEvent):void
        {
             this.m_isActive = false;
        }

        private function m_next(e:TimerEvent):void
        {
             if (!this.m_isActive) return;

             // Code to move to next slide
        }
    }
}

In the example above, the programmer using this slideshow component is expected to call removeChild() to remove it from the stage. However, because the component does not stop the Timer when it is removed, it will continue to fire the TIMER event for as long as the application is run, and also prevent the memory used by the component from being garbage collected by holding a reference to its m_next method. If multiple instances of the slideshow object are created and disposed using removeChild(), their timers will continue to fire and none of the components will actually be cleared from memory.

Mathematical Elegance in Programming

Project Euler is a collection of mathematical problems for the programmer who enjoys taxing his brain cells once in a while. The problems are ordered to be successively difficult to solve, which explains why, as of today, 91,510 people have solved problem one, while problem 283 is solved only by 9 people. Not only are they successively more taxing, but going through so many problems itself is a tedious task that requires mental stamina even when taken in installments over several days.

Understanding the sum of numbers from 1 to N

Diagram A

Diagram A shows a square with each side 10 units long. A green diagonal cuts the square into two equal triangles. The number of squares making up the square equals 10 x 10 = 100.

Diagram B shows one half of the triangle, whose base and height are 10 units for a total of 55 cells. The number of cells can be calculated by adding the number of cells in each column, i.e. 10 + 9 + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1 = 55.

A similar blue triangle is placed above the red triangle in diagram C, in a way that both triangles are touching but do not overlap. Both triangles encompass 55 units and have sides of 10 units each. They combine to make a rectangle that is 10 units wide and 11 units tall. The total number of cells in the rectangle is 55 + 55 = 10 * 11 = 110.

Diagram B

Thus it can be seen how the total number of cells in one triangle (i.e. N + (N – 1) + (N – 2)…+ 1) can be computed by calculating the area encompassed by a rectangle that is N * (N + 1) and dividing the result by 2.

Thanks Reddit!

The good part is that solving a problem helps an individual build an insight that is useful while solving another one later down the line.

The first problem in Project Euler asks to add all the natural numbers below 1000 which are multiples of 3 or 5. The straightforward way to resolve this is to use a loop from 1 to 999 that uses a modulus operation to evaluate each integer between 1 and 1000 with 3 and 5, adding the ones that are perfectly divisible and discarding the rest.

Diagram C

Here’s an implementation of this code in ActionScript.

var sum:uint = 0;
for (var i:uint = 1; i < 1000; i++)
    if ((0 == i % 3) || (0 == x % 5)) sum += i;
trace(sum);

But the secondary goal of these problems is to have an implementation that can return an answer in less than one minute. Problem one is not all that taxing for a modern computer, making even a naïve implementation run well within the required time frame. But complexity for later problems increases exponentially, making the selection of a fast algorithm very essential.

Hence, it is required that one should understand the mathematical principle behind each problem in order to write an efficient solution.

A step-by-step breakdown of the complex, but more efficient solution goes as follows.

The smallest multiple of 3 greater than 1 is 3 itself.

The largest multiple of 3 less than 1000 can be computed easily.

multiples = (1000 - 1) / 3
multiples = 333.33
multiples = floor(remainder)
multiples = 333

The floor() function is used to discard the decimal part of the result by mapping the real number into the previous smallest integer.

The result, 333, is the number of multiples of 3 between 1 and 1000. So the sum of these values can be computed by adding the multiples together.

(1 * 3) + (2 * 3) + (3 * 3)...+ (333 * 3)
= 3 (1 + 2 + 3...333)

The sum of numbers between 1 and n is n (n + 1) / 2. So the sum of 1 to 333 is 333 (333 + 1) / 2, which is 55,611. Multiplying that by 3 gives you 166,833, which is the sum of all multiples of 3 between 1 and 1000.

The same method can be used to compute the sum of multiples of 5 between 1 and 1,000, to get a result of 99,500.

The problem asks to compute the sum of multiples of 3 or 5. What we have done so far is compute the sum of multiples of 3 and 5. To remove the overlap between the two sets, compute the least common multiple of the two numbers, which is 15, and calculate the sum of multiples of that number between 1 and 1000. Subtracting that set from the first two will result in a set which contains numbers which are either multiples of 3 or 5 but not both.

The same principle also applies when the sum of multiples of 15 is deducted from the sum of multiples of 3 plus the sum of multiples of 5.

So your final solution is sumOfMultiples(3) + sumOfMultiples(5) – sumOfMultiples(15).

The complete implementation of the program is as follows.

package 
{
    import flash.display.Sprite;

    /**
     * Project Euler solutions entry point
     */
    public class Main extends Sprite 
    {
        public function Main():void 
        {
            var p:IProblem = new Problem1();
            trace(p.solve());
        }
    }
}

package  
{
    /**
     * If we list all the natural numbers below 10 that are
     * multiples of 3 or 5, we get 3, 5, 6 and 9. The sum
     * of these multiples is 23.
     * 
     * Find the sum of all the multiples of 3 or 5 below 1000.
     */
    public class Problem1 implements IProblem
    {
        public function solve():uint
        {
            var limit:uint = 999;
            trace((sumOfMultiples(3, limit) + sumOfMultiples(5, limit)) - sumOfMultiples(15, limit));
        }

        private function sumOfMultiples(factor:uint, limit:uint):uint
        {
            return factor * sum1toN(limit / factor);
        }

        private function sum1toN(n:uint):uint
        {
            return Math.round((n * (n + 1)) / 2);
        }
    }
}