Thursday, April 30, 2009

Cocoa Bindings and CALayer

Well, specifically I don't know if this is an issue with Core Animation layers or I'm doing something stupid. What I'm doing is programmatically binding a CALayer to a managed object with a particular key path. The problem occurs when I destroy that layer. It causes the program to crash. This is due to the a value of the object being updated (incremented skill points) and as a result it sends KVO messages to all listening objects. The CALayer never got unbound and thus a message is sent to a deleted object.

Well, I figured the simple fix is an unbind: call. At least I thought it was. The app still crashes.

I'm not sure what I'm going to do. My first guess will be to apply bindings via a NSObjectController I programatically create.

In any case, I'll hopefully finish the skill browser this weekend and start focusing work on the skill plan next week.

Wednesday, April 29, 2009

Graph Algorithm

Since I did spend more than a day on thinking about this one, I guess it's worth posting. Here's how it works:

You have 5 "levels", essentially the depth of the deepest tree in the game. Each of these have a value that indicates how far from the top do you go down before drawing a node. We'll call it the height for the sake of clarity. If a call is made to increment a level x (x being 1 through 5), a call is made to all levels greater than x. This call checks the value of the called level and compares it to the value of level x. If theirs is smaller than level x, it is set to the value of level x. Level 1 starts at the way left and level 5 is at the far right.

The first thing that gets passed in to the main recursive function is the root node.

To start, the recursive function checks to see if the node is a leaf, i.e. doesn't have any child nodes. If it is, it calls a drawing method that returns the drawing. It then increments the height of the level by the standard height of the drawing. Finally, the drawing gets returned.

If the the parent node (not necessarily the root node) does have child nodes, they first get sorted by their depth. An empty array is also created. Then, a call is made to the main recursive function for each of the child nodes. The drawings that are returned are added to the array. When all the children have been cycled through the height of the level first gets set to that of its first child's level height plus halfway the distance between the first child node and the last one. This will caused the parent node to be drawn right in the middle of its child nodes, height-wise. A call is made to draw the parent node. The array of child node drawings are then cycled through and lines between them and the parent node are drawn. Finally, the drawing of the parent node gets returned.

This method requires no recursion to make "adjustments" for over-lapping. It's a one-shot passthrough. It can be somewhat optimized to run a bit more efficiently but as these graphs aren't terribly big, there wouldn't be any noticeable time savings. I hope my explanation is clear and if anyone wants me to clarify any of it, just post a comment.

Tuesday, April 28, 2009

Core Animation!


Yes, I'm aware that this app doesn't have a real need for animation nor do intend to utilize any. Core Animation does have two great advantages for me: it's fast and it's easy (relatively speaking). It's been about a year since I even looked at CA so I spent much of my day doing some catching up on the basics.

The screenshot posted is more or less a skeleton of where I am now. I do plan on doing left to right tree growth. The size, color and content of the boxes will all definitely change but, after hours of fidgeting around with math, the box positioning looks right. I'm still trying to figure out how CATransform3DRotate works and getting the connecting lines' angles right. One big concern, though, is the size of the view. Currently, its static (and too big, for that matter). Ideally, it should be adjusted to the size of the tree to eliminate unnecessary scroll bars if the tree fits inside the view.

Monday, April 27, 2009

Still Working


I did laugh a bit a little when I saw this compiler error.

In any case, I haven't posted something to my blog in a while. I would have posted my tree drawing algorithm that I came up with but I'm sure it would bore people. But, just so people know, I am working on the skill planner with decent progress. I'm going to submit it when I have a decent tree display working.

Wednesday, April 22, 2009

Project Update

My latest submission is pretty big. Before you compile and run it, make sure you delete your database store as it will be rendered incompatible. Kind of reminds me that I need to start maintaining a change log.

There will come a point where the program will be a release version. Asking everyone to delete their database store (or having the program do it by itself) is simply unreasonable. I know Core Data has a migration manager, but it's pretty limited. Doing migration the old 10.4 way makes you wish you had more than one brain to pull a gun's trigger on. Believe me, I've been there. I think the path I'll end up taking is to have everything be stored in a preference file. I'll then simply parse in the data into the new store.




Skill Planner User Interface

To be honest, this is something I'm struggling with. Part of the reason I haven't submitted anything to the repository yet. I don't like EVEMon's interface. It's very, how should I say it... Windows-y? Buttons look ugly; The arrangement feels very out of place; The idea of being able to view the ship/item browser only if you create a new plan seems awkward; There's way more information on the screen then what's really practical. However, it works and in doing so I think it allows your the actual skill plan be arranged in a manner that the player really prefers.

So that's my challenge: try to come up with an interface as practical as EVEMon's and at the same time make it look clean and organized.

Tuesday, April 21, 2009

Skill planner and 10.5

I spent some of my time last night rewriting my code over to be more 10.5-ish. This included things like the @property and @synthesize stuff (forgetting the name) and fast enumeration. I've also noticed that Core Data behaves somewhat differently under Leopard. For example, transient attributes that weren't optional didn't require being set. Not the case anymore. Also, I may be wrong on this one but I don't recall being able to make relationships with abstract entities.

Getting back to The skill planner, I'm getting steady progress with it. However, I have taken advantage of BWToolkit, an interface builder palette with a slew of really useful elements. I've ran into this situation before of trying to include external frameworks into the resources directory and linking it. It's a very unintuitive way of doing it. So, for now, any releases will require that you put the framework into your /Library/Frameworks/ directory (notice there's no ~ for the home directory). It's something that'll definitely be fixed.