Archive for August, 2009

ActionScript, Java When instanceof doesn’t recognize an instanceof.

2 Comments

Java’s ‘instanceof’ keyword is not the same as ActionScript’s ‘is’ keyword. In theory, they do the same thing: find out if an instance of an object implements a class or interface. In reality, they’re quite different.

Java compares for an exact match. ActionScript compares for a match or any subclass of the class being compared.

Let’s say we have class A which implements interface I. And we have class B which is a subclass of A (and implicitly implements interface I).

Java:

if( A instanceof I ) // True
    print( "yeah" );

if( B instanceof A ) // True
    print( "yeah" );

if( B instanceof I ) // False!
    print( "yeah" );

ActionScript:

if( A is I ) // True
    print( "yeah" );

if( B is A ) // True
    print( "yeah" );

if( B is I ) // True!
    print( "yeah" );

So, having learned a lot of ActionScript before diving into Java, I expected ‘instanceof’ to behave just like ‘is’. But no. And that was annoying not to realize at first. So, you’ve been warned!!

Update: Hmm, now I wonder if overloading method parameters behaves the same way as instanceof in Java? I’m going to be safe and make an interface for any classes that have multiple subclasses (ie, categories of entities which require special behaviors). It’s still polymorphic, so I guess it’s “good design.” I haven’t had quite enough experience digging into the reasons for Java’s language design choices.

Update 2: Of course I had to test the behavior of overloaded methods. Turns out that Java isn’t as exacting with overloaded methods–which is a relief!

For example, I have an Entity class, and a subclass called ItemEntity. I need to do some special handling on an ItemEntity (or any subclass of it) in a method that takes Entity as a parameter. Overloading that method to take an ItemEntity gives me the desired behavior for ItemEntity or any subclass of ItemEntity. Yay!

ActionScript, Java, Project Darkstar When ActionScript talks to Java using bytes

0 Comments

I’ve just finished building my client/server communication loop for Spirits of Gaia. The client is Flash (Flex), and the server is Java (built on Project Darkstar).

Darkstar uses a binary message format, which is a different approach from something like SmartFox, which uses strings (“raw”, XML, or JSON). I had experience with SmartFox, but I hadn’t tried to implement a binary format in Flash before. It really wasn’t bad in the end, and most of my time was spent just learning about ByteBuffers and ByteArrays in ridiculous amounts of detail.

And–of course–one of my bugs probably induced more research than necessary as I attributed malfunctions to various other possible causes. The bug was that I inherited one of the command processing classes from a base class which didn’t implement what I thought it did, so it was silently failing. :roll: But I learned a lot. A whole fricken lot! And that’s enough learning for anybody.

So one issue is that you can’t be sure what the endian-ness is for the server or the client. Well, maybe you can, but before now I didn’t know enough about it to make any assumptions. Darkstar uses ByteBuffers to hold incoming messages, and the default for Java is big endian for ByteBuffer. Thus, I use big endian on the server.

I had a feeling that Flash would take care of it for me, but of course I wanted to make sure it was using big endian, too. For a while, though, I didn’t know how to make a ByteArray use big endian or little endian.

hexadecimal My first approach was to get around it entirely by encoding all values that require more than 1 byte into hex strings. What a joyful aside that was! (Sarcasm, you see.) I mean, now I know how to encode anything to hex and back and do it sideways, too. But, this wasn’t working so well and it was bloating the nice binary format anyway. (No, I wasn’t really concerned about the size of the packets based on that, but if there’s a better way and it’s more space efficient–why not?)

Then I dug a bit deeper and realized that you can tell a ByteArray to use big endian like this:

var buffer:ByteArray = new ByteArray();
buffer.endian = Endian.BIG_ENDIAN;

Hard, huh? :) So then I didn’t need to encode multi-byte values into fun hex strings anymore (with one exception). So my PacketBuffer class got a bit more efficient in speed and size, and all is well now.

The one exception is for Java long values, which are 8 bytes. Flash (as far as I know) has no way to pull an 8-byte value from a ByteArray. And, no, I don’t want to do it by hand–which doesn’t mean I won’t! If encoding to hex string doesn’t work out, then I’ll write some code to stitch 8 bytes into a long value and stuff that into a Number (since it won’t fit into a 4-byte int). But, honestly, that kind of stuff is not my cup of tea because it’s not fun to me. But if it’s gotta be done, I’m a professional, so I’ll buckle down and do it. Clearly, I want to whine about it a lot just in case I do really need to do it.

For completeness, you tell a Java ByteBuffer to use big endian like this:

final ByteBuffer buffer = ByteBuffer.allocate( someSize );
buffer.order( ByteOrder.BIG_ENDIAN );

I think it’s ok to assume that Java (and Darkstar) will still default to big endian on whatever OS my future game server will be running (a flavor of Linux, no doubt). If I run into some bizarre bug where command ids are getting scrambled, I’ll know the first place to look.