|
Post by chriscrawford on Sept 23, 2015 7:06:21 GMT -8
8:06 AM I have skipped entries in this diary for the last few days because I was stuck on a nasty problem. The repaint() method was not working. Nothing would draw in the Storyteller window. After much cogitation, I determined that the problem lay in the architecture of the program. There are four major classes that interact: 1. SWAT. The outermost class, which handles everything: the editors, the FrontEnd, etc. 2. FrontEnd. This displays the output to the player. It owns the Engine. 3. Engine. This runs the storyworld. It owns FrogLizard. 4. FrogLizard. This keeps the data on the operation of the Engine.
This structure is the one that works. Earlier, the ownership of the various classes was rather snarled up, and so various objects ended up calling themselves. This screwup was the result of the evolution of the code; the architecture was modified so many times that I never noticed the absurd ownership hierarchy. But it's fixed now.
So now I can return to the task of getting LogLizard functioning. Right now I am attempting to reincarnate the tree structure that Facundo set up, which holds all the steps taken by the Engine. This is tricky, because his code includes lots of client-server stuff that I must eliminate without damaging the underlying tree data structure. I expect this to be a messy, time-consuming, bug-prone business.
|
|
|
Post by chriscrawford on Sept 23, 2015 8:11:21 GMT -8
9:01 AM Here's a good example of the kind of thing I have to wade through. At one point in the code, it needs to obtain the index of an element of a tree. It does so with this line of code:
int treeIndex=logManager.getTreeModel().getIndexOfChild(logManager.getTreeModel().getRoot(),tp.getPathComponent(1));
Fair enough. Let's go see the reference in logManager:
public LogTreeModel getTreeModel(){ return treeModel; }
Just a standard getter. Good. Let's move on to this method "getIndexOfChild" in class LogTreeModel:
public int getIndexOfChild(Object parent, Object child) { if (!(child instanceof Node)) return -1; Node nc = (Node)child; if (parent instanceof Node) return Utils.indexOf(((Node)parent).children,nc.id); else // the log processor thread may be writing // the rootChildren array synchronized (rootChildren) { return rootChildren.indexOf(nc.id); } }
This is a bit hairier. First it checks for the case where the input is of the wrong type. Of course, the calling line of code (the first code block above) insures that it's the correct type, but Facundo is a careful programmer; he doesn't know if a future programmer might screw things up. Me, I'm not so careful. If any future programmer screws it up, he can go to hell.
Next he checks to confirm that "parent" is an instance of "Node". Same story: very, very careful. Probably necessary because this is client-server code that faces special difficulties, But for me, it's "Damn the bugs! Full speed ahead!"
At last we get to the one bit of code that actually does something: the one that calls Utils.indexOf. Let's look at that:
public static int indexOf(int[] a,int e){ for(int i=0;i<a.length;i++) if (a[i]==e) return i; return -1; }
All this does is sweep through an array looking for a match. Trivially simple. But why go through all the circumlocutions to do a simple array search? I know, I know: an abundance of caution. But I see no need for all that caution in the new, single-machine version of Siboot, so I'm going to bypass all those middlemen and just put the loop search right into the original code.
This is what I spend most of my time doing: figuring out complicated code written to deal with the complexities of client-server situations, in which the server might not respond to the client's request for a little while. Once I've figured it out, I have to strip out all the client-server checks, double-checks, and triple-checks to get the short bit of code that actually performs the desired function.
|
|