Thursday, January 3, 2008

Runnable demo on the web!

There is a live, runnable, ASiddur demo available via a Facebook application. It's running the somewhat old stable version without full-screen or reminder support. And the controls are a little more cumbersome that on most phones. But at least it's a start.

Sorry for those who want to use it but don't have Facebook accounts. If anyone can point me to a site that does this without a need to register, please let me know.

For all QR-code enabled devices out there, here's the link to the stable version:

ASiddur project still alive

Despite the appearances on the blog and on the project web page, I haven't given up working on ASiddur. I've mostly gotten through a very busy period at work, and in the meantime, added to the size of my family, both of which diverted my attention temporarily from the project.

In the short term, I'm going to concentrate on fixing a couple of small bugs (V'Sein Tal Umattar appearing a year early and some very minor text issues), and releasing a newer stable version with the reminder ticker and full-screen support.

Once that's done, I plan on writing some unit tests for the automatic test calculation code. (The reason that there aren't existing unit tests is that I could never seem to make it run for the J2ME parts of the project. But at least the encoding is done in J2SE and can be tested separately. There could easily be mistakes that I missed when looking at the hex dump of the resulting output.)

Thursday, April 5, 2007

Don't forget "V'Sein B'racha"!

I just found a bug in the reminder string (e.g. the ticker at the top of the screen), where it did not include "V'Sein B'racha". It is now fixed.

Sorry for the slow progress recently; work is still very busy. I'm still working, just slowly.

Tuesday, February 27, 2007

Cleaned up nikud (UPDATED)

Just a quick post to note that I cleaned up the nikud processing. On to figure out why the dynamic text block is getting truncated.

UPDATE: I also just fixed that bug. I was calculating the size of each block by subtracting the position of the previous block from the position of the current block. That does give the size, but the size of the previous block, not the current. Also, it can't work for the last block. Now the size is calculated when encountering the text block ending marker. Next up is to start actually parsing the text on the reading side, which may lead to some refactoring. Stay tuned.

Sunday, February 25, 2007

New plan for removing nikud

I have a new plan for implementing the option to remove nikud. I realize I've never even explained why this is necessary, so in the way of introduction, the tefilla text as I have them include nikud. Once I have other areas in better shape, I'd like to add nikud to the image-based fonts in ASiddur. I'm putting this off until later since many people are able to daaven without nikud, and trying to add nikud without making the text hard to read and also without cutting down too much on the amount of text visible on screen will be somewhat challenging.

As I've mention in the previous post, the existing code filters nikud out when reading it from a file. Since the whole tefilla is read into a buffer initially and just referenced, that works well. This limits the size of the buffer needed and means that filtering can be done just once (as opposed to every time text is shown). That also means that the text can be drawn all at once, especially when using native fonts.

However, that doesn't work very well with the dynamic text because the many features presume that they know the length of the text. For example, when printing out retzei, it is important to know how long ya'aleh v'yavo is. And if the code that reads it in removes nikud, that length will be incorrect.

Instead, my new plan is to handle all of the nikud removal right when the text is drawn. That really is cleaner if I ever switch to more of a Model-View-Controller or related pattern. The main drawback is that less of the tefilla will be buffered at a time, and that native fonts will take a performance hit, since the string will have to be drawn a letter at a time, rather than just passing the whole string to the drawString() function.

The implementation is pretty easy for the Image-based fonts. All that's needed is to create a small empty (or transparent) image, and to manually set the sizes to 0. For native fonts, the easiest is to deprecate the MidpFontAdapterStrategy and instead use the ImageFontStrategy, but let it fall through to the native font in all cases except for nikud, which would be set up as above. Now to get it coded...

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.