Monday, January 29, 2007

Java primitive data types

First, I have to apologize for the slow pace recently, but I've been busy at work. This situation will likely continue for another few months, but I'll do my best to progress. (Of course, by the time this is over, I'm sure something else will be competing for time, but that's life for you.) It's a little frustrating to have lots of ideas and (what at least appear at the time to be) clean designs, but not have the time to actually get them down and make them work. Well, I'll do what I can. In the meantime, back to griping about Java and explaining what I've been up to...

Just what does Java have against unsigned data types, anyway? I just finished debugging a problem that was caused by my assuming that a byte was unsigned. After all, if you're specifically choosing your data type to be a physical item, wouldn't you want it unsigned anyway? (A byte is defined in terms of the size, as opposed to int or character, where the type represents a logical item.) Well, that at least made sense to me before I wrote the code. Now I have to take each byte, and deal with casting it to a char, and then or'ing it with 0x00FF just to keep it positive. Ugh. There's gotta be a better way.

The upshot of this is that I can now see the (beginning of the) first block of a tefilla in the daavening view. Check out the dynamic Ma'ariv (last on the list). The only remaining major issue (other than actually parsing the markup to select tefillah text and include other blocks as needed) is to remove the nikud(*). In the current (e.g. legacy) setup, it was done when the file was read in, for efficiency reasons - you only need to do it once, and not every time text is shown. That doesn't work in the new model, since that will affect the distance to other characters and throw off things like if/then/else block lengths. On the other hand, I'd rather not have to
pull it out each time a line is shown. And in any case, that will be slower, and storing the extra (unneeded) characters/nikud means needing about 30% more buffer room.

(*) This was true when the post was originally written, but I've since noticed that the entire block doesn't come through. I'll be looking into that.

I don't yet have a good answer to this; at the moment, processing is done when reading in the block to transform all unwanted nikud into null bytes, which are later pulled out. But now I do twice as much work as before, so that's not a good long-term solution. But right now, I at least want to get something out that works, and then clean it up. I don't know why only part of the text block is coming through; I'll have to investigate that later. Native fonts with nikud not shown is probably broken at this point (since my emulator doesn't have native Hebrew fonts, I'm not yet testing that functionality). And I know that it is very incomplete, so don't bother filing bugs for it quite yet.

Sunday, January 14, 2007

Heisenbugs

I'm experimenting with writing a blog on ASiddur development. We'll see if this works as a method to communicate what's been going on.

I finally tracked down a bug in the latest development version that I put off looking at, since everything appeared to work correctly. All that I saw was a NullPointerException with a short stack trace in the output when I would run in the simulator, but everything appeared to still work correctly. So I figured that I could put off looking at it until I was getting closer to releasing version 0.3. Then I got reports that people were unable to actually run the latest version, so I decided to look at it more closely.

I fired up the debugger, setting it to catch any NullPointerException. After wading through the ones that were thrown and caught by design (e.g. the font images that are not supplied), I eventually got to the point where the main form came up, but no NullPointerException was being thrown. Given that the all the code did throw the exception was either platform code or code that's been around for a long time, I didn't think that was the problem. I'd found ASiddur's first Heisenbug. After adding some print statements and commenting large blocks of code, I finally traced the occurrence of the bug to the following line:

getDisplay().setCurrent(get_MainForm());


This line runs at the end of the initialization sequence, and switched the displayed item from being the splash screen/progress indication to the main form. Oddly enough, commenting out the line had no effect - I'd expected the main form to not show up at all, but it did anyway. Reading the documentation further, it appears that an newly-created Alert (the type of the splash screen) has a default timeout. So the code that I added to read in and begin to process a binary-format tefilla file made things take long enough that the default timeout was triggered. Even so, from reading the documentation of the setCurrent() method, a null argument (which it wasn't) is allowed (although it would have meant that ASiddur requested to be paused). And you're also allowed to call setCurrent with the currently displayed item (which would mean a request to come out of the background). So I have no idea why the call caused the NullPointerException, and much as I'm loath in general to blame the platform, I think that it was a bug in kvm. In any case, the workaround (to explicitly set the timeout of the splash screen Alert to FOREVER) is certainly correct code, so I'll leave it in and hope that it fixes the problem everywhere.