Well well well. It sure has been a long time.
Today i have released a new and improved experimental version 0.3.90 (yup, that means pre-0.4), codenamed "Threadless". Why? Well, it's not because it makes t-shirts. It's because it doesn't use threads. Not too much of them, anyway.
Before this release, OpenWIG relied on threads for event synchronization. Whenever I needed to call an event handler, I spawned a thread that would perform the Lua code and die. Which is all good and nice, but can bring a lot of trouble. For one, when you use many threads, you need to care about (dead)locking. For two, some j2me implementations are somewhat inferior to the rest *cough*Symbian*cough*. Their garbage collection is simply not good enough. So it's better not to create too many objects, if you know what i mean.
Also, for the same reason, there is now a pre-allocated instance of each of the screen types (like "item details", "zone navigation", "dialog" etc.) and no new screens are created.
Oh, and screen switching is now stateless. That means that each screen knows in advance which screens can follow it. And that's cool! Lots of problems with screen refreshing disappeared this way.
And lot of them appeared. Oh well, for every bug you fix, three new are born.
In other news, we now have the latest and greatest Kahlua revision, which means that we support more obscure code. Inventories and AllZObjects are now accessible from Lua as tables. And some minor thingies, i don't remember exactly.
Anyway, the new version is very cool and you should all download it.
May 19, 2009
December 11, 2008
how to send JAR files to a Nokia from linux
Just so i don't forget next time.
- install gammu
- create a .gammurc:
[gammu]
# your phone BT address:
port=00:02:5B:00:A5:A5
connection=bluephonet cd /directory/with/jar/and/jad
gammu --nokiaaddfile Application NameOfJarWithoutExtension
December 5, 2008
internal affairs filed under JSR179
OpenWIG 0.3.07 is out and it supports JSR-179 style "Location Providers" a.k.a. internal GPS.
Getting that to work was no picnic, though.
Here's a basic overview of how it's supposed to work:
Well, yes, but with a caveat: there's no listProviders or equivalent method. If the phone has more than one provider, it can return pretty much anything it wants.
And it turns out that e.g. Nokia N95 has more than one provider, and one of them is very dumb and coincidentally that's the one that is selected when you specify "empty" criteria (the default Criteria instance means basically "anything will do")
It seems to work when you say that you want to get speed, course, altitude and you allow it to cost money:
Getting that to work was no picnic, though.
Here's a basic overview of how it's supposed to work:
- choose a list of things you want from your GPS device and set it all up in a Criteria object
- instantiate a LocationProvider by calling LocationProvider.getInstance(myCriteriaObject);
- periodically ask for a new location by calling provider.getLocation(timeout)
- or implement a LocationListener interface, and register that with the provider. You can then specify some refresh intervals and timeouts and whatnot. Fortunately, you can also leave it on default values.
Well, yes, but with a caveat: there's no listProviders or equivalent method. If the phone has more than one provider, it can return pretty much anything it wants.
And it turns out that e.g. Nokia N95 has more than one provider, and one of them is very dumb and coincidentally that's the one that is selected when you specify "empty" criteria (the default Criteria instance means basically "anything will do")
It seems to work when you say that you want to get speed, course, altitude and you allow it to cost money:
Criteria c = new Criteria();Oh and then there's the fun with invalid locations that can either have isValid flag set to false or be null. But that is easy to get right. Finding out that a phone is giving you a bad provider is the real pain.
c.setAltitudeRequired(true);
c.setSpeedAndCourseRequired(true);
c.setCostAllowed(true);
provider = LocationProvider.getInstance(c);
November 24, 2008
what's cooking
Version 0.3.07, that's what. It will have all bugs from the previous post fixed, and its navigation arrow will be prettier and move smoother and just be plain old sexy.
Oh, and internal GPS's will be supported!
It will be ready sometime this week.
For the version after that, I intend to try and dig a bit into saving and loading. It won't be perfect, but maybe, just maybe, it will work well enough for most cartridges.
sidenote: there is a midlet called "OpenWIG-blackmagic" sitting silently in my phone. it has all kinds of very evil features that should never have been born. muhahahaa!
sidenote2: The name "OpenWIG" sucks. I need to come up with a different one.
Oh, and internal GPS's will be supported!
It will be ready sometime this week.
For the version after that, I intend to try and dig a bit into saving and loading. It won't be perfect, but maybe, just maybe, it will work well enough for most cartridges.
sidenote: there is a midlet called "OpenWIG-blackmagic" sitting silently in my phone. it has all kinds of very evil features that should never have been born. muhahahaa!
sidenote2: The name "OpenWIG" sucks. I need to come up with a different one.
fun bits
a.k.a. OpenWIG bugs worth mentioning, and their respective cartridges
Srnčí důl:
the official Players call "OnSet*" before performing the setting. I.e., when you set task.Complete = true, then the player first calls OnSetComplete and only after that actually sets the variable.
The OnSetComplete event in Srnčí důl (Roedeer deep), for some wicked reason, checks for this behavior: if task.Complete == false then (do stuff) So if at the moment of calling OnSetComplete, it's already Complete, there be failurez.
Blair Witch:
so I took the latest and greatest version and headed out, to try and play this cartridge, which is probably best one in CZ, and also the most complex one. So it was kind of baptism of fire for OpenWIG. Plus, this time, i was a member of a group equipped with Colorados, so i could check the behavior against the "right" one.
Found two bugs. In one, i could see all my virtual companions long after we left them behind in a dead zone. The other, at first i didn't think that it's a bug. I just completed a simple task ... then all the coloradists spent half hour trying to complete the very same task and failing spectacularly.
Both bugs were rather easy to find and remove.
First one: when a zone deactivates, it stops evaluating position events. That means that if you deactivate a zone in which you stand, as far as OpenWIG is concerned, you'll stand there till the end of days. Because it will never again check if you are inside or not. It just remembers the last state.
Fixed by forcefully removing a player from a deactivated zone.
Second: in the mentioned task, you have to carry an object outside of an invisible zone that envelopes the visible zone in which you start.
The respective event asks if invisibleZone:Contains(Player). Welll..... Yes, if the zones overlap, the player can be in more than one zone at once. That works fine. But when doing that, I apparently overlooked something: it doesn't go the other way around. Player is in multiple zones, but only one zone Contains() the player. So when i was in the inner visible zone, the event never found out that i was also in the invisible zone, and let me throw the task object away without hassle.
Fix was fairly trivial, i just needed to override zone's Contains method... ah, why would i write all this, you can figure it out.
...and for a time, it was good...
Petřínská Wherigovka:
This cartridge also has that habit of deactivating zones that you stand in. But it turns out that when fixing the problem from Blair Witch, i overlooked something again.
There are two internal states for a zone: contain says whether you are present in (close to, distant from) the zone, and ncontain aka "next contain" says whether you are going to be present in the zone in the next five seconds, unless something happens. So most of the time it's the same as contain.
When "forcefully removing" the player, i reset the value of contain, but not ncontain. In the next timestep, zone realized that the player is going to be inside it real soon, and invoked the OnEnter event.
Which had a rather lengthy dialog. Which ended in a question. Which, if answered correctly, would deactivate the zone. Which would lead to another OnEnter... you see where this is heading.
Also i found out that even when the zone is inactive, quite a lot is going on in it.
So i put a stop to it, and that's the end of this nasty little bug.
...or is it?
Srnčí důl:
the official Players call "OnSet*" before performing the setting. I.e., when you set task.Complete = true, then the player first calls OnSetComplete and only after that actually sets the variable.
The OnSetComplete event in Srnčí důl (Roedeer deep), for some wicked reason, checks for this behavior: if task.Complete == false then (do stuff) So if at the moment of calling OnSetComplete, it's already Complete, there be failurez.
Blair Witch:
so I took the latest and greatest version and headed out, to try and play this cartridge, which is probably best one in CZ, and also the most complex one. So it was kind of baptism of fire for OpenWIG. Plus, this time, i was a member of a group equipped with Colorados, so i could check the behavior against the "right" one.
Found two bugs. In one, i could see all my virtual companions long after we left them behind in a dead zone. The other, at first i didn't think that it's a bug. I just completed a simple task ... then all the coloradists spent half hour trying to complete the very same task and failing spectacularly.
Both bugs were rather easy to find and remove.
First one: when a zone deactivates, it stops evaluating position events. That means that if you deactivate a zone in which you stand, as far as OpenWIG is concerned, you'll stand there till the end of days. Because it will never again check if you are inside or not. It just remembers the last state.
Fixed by forcefully removing a player from a deactivated zone.
Second: in the mentioned task, you have to carry an object outside of an invisible zone that envelopes the visible zone in which you start.
The respective event asks if invisibleZone:Contains(Player). Welll..... Yes, if the zones overlap, the player can be in more than one zone at once. That works fine. But when doing that, I apparently overlooked something: it doesn't go the other way around. Player is in multiple zones, but only one zone Contains() the player. So when i was in the inner visible zone, the event never found out that i was also in the invisible zone, and let me throw the task object away without hassle.
Fix was fairly trivial, i just needed to override zone's Contains method... ah, why would i write all this, you can figure it out.
...and for a time, it was good...
Petřínská Wherigovka:
This cartridge also has that habit of deactivating zones that you stand in. But it turns out that when fixing the problem from Blair Witch, i overlooked something again.
There are two internal states for a zone: contain says whether you are present in (close to, distant from) the zone, and ncontain aka "next contain" says whether you are going to be present in the zone in the next five seconds, unless something happens. So most of the time it's the same as contain.
When "forcefully removing" the player, i reset the value of contain, but not ncontain. In the next timestep, zone realized that the player is going to be inside it real soon, and invoked the OnEnter event.
Which had a rather lengthy dialog. Which ended in a question. Which, if answered correctly, would deactivate the zone. Which would lead to another OnEnter... you see where this is heading.
Also i found out that even when the zone is inactive, quite a lot is going on in it.
So i put a stop to it, and that's the end of this nasty little bug.
...or is it?
November 3, 2008
OpenWIG 0.3 beta
Released this night. Head over to the openWIG project page and get it (link is on the right side).
It has its own functional file browser, and a pretty preferences screen. It mostly looks the way i described it a while ago.
No big changes on the player side of things, though, only some minor bugfixes.
Caveats:
It has its own functional file browser, and a pretty preferences screen. It mostly looks the way i described it a while ago.
No big changes on the player side of things, though, only some minor bugfixes.
Caveats:
- It's a beta and i didn't really test it (mostly because of the emulator stuff mentioned in last post). It just might be that it is severely broken in some stupid way and unfit for general use.
- It can no longer load files from JAR archive. That functionality might be restored, but as of now, i don't see any reason to do that.
testing FileConnection with the J2ME emulator
...is difficult at best, and impossible most of the time.
UPDATE: ...CAN be very easy, IF you "specify the security domain" in NetBeans (and choose Manufacturer, for best results). All the problems mentioned below disappear, because the emulator stops asking questions. But if you want to test behavior on regular phone with no rights, you'll have to test on an actual phone - read on.
one: unlike most (if not all) phones, the emulator runs confirmation windows in the same thread as commandActions.
That means that if you try to do anything file-related from a commandAction, a security confirmation pops up and you can't dismiss it, because your command thread is (dead)locked waiting for the result of this confirmation.
Oh well, I made my file browser run the file commands in a background thread.
two: unlike all phones, the emulator wants a security confirmation for each and every method call on the FileConnection object. And it does not remember permissions. Therefore, listing a directory takes three confirmation clicks, and every time you want to re-read a file, another confirmation (which is likely to deadlock you, for reason one).
three: the emulator (at least version 2.5.2 in linux) creates a brand new tree structure for each run. And it appears that you can't choose what will appear in that structure. So if you want to test opening a specific file, you have to copy it into the proper location every time.
(although i remember that it behaved slightly differently on my notebook. i'll have to check that out too)
and all's good when the end's good, four: do not ever in your life try to "mount" parts of your filesystem into the emulator by linking them to the temporary filesystem root.
Upon exiting, the emulator happily descended into my directory and recursively deleted it. Fortunately, there wasn't anything irreplaceable, or i haven't noticed yet; but i lost a good hour of work.
Good to know, though, is that there is now a way to undelete files from an ext3 filesystem. Didn't help me, though; the software insisted on segfaulting. It's apparently a known problem with "large partitions on some 32bit systems".
UPDATE: ...CAN be very easy, IF you "specify the security domain" in NetBeans (and choose Manufacturer, for best results). All the problems mentioned below disappear, because the emulator stops asking questions. But if you want to test behavior on regular phone with no rights, you'll have to test on an actual phone - read on.
one: unlike most (if not all) phones, the emulator runs confirmation windows in the same thread as commandActions.
That means that if you try to do anything file-related from a commandAction, a security confirmation pops up and you can't dismiss it, because your command thread is (dead)locked waiting for the result of this confirmation.
Oh well, I made my file browser run the file commands in a background thread.
two: unlike all phones, the emulator wants a security confirmation for each and every method call on the FileConnection object. And it does not remember permissions. Therefore, listing a directory takes three confirmation clicks, and every time you want to re-read a file, another confirmation (which is likely to deadlock you, for reason one).
three: the emulator (at least version 2.5.2 in linux) creates a brand new tree structure for each run. And it appears that you can't choose what will appear in that structure. So if you want to test opening a specific file, you have to copy it into the proper location every time.
(although i remember that it behaved slightly differently on my notebook. i'll have to check that out too)
and all's good when the end's good, four: do not ever in your life try to "mount" parts of your filesystem into the emulator by linking them to the temporary filesystem root.
Upon exiting, the emulator happily descended into my directory and recursively deleted it. Fortunately, there wasn't anything irreplaceable, or i haven't noticed yet; but i lost a good hour of work.
Good to know, though, is that there is now a way to undelete files from an ext3 filesystem. Didn't help me, though; the software insisted on segfaulting. It's apparently a known problem with "large partitions on some 32bit systems".
Subscribe to:
Posts (Atom)