Framework Code Builder
So I haven’t been posting as much but I’ve made significant progress. I’ve been able to complete most of the document events. I’ve started to essentially look through the code design and clean up a couple elements there, I added a couple more messages that I wanted to broadcast that I think would be helpful as I move along in the development. Document and document management is nearly complete though, I need to add all the NSCoder elements but I’m fairly happy with how everything is going there. From the standpoint of working on the project you can basically add all your objects save your file off and work on again after your coffee break (kinda an expectation with any program).
I’ve moved onto the code building process and properties editor. Essentially everything is tied together now from the application perspective, now it’s time to be able to edit the actual fields that will influence the final results within cocos2d. The plist file is about halfway hashed out, about far enough to complete most bodies, with joints happening next. I’m able to load the framework properties. What’s going on behind the scenes, aka the way I’ve coupled it is I’ve defined a protocol for generic information I’d need a framework and 2dphysicsobjects. User selects a framework to work with, framework manager instance manages the framework (holds a reference) to the framework. User selects a generic object type they want to create, framework manager delegates that work to the actual framework, the actual framework creates the physics instance of that object. Backtracking a little bit, the framework on initialization will load the metadata for the entire real framework. Now after objects are created by the framework, the framework can ask what real classes within the framework is it associated to. The cool part is that each physics object implements a responder method that lists by classnames the parent type it’s associated to. Based on that parent class it will build out all the associative properties and hold a reference. Now when I expand my properties window I can see all the real properties based on framework that my object is associated to.
Also as part of the coding I’m making sure to be KVO compliant, when I observe a change that would result in a rendering difference within the object I update the objects render properties (yes, separated that way I’m not coupling the framework and the renderable object together).
So in a list format
- Document management, 80% complete
- Application state (save, load, etc…) need to tackle next
- Framework loader (25%, need to finish properties list of half box2d and entire chipmunk api)
- Code Building, groundwork in place to start generating code
NSarraycontroller
Document model and the front end are more or less completed. I’m happy with the results. As users add physics groups and physics objects I’m able to update the document model first and broadcast a notification that the document has been updated. Additionally the notification drives an update to the treeoutlineview which is visually rendering the structure. Extreemly happy about all this.
Next challenge I’ve been tackling is the render buffer array. Essentially I’ve decoupled the render tree from the document. This provides a benefit in that I can maintain objects in multiple states more easily, namely view or invisible. Viewing from a render array allows me to quickly draw what’s needed without inspecting every element and requesting whether or not they need to be rendered.
I was able to get some great tips on apples developer forums for using an nsarraycontroller for this type of caching and then key value observing for property changes to force rendering. Very great ideas which I will try and have implemented tommorow.
Updates still coming
*Sorry for the delays, this will be a short blog. I’ve been caught up unfortunantely with a seperate vendor project but back on track with this one.
Updates for the project include
- Continual work on the document model
- Additional notifications provided on document changes. Basically things are getting cleaned up and decoupled.
- Found a bug where the document model tree and view tree were out of sync. It was causing weird crashes once in a blue moon.
Continual work being made on this project, hopefully back on track now. I will probably begin dragging my laptop along throughout my day and coding more throughout the day to play catchup.
Group management
Sorry for the long delay in updating, I’ve taken some time to think about my plan of attack and also I’ve been delayed with some issues at work. None the less, I’ve progressed on the document model. For the sake of simplicity of rendering I had to modify the NSTreeController – Document model contract. Essentially although I can update the document model via notifications, it didn’t make sense for the update. Inversely it does make sense to update everyone downstream that the document has been updated. One of the issues I ran into was how I would handle grouping. From a code perspective I could not find a good argument for creating n-sublayered groups meaning I can’t see a good reason yet for exporting groups within groups yet. On a future release I’d like to support it but at the moment I need to research a better way of tieing the NSTreeController contents and Document Group array together without deep nesting conditionals because it will present significant issues on preview rendering and also code generation (I can’t force box2d to respect groups farther than 1 level).
That being said, sorry but I will have to force users to create 1 level groups for objects. If it doesn’t make sense what I’m talking about I’m referring to objects that contain multiple parts that you’d like to logically group together. I can generate a class that respects all these parts as being a unit, so they are generated on screen at the same time for referencing etc…. The problem is, I can’t necessarily infer that they are joined and I can’t necessarily force box2d to call downstream creation of objects at compile time based on subgrouping. The only thing I can force is a subgroup to generate all it’s subgroup dependencies at the same time that the first layer is initialized. For this reason it makes no sense to have a subgroup of a subgroup.
None the less, document model seems to be cleaned up, NSTreeController is cleaned up. They both understand their relationship. I will work on adding NSTreeNode support (right now they use the generic BaseNode and ChildNode from Apple examples). Once thats complete I will be ready to move back to rendering. I’ve found that NSArray can make callouts to all objects in an array to perform a selector. This works great as it will simplify my code. I will go back and add that. Then I should be able to push past and begin working on property views. Sorry for the delay everyone!
Symmetric Tree Management
I realized today that NSIndexPath is just what it says, an index path. Keeping that in mind I was able to overcome the obstacle of managing the object hierarchy within the document model and the nstreecontroller symetrically. Now both the view and document model match up verbatim which is very nice. Allows me to do some great things in terms of object grouping. I know I mentioned that I would possibly have a full end to end test possibly by the end of this week but rest reassured that these tweaks are essential. If I’m not accurately managing the view hiearchy I can’t accurately render things. At the end of the day once the IDE is done all I’m looking at is the model to generate the c++ code. If the document model isn’t an accurate representation of the exact user intentions then it will be difficult to manage generating the code. Now that I’ve essentially completed the insert calls I will manage the removal and retrieval (smaller code amount + copy and paste is my friend).
Great thing to note for anyone out there looking at examples for NSTreeController or NSIndexPath, please remember to take the examples with a grain of salt. Objective-C 2.0 introduced try-catch-finally blocks.
@try {
}
@catch (NSException *e )
{
}
@finally
{
}
These are your friends, like KVC you can much more quickly code and reduce the amount of lines of code. Check the Developer docs, most framework classes and their corresponding critical methods raise exception types that can be caught rather than the traditional strict checks. Can it be abused? Yes, like anything else it can. However, when I know that things such as the tree and document are kept in sync catching a bounds exception vs actively checking will cost me significantly less. It’s a good tradeoff. Check less for conditions that are nearly impossible unless data integrity problems arise. Unlike java or many other languages Objective C does not enforce receiver methods to catch exception types, it will automatically log out that an exception was raised on the receiver. It is up to the receiver to choose to subscribe (I love that objective c method calls are messages and not direct calls). If I remember my gcc compiler though, these advanced directives will cost you some in compiler complexity and footprint and are well worth it (iOs programming is different story, static library + dynamic linking from try-catch blocks or synchronized == very bad, will not compile and will throw obfuscated messages)
Apparently NSTreeController and NSDocument have a mutually exclusive relationship. For now I’ve created my notifications of when the document model is updated. For some reason I was thinking I could directly modify the underlying contents array and all would be good but that has a nasty effect. It clears the outline view and reinitializes it. Ideally I need to move the document model to use an NSIndexPath for the underlying array. If I can do that the trees would be symmetrically represented (they are not copies of each other nor are they even references of the same object).
Screen shot below shows though, grouping is working, model rendering is working, model interactions are working but aren’t displayed (hard to capture without a video).
So why is my application group centric? Creation speed of objects, it provides a hint that these physics models represent some logical division. Do you need to use groups? No. However if you don’t use groups there will be a performance penalty since everything will be added to the default group and the code generated will assume all these objects are required for allocation at once. Additionally groups will provide ease of access. An example would be a complex model such as a bridge. It’s comprised of multiple distance joints and bodies. Without a group I’d be stuck trying to fetch each object by some unique id for each joint and body. With a group I can specify the group name and iterate through each object (joint or body).
Model management
One of the interesting things about this project is learning and adapting. I’ve created a loose project plan, objectives, and mapped features together. Similarly my document model (which provides all project information and objects) provides a guide for all onscreen information.
Given it’s importance I thought it’d be a good time to revisit it. Speed and convenience being the two major factors. Size isn’t as much a factor since honestly by the time it was time to consider storage size it would likely not render properly as far as physics models in a game engine go. Last night I reversed it’s role from passive backed storage to an active participant in the modeling process. Given the goodies of objective-c and nscoder I don’t have to serialize the entire document model just enough to give me all the data I need and rebuild the object. Knowing that I stripped control from the NStreecontroller for updates on model objects and moved that to the document model. The beauty is regardless of who updates the document, with it performing updates I can transmit these events to any class that is active and listening via nsnotification center.
Seems small now but when you look at a use case of the bigger picture rather than tightly coupling the view for rendering and the view that manages grouping, and sending messages directly across the wire to these classes when the document updates via delegation I can easily update the document and everyone is aware. With everyone being aware then objects are updated more easily within the IDE as they should be.
With these updates I will be able to make sure I’m accurately rendering all models created in the IDE.
