Tuesday, April 19, 2011

C++ doesn't help!

I really feel the lack of any "package" protection level in C++. Every significant new piece of software triggers some hide-and-seek problems that must be solved before the code can actually get written. Something like saving animations and re-loading them, for instance.

I struggled with "how I could share the animation data so that AnimWindow doesn't have to know the details of writing to files, but that FileWindow doesn't need to know the details of animations structures... Then came the ghosts of deep object copy and reference counting bats (they are quite frequent in the caves of poor design).

Curieux, non ? Dans la petite "todo list" basée sur les premiers essais sur DS, aucune mention de "sauver l'animation créée" ... C'est pourtant la fonctionnalité primaire qui manquait encore et qui devait recevoir la priorité. C'est qu'à nouveau, on touche à "qui peut manipuler quoi" dans le programme, et le C++ n'aide vraiment pas dans ce domaine-là. Par moment, j'en viens à regretter la "visibilité par package" du Java. C'est dire!

Hopefully, a light sparkled in the darkness: I needed animation data to be shared by the two windows, but that didn't mean the objects must be accessed by the two. The animation being edited can remain held in AnimWindow::tlist and AnimWindow::anim, as the other components won't edit frames or timeline. And that allowed me to apply the coding practice that works the best for me: interfaces. All I need is that AnimWindow offers a iAnimHolder to the rest of the software. That interface serialise the current animation into a vector of information with the only constraint that it must be easy to reconstruct the editable object. pfew.

From that point on, things went better: it was a mere matter of mimmicking the Scream Tracker's approach to pattern compression: if value is repeated, don't repeat it. Bare "unsigned" encoding command-class, command (e.g. move limb, delay, change sprite ...), object identifier (which limb, usually) and leaving 16 bits for the actual data (number of frames to wait, sprite reference or pair of coordinates relative to the "center" of the frame editor) was enough. And they could naturally be packed into an large DataBlock before being pushed to a .spr file.

Heureusement, à force d'accumuler les tentatives UML, j'ai fini par constater que les besoins de AnimWindow::tlist ne sont pas similaires à ceux de ThumbsWindow et FileWindow: seul l'AnimWindow doit manipuler les animations en tant qu'objet. Pour le reste, il me suffira de "stocker" les animations pour pouvoir les resservir plus tard. En somme, il suffit que l'AnimWindow offre une interface de sérialisation/désérialisation et rien de plus.

Comme la sauvegarde et le chargement de fichiers .spr prévoyait déjà la possibilité de manipuler des blocs "de données inconnues", le reste n'était que pure formalité: voilà donc AnimEds capable de sauver et recharger une animation. Encore quelques widgets et on pourra en manipuler autant qu'on veut et passer de l'une à l'autre comme s'il s'agissait de simples sprites.

Oh, btw, if you missed the post "animation editor 0.1", it has been translated earlier today.

No comments: