May 2005 Archives

Using XML in NeoSwiff

| 5 Comments | No TrackBacks

Someone had asked me how to load, parse, and display .xml files using NeoSwiff. I created a simple example you can download here that does just that.

This example runs in the standalone version of NeoSwiff. It consists of two classes - the main application form, and a "Track" class that represents data in the xml file. The final result looks like this:

The code should be pretty straight forward. You create an XmlRequest that is capable of loading an external .xml file and listen to it's StatusChanged event. When the Status changes, you examine it, and if it is equal to XmlRequestStatus.Success then the file was loaded successfully and you can start reading the data from the Response. If there was an error, you can examine the request's XmlError property and check for things like XmlError.CommentNotProperlyTerminated, XmlError.MalformedXmlElement, etc.

The parse function I created looks at the XmlRequest's Response property (which is of type XmlDocument) and essentially just does the FirstChild / ChildNodes loop that you're probably familiar with in parsing XML in Flash. Note in C# we're using the "foreach" keyword to loop over both ChildNodes and Attributes. A quick code example:

/** Loops over the XML document and populates the list box */
private void ParseXml(XmlDocument xmlDoc) {
	XmlNode playlist = xmlDoc.FirstChild;
	
	foreach (XmlNode track in playlist.ChildNodes) {
		list.Items.Add( ParseTrack(track) );
	}
}
	
/** Reads individual track information */
private Track ParseTrack(XmlNode trackNode) {
	Track track = new Track();
			
	foreach (XmlAttribute a in trackNode.Attributes) {
		if (a.Name == "mp3") {
		   track.Url = a.Value;
		}
	}

	// the first child of the track node is the artist node.. 
	// and the first child of that is the CDATA text, so get the value
	// which is the artist name
	track.Artist = trackNode.FirstChild.FirstChild.Value;
			
	// the second child of the track node is the title node...
	track.Title = trackNode.FirstChild.NextSibling.FirstChild.Value;
			
	return track;
}

Also, the Track class looks like this:

/** 
 * A class that represents a single track entity in the XML file - notice
 * we implement IListItem with a DisplayText getter so the ListBox knows what
 * to display when a Track is added to it's Items.
 */
class Track : IListItem {
	
	public string Url;
	public string Artist;
	public string Title;
		
	public Track() : this("", "", "") {}	
	public Track(string url, string artist, string title) {
		this.Url = url;
		this.Artist = artist;
		this.Title = title;
	}
		
	public string DisplayText {
		get {
			return Artist;
		}
	}
}

This example is pretty simple, but shows you how you can load, check the status of, parse, and use xml data in your .swf files created via NeoSwiff. Essentially, this is exactly how I would do it in ActionScript, though everything here is typed just a bit differently. I had posted similar code in ActionScript awhile ago, for comparison purposes. Notice that the ActionScript code is a lot shorter (easier?), but the C# code feels a little more structured.

Phishers need to proofread too...

| 9 Comments | No TrackBacks

Just got this awesome email that I had to share. Links have been removed, as it's a phishing scheme.

[snip]
You have added phoneseller@yahoo.com as a new email address for your eBay account.

If you did not authorize this change or if you need assistance with your account, please contact eBay customer service at:

http://scgi.ebay.com/verify_id=ebay [[phishing link location removed]]

Thank you for using eBay!
The PayPal Team
[/snip]

I never knew PayPal was responsible for eBay as well! I'll be sure to click through the links and provide my login credentials. Maybe I'll post them here at some point as well, just to verify that I'm the one running my own website. :-)

NeoSwiff's Inline Assembly

| 6 Comments | No TrackBacks

Not only does NeoSwiff parse C# code to create .swf files, it also doubles as FLASM, allowing you to write inline assembly language that gets compiled directly to .swf bytecode. Here's how...

My last entry was for my little experiment application QuickDefine in which I wanted to integrate mProjector and NeoSwiff. I had a hard time calling the mProjector commands directly from NeoSwiff, and had to write an ActionScript file compiled with MTASC to glue the whole thing together.

Not anymore.

Through the power of NeoSwiff's inline assembler that was recently discovered, I can program at the bytecode level directly from within my class files. C# has a magical "unsafe" keyword that lets me write assembly language inline in a method body. Here's a small example:

/** 
 * Manipulates the stack directly.  Note the use
 * of the unsafe keyword which allows us to use
 * the __asm keyword.
 */
private unsafe string[] listFiles(string path) {
	__asm {
		push path
		push 1	// number of arguments
		
		push "mFile"
		getv // get the mFile global object
		
		push "listFiles"
		callm // call mFile.listFiles method
	}
} 

I can use the above method like so:

// use mProjector to get some Windows integration functionality
// -- call mFile.listFiles via inline assembler code			
string[] files = listFiles("c:\\");

// iterate over the files and display them in the mProjector
// trace viewer
foreach (string fileName in files) {
	// mTrace is another function that call's mApplication.trace
	// whose output I can see by opening mProjector's trace
	// viewer tool
	mTrace(fileName);
}

Notice the use of the unsafe keyword, and how the assembly code is placed within the __asm code block. Pretty slick, huh? I had mentioned this to Jesse and he promptly called me a geek.. then I realized that getting excited about inline assembly is something only a geek would do, so I guess the term was fitting.

The whole concept of assembly programming is pretty advanced, but also very powerful because it's so low level. I used to use FLASM to optimize bytecode of a .swf file, but the process was painful. You would compile a .swf in Flash, open it in FLASM and tweak the assembly, then re-assemble with FLASM. If you ever had to re-compile the .swf from Flash you'd lose all of your changes, so you had to save backups and document what you changed to make re-applying the changes easier.

With inline assembly, I get the benefits of optimizing certain portions of code without the pain of having the "extra" FLASM step. The workflow is much improved in this way, and I can bring my .swf bytecode optimizations directly into the C# world.

There will be full documentation published at some point. But, the assembly language has everything you would expect.. gets, sets, branches, jumps, registers, "init object", math operations (add / subtract / increment / etc.), and even labels (so you can jump to a label, as opposed to an address). The power that this brings to the table should make you give NeoSwiff another look once the docs are released. This is a very serious contender, and is shaping up to be an amazing product.

So... what I've been doing is wrapping up the mProjector commands into a NeoSwiff .scl library. Now, I can write code like this:

using mProjector;

// ... later on in a method call:
mApplication.trace("This is an example message");

Which makes using mProjector as easy in NeoSwiff as it is in ActionScript. The only part I haven't figured out yet how to add event listeners for the events. That is, this doesn't work yet...

mApplication.onSystemTray += new EventHandler(SystemTrayClick);

... but I'm sure there's a way somehow - just haven't discovered it yet. Once that final piece of the puzzle is in place, I'll probably publish my .scl library for others to use to easily integrate mProjector and NeoSwiff.

As an aside, if you program in assembly it's very easy to corrupt the stack. If you return a value from a function you simply push a value on the stack, but you have to be very careful. NeoSwiff provides two commands to help in debugging situations where you may inadvertently corrupt the stack:

System.Diagnostics.Debugger.BeginStackCheck();

the_unsafe_method();

// Raises an exception if the unsafe method has corrupted the stack
System.Diagnostics.Debugger.EndStackCheck();

The geek in me loves this stuff...

QuickDefine

| 4 Comments | No TrackBacks

I got tired of manually looking up words in an online dictionary, so I wrote this little app to do it for me.

Built with mProjector, NeoSwiff and MTASC, this windows-only application will sit in your system tray and wait for input. Any time you need to look a word up, just click the tray icon and the lookup form will appear. Type in (or paste) the word, hit enter or click the button, and a browser window will launch you to the Encrata site with the definition of the word you were interested in.

You can find the download here: QuickDefine.zip (743 KB)

The complete source code is included, and the code is licensed under the GPL.

Originally I had wanted to write the entire application in NeoSwiff. It was incredibly easy to create the Lookup form, but I got stuck with trying to integrate the mProjector commands. I tried using the ActionScript.NativeAccess and Swiff.Internal namespaces, but to no avail. There has to be a way somehow, but I didn't want to spend too much time on such a little project.

Thus, I created an ActionScript 2 class that handles the mProjector functionality. It essentially just sets up the system tray functionality and creates a window that houses the .swf made by NeoSwiff.

Overall, this project took less than an hour, including testing. It works fine for my needs, but feel free to adapt it to your own needs. I'm sure there are things that can be added (like specifying what dictionary to use instead of Encarta), but I defintiely don't need more work to do. :-)

Flex.org - The Directory for Flex

Archives