Posts Tagged ‘C++’

An introduction to Unity3D for Android

We’re going to take a short break from the Seven Languages updates to talk about Unity 3D, as I’m working on a short demo project and would like to chronicle some of the early highlights as well as bumps in the road.

Unity 3D is an incredible tool geared solidly towards making 3D game content. For years Unity lived in obscurity, targeting its output strictly to the largely unheard of Unity Web player, a competitor to Flash that never really took off. Unity has always been interesting, but its reach was never truly compelling until recently. What’s changed? Unity now has the ability to compile projects to native applications that target iOS and Android in much the same way as Adobe’s CS5 can create native applications for iOS and Android that run swfs using the AIR packager.

Most of what I’ve done with Unity involves mashing together various different tutorials and making them behave in new and interesting ways. This is surprisingly easy to do. What’s slightly harder is making sure it all works when you’re ready to publish to an APK file. I’ll break this down a bit and highlight some of the things that can go wrong.

Certain standard library code won’t compile on Android. This is typically going to be code in JavaScript files, as JS allows and encourages dynamic object referencing while Android an iOS does not allow it in any form no matter the language you choose. For this reason alone I’d suggest to never use JS if developing for iOS or Android. Code that doesn’t generate any immediate errors as you’re writing it may be non-compilable. One such error was easy to find and fix:

Assets/Standard Assets/Scripts/DragRigidbody.js(31,22): BCE0019: ‘isKinematic’ is not a member of ‘UnityEngine.Component’. (Filename: Assets/Standard Assets/Scripts/DragRigidbody.js Line: 31)

I found the solution to the issue here

Other errors were more insidious. One in particular was evident in the Detonator demo buried in the example project on this page.

BCE0019: ‘size’ is not a member of ‘UnityEngine.Component’.
BCE0019: ‘detail’ is not a member of ‘UnityEngine.Component’.

If you look at the relevant code in light of the restriction against dynamic coding the problem is obvious.

var offsetSize = currentDetonator.GetComponent("Detonator").size / 3;
var hitPoint = hit.point + ((Vector3.Scale(hit.normal, Vector3(offsetSize,offsetSize,offsetSize))));
var exp : GameObject = Instantiate (currentDetonator, hitPoint, Quaternion.identity);
exp.GetComponent("Detonator").detail = detailLevel;
 
// currentDetonator.GetComponent returns GameObject.  
// GameObject does not have a .size or a .detailLevel.
// variable.

So you’d think this could be solved by just casting the return value of GetComponent into Detonator and we’ll be fine. Unfortunately there’s an entirely different problem when you do that…

BCE0018: The name “Detonator does not denote a valid type”

But why is this? Why would it suddenly be invalid on Android but not when compiling for the web player? That has to do with the order in which scripts are compiled. This link details some of the pitfalls that can be related to script compilation order. This particular issue was a result of the fact that the JS file was compiled *before* the Detonator and had no reference to the Detonator scripts. I could solve this by re-arranging the locations of the script files, or by re-writing the JS to be C#. I opted for the latter. This solved my problems.

Another issue I ran into, that was harder to diagnose, is that in one of my scenes I’d created a terrain, as I wanted to play with the terrain painting tools. Unfortunately, every time I tried to load the scene that had the terrain my apk would crash. This is because Terrains are unsupported on Android. This means that you won’t be using any of the pretty terrain painting tools if you’re targeting mobile.

Don’t let any of these things stop you from exploring Unity, however. These have been fairly minor setbacks, and the results of a successful compile are nothing short of incredible. Unity’s particular deal with the Devil is that it gains incredible ease of content creation for performance, but depending on how you look at it Unity might just have gotten one over on Lucifer. Performance may not be up to the level of C++ but it is definitely respectable, and the tools for creating and managing projects are truly amazing.

I’ll be sure to keep you posted as this progresses.

Tags: , , ,

12 Comments


Flashing your C String

On a project I worked on a few months ago, I was tasked with taking data from a binary source file, reading it into Flash as UTF Bytes (eg: a ByteArray) and parsing the resulting ByteArray as a String. Straightforward enough, right?

What I know of the file to parse is that it is a very long list of words compressed and encoded, and that it needs to be decoded at runtime inside the swf. Fortunately, I have the algorithm for decoding the string on-hand, so I know I can implement this with relative ease. All I have to do is load the .dat file containing the list and then run the resulting byte array through the parser and get my list of words.

var ba:ByteArray = myImportedByteArray;
ba.position = 0;
var encodedString:String = ba.readUTFBytes(ba.length);
trace(encodedString);
/* My expected result was something akin to:
"Header Metadata - (Jibberish representing encoded list goes here)"
*/

So funny enough, when I do that what do I get instead?

"Header Metadata"

Huh.

I spent a good long time puzzling over where the encoded word list was in all of this. I could open the .dat file in Eclipse, and plainly see the list right there. I wondered if perhaps there were some sort of problem reading the data. Maybe the ByteArray was incomplete? No, because when I traced ba.length it indicated that the array was well over 90,000 bytes in size. Definitely too many to simply be “Header Metadata”. Next, I did this:

// 200 chosen simply for the sake of an easier to read log...
ba.position = 0;
var byte:Number;
while(ba.position < 200){
	byte = ba.readByte();
	trace(byte, String.fromCharCode(byte));	
}

What I recieved in the output window was in fact the first 200 characters of the file just as I’d expected them to be!

72 H
101 e
97 a
100 d
101 e
114 r
32  
77 M
101 e
116 t
97 a
100 d
97 a
116 t
97 a
0
32  
63 ?
32  
0
102 f
111 o
111 o
98 b
97 a
46 .
46 .
46 .

This gets more and more curious by the moment. At some point though, the lightbulb goes on. Look at this right here….

100 d
97 a
116 t
97 a
0        // < -- see that 0?  
32  
63 ?
32  
0        // < -- and that 0?

Anatomy of a String

So, in Flash-land we very seldom have to know about what might be going on under the hood of the String class. I mean, we just declare Strings, read them, print them, concatenate them, and in general just don’t really care much about how they work. It is not like this in all languages, however. Hop aboard the black stallion, for the Horseman is about to take you to a magical world known as “C Strings.”

The C language generally operates “Close to the metal” of a machine. You can think of it as an abstraction that allows you to write code that is then directly translated into Assembly-level instructions, that are then executed by the machine’s processor. In that sense it is a “High level” language (at least in comparison to writing Assembly by hand) but it is lower level than what an ActionScript or Java programmer would have to deal with as our respective Virtual Machines abstract over the nitty-gritty of memory allocation and deallocation, and direct pointer manipulation inherent in C. So what does a String look like in this lower level world? It is ultimately nothing more than an Array of char values.

char someString[10]; // an array of char values with a length of 10

It needs to be pointed out that there is a very important distinction between C Arrays and ActionScript Arrays. C Arrays are fixed-length. If you declare an Array to have a length of 10, then a contiguous set of memory addresses, of a size capable of storing 10 units of the data (in this case, char values) is allocated for that Array. That’s all. Nothing else happens. An Array in C is not an Object, so it doesn’t have a notion of a “length” property, nor does it have .push() or .pop() functions. Unless you know the length already, you can iterate your way past the end of the Array and keep on going into some other variable’s data… possibly even into undefined space.

This is considered “a very bad thing to do”. (As an existential aside about walking off the end of an array, please read this blog post by Steve Yegge)

But wait, if you can’t know the length of an Array in C then how can you possibly know when you’ve reached the “end” of a string?

Good question! Here’s what the string “Hello World!” looks like in C:

char *foo = "Hello World!";
// looks to the machine like this in ASCII....
// {72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33, 0}

Each of those numbers maps to a Unicode representation of a letter, so for example 72 maps to “H” while 33 maps to “!”. If you want, to see this in the Flash context you can set up a KeyboardEvent listener and trace the event. You’ll find the keyboardEvent.charCode property will match the above.

But do you notice anything funny here? “Hello World!” has 12 chars, but that array above has 13 entries! The very last one of course being 0. Now why is that?

In C, when you want to know if you’ve reached the end of a string, you’ll look for what is called a null terminator. In C, 0 can be considered a null value and so when a string is declared it has a length equal to the length of the characters entered into it plus one for the terminating 0. Any code that wants to parse the string can know that it should stop when it hits a 0 because to keep going after that could lead anywhere! And we certainly wouldn’t want to add some instruction set for connecting to the printer to your string… or worse, overwrite it with some random garbage!

And so this brings us back to our little ByteArray in Flash and the encoded word list. As you can see, the header metadata is immediately followed by a 0. In C terms, this file is in fact 3 strings instead of 1. Knowing this, and observing the fact that Flash’s String object seems to believe that this 90,000+ length ByteArray is in fact a string of a mere 15 or so characters, we can deduce that under the hood Flash’s String is C’s string.

My algorithm then, had to account for this fact and once I knew that Flash would treat a 0 byte as a null terminator when calling readUTFBytes, was able to successfully reach the word list.

Tags: , , , , , ,

4 Comments


What the b2World can teach you about C++ (and ActionScript, too)

I’m going to let you in on a secret. The Scriptocalypse banner at the time of this writing uses the Box2DFlashAS3 physics engine, a port of Erin Catto’s Box2D, written in C++. This is not the first time The Horseman has used Box2DFlashAS3. In fact, it’s one of those things that he learned to work with in the midst of a professional project “under the gun” as it were.

If you’ve never worked with a physics engine before, Box2D looks intimidating. To make matters ‘worse’ for an ActionScripter, the Box2DFlashAS3 port of the library breaks almost every standard ActionScript code convention. This made the task of parsing the library for comprehension a bit more difficult than other AS3 libraries I’ve encountered, though obviously it’s doable. Without knowing anything about the pedigree of the library, at first I wondered why the author chose to do this. I clued in fairly quickly after skimming the source code and finding references to “native” datatypes that Flash just doesn’t support (int32, anyone?) that had been commented out and re-written a line below with datatypes Flash recognizes. Box2DFlashAS3, as a port, is very much a “transliteration” of the library from its native code as opposed to a smooth “localization.” It would be like translating literally:

“Ik kom uit Amerika” -> “I come out America”

Instead of translating the general meaning…

“Ik kom uit Amerkia” -> “I’m from America”

Everything from the naming conventions, to the placement of the variables, to the slavish insistence on strictly defining the length of Arrays on instantiation, to the way you create instances of b2Body and b2Joint, to the ubiquity of the LinkedList structures used for iteration looked like it came straight from a different paradigm. The linked lists alone are peculiar in ActionScript. Virtually every physics body, shape definition, and joint is capable of containing a reference to a “next” and “previous” object of the same datatype, and almost nowhere are you as the user given an Array to sift via the API.

“Why would I want or need to explicitly declare Array lengths on instantiation? Why would I need to specifically create bodies and joints by calling the b2World rather than just instantiating them like I would do for a MovieClip object? Let’s read the user’s manual…”

From the manual:

C++ is great for encapsulation and polymorphism, but it’s not so great for API design. There are always significant trade-offs when creating a C++ library.

Should we use abstract factories or the pimpl idiom? These make the API look cleaner, but they ultimately get in the way of debugging and efficient development.

Should we use private data and friends as necessary? Perhaps, but eventually the number of friends can become ridiculous.

Should we just wrap the C++ code with a C-API? Perhaps, but this is extra work and may lead to internal choices that are non-optimal. Also, C-APIs are harder to debug and maintain. A C-API also breaks encapsulation.

For Box2D I have chosen the path of least resistance. For some cases a class is well contained in its design and function, so I use public functions and private data. For everything else I use classes or structs with all public members. These choices let me develop the code rapidly, it is easy to debug, and it creates minimal internal clutter while maintaining tight encapsulation. The downside is that you don’t see a clean, simple API. Of course, you have this nice manual to help you out. 🙂

Remember, the above excerpt is from the ActionScript-specific port of the manual!

Here’s some more:

Joint Factory

Joints are created and destroyed using the world factory methods. This brings up an old issue:

Caution

Don’t try to create a body or joint on the stack or on the heap using new or malloc. You must create and destroy bodies and joints using the create and destroy methods of the b2World class.

Heap? Malloc? In ActionScript?

Box2D doesn’t use reference counting. So if you destroy a body it is really gone. Accessing a pointer to a destroyed body has undefined behavior. In other words, your program will likely crash and burn. To help fix these problems, the debug build memory manager fills destroyed entities with FDFDFDFD. This can help find problems more easily in some cases.

If you destroy a Box2D entity, it is up to you to make sure you remove all references to the destroyed object. This is easy if you only have a single reference to the entity. If you have multiple references, you might consider implementing a handle class to wrap the raw pointer.

Often when using Box2D you will create and destroy many bodies, shapes, and joints. Managing these entities is somewhat automated by Box2D. If you destroy a body then all associated shapes and joints are automatically destroyed. This is called implicit destruction.

When you destroy a body, all its attached shapes, joints, and contacts are destroyed. This is called implicit destruction. Any body connected to one of those joints and/or contacts is woken. This process is usually convenient. However, you must be aware of one crucial issue:

Caution

When a body is destroyed, all shapes and joints attached to the body are automatically destroyed. You must nullify any pointers you have to those shapes and joints. Otherwise, your program will die horribly if you try to access or destroy those shapes or joints later.

Ahah! Any seasoned ActionScript developer should know and understand the concept of reference counting, as it’s a long-standing garbage collection technique used in the Flash Player (though the player now uses mark-and-sweep). But even though this documentation is clearly still “in another language” so to speak, things are definitely coming together here.

As pretty much anyone who’s done more than scratch the surface of Box2DFlashAS3 can tell you, trying to perform an action on a body or a joint that has either been destroyed or has “fallen out of the world” by leaving the confines of the AABB is asking for trouble. That manual is not kidding when it tells you to “nullify your pointers” when you destroy the object (or in ActionScript parlance, set your variable containing the b2Body/b2Joint = null) , and the more places in which you’re storing references to those bodies the more diligent you must be about cleaning up after yourself. The most disastrous behavior I found was calling b2World.DestroyBody() / DestroyJoint() on a body or joint that had already been destroyed. Completely threw off the internal count and broke all kinds of madness loose.

The paranoia about how you create and destroy the bodies and joints, and about Array length pre-definition is directly related to the fact that in straight C++ you are responsible for your own memory management and garbage collection. The implications of this are somewhat alien to the ActionScripter who has never worked with code in an unmanaged environment before, but become blindingly obvious when you have to handle it yourself.

Suddenly, the length to which you define your Array really, really matters! We’re a bit spoiled here in Flash-land with our dynamic-length Arrays. Those are more traditionally thought of as “Lists,” as they can grow or shrink in size on-the-fly at runtime. The worst that happens in ActionScript when you try to access an Array location that stores no data is that flash returns a literal datatype of “undefined”. In C++, may the Four Horsemen of the Scriptocalypse have mercy on your soul for daring to step off the end of an Array. This is why Box2D is so heavily reliant on Linked List structures when returning collections of bodies and joints. At least when you walk off the end of one of those, it can tell you explicitly what you’ve done rather than executing undefined behavior (which is a far different animal than returning a literal datatype defined as “undefined”).

So, what’s the point of all this rambling? I think what I found enlightening about my experience working with Box2DFlashAS3 was that it really gives you an appreciation for the care with which you must treat your resources. In our little world of managed code, we get away with a lot of things every time we compile a swf that just wouldn’t fly in C or C++. As a consequence, we can “afford” to be a little sloppy with our resources… but can we really afford it? Shouldn’t we always take care to implement a scheme for thorough destruction of all object references when they’re no longer needed? Isn’t it true that the more different places in which an object is stored, the harder this becomes?

Before snagging and holding onto a reference to an object whose life and death are somehow integral to the program, even in the highly managed world of ActionScript, maybe it’s a good idea to stop and ask yourself “Do I really need to store a reference to this object here? How much extra work will I create for myself when I have to destroy it? What harm will come when I fail to destroy it?

Tags: , , ,

No Comments