Rebundling WarKit Using Modules to Create a Generic, Extensible Application Well, I had a nice Christmas back in Northern Illinois (darn, I just missed seeing Don there, too). However, I had another one of my unpredictable brainstorms, completely changing the nature of our project. Fortunately, it can still build on most of the work we've done to date. Well, the work I've done to date, so it doesn't matter too much either way. The goal of the project has changed from building a Kit with Examples to building an Application using Bundles. By using Bundles appropriately, we can achieve virtually all the flexibility of a Kit. By building an actual application, we can make things easier for the developer (and more uniform for the user). And while we may want to improve the core Application, we can still make it backwards compatible with the various bundle formats. First, for those who don't know (and to make sure I got it right), I will explain exactly what a Bundle is. Next, I will explain what a War bundle would consist of. Finally, I'll explain how a bundle would be used by a user application. The last may turn into a separate essay, depending on how long-winded I get. I. What is a Bundle [Drawn from NextDev/Concepts/ObjetiveC/4_RunTime] A bundle is a construct defined by NeXT Objective-C. It is a directory containing both new Classes (in a library file) and archived Instances (in 'nib' - NeXT Interface Builder files), as well as graphics, menus, and virtually any other NeXTSTEP resource. The ability to dynamically load new classes is one of the niftiest things about Objective-C. In essence, an application which uses Bundles only needs to provide a main menu and a way for selecting bundles, and the code in the Bundle can do everything else. To access information inside a bundle, we would work through the "principalClass" as follows: Class vendor = [myBundle principalClass]; We would then send messages to this class - or instances thereof - to access the other objects or resources contained in the bundle. Classes in the bundle either conform to a protocol - or, even better, are subclasses of pre-existing classes. II. How do we use it The basic idea is that each bundle would make up a single scenario. There are generally three components to any wargame: - the map of the world - the pieces and the rules governing them - the setup The first is a simple hierarchy of regions and terrains as we discussed earlier. The pieces are basically just a set of classes for the different unit types. The complicated part is the setup. The setup not only has to decide the initial deployment of forces, but also determine the different sides involved. There is a separate problem in that both the client and the server would be affected by the Bundle. The server needs to know the map, and the client needs know the pieces. I think the best way to handle things is to have the principal object be a vendor ("WarVendor"). It would need to respond to the following class methods: // Server methods + serverClass; // Client methods + clientClass; [I don't think you can have a protocol for class methods, but I may be wrong]. The WarVendor might return itself as either the client or the server class; however, it is possible a given bundle might only have the client or the server portion present - in which case it would return nil for one of these methods. The server process would load the bundle, find the server class, and instantiate it. The server would then be "run" so as to respond to Distributed Object reqursts. The server object could be queried for the map instance, which it could either construct dynamically or read in from a nib file. We could write a generic WarServer object that implements all the necessary functionality for a server. However, if we designed it right, people could create subclasses for any special behavior they wanted. On the client side, an instance of the client class would be 'run', possibly in a separate thread. It would be responsible for sending and receiving messages with the server AND with the UI elements of the client application. The client would be the owner of the various nib files - windows, menus, inspectors, and what not. It would be the "Model" in the MVC paradigm we discussed. The client class would respond to the method: + pieceClasses; This would return a List of all the classes for different pieces that could be instantiated. Each piece would have inspectors associated with it, to examine states, specify movement, or initiate attack. Each class could also maintain statistic about how many units were created and destroyed. III. What it looks like A user goes to their shelf and click on WarGame.app. It comes up with a radio panel with the choices "Start Server" or "Connect to Server At:" The "connect to:" panel may have a list of NetInfo hosts, or it may have looked around the network for objects with name "WarServer". If the user chooses to start a new server, he is presented with a list of bundles to load. Bundles should be in ~/Apps, LocalApps, and NeXTApps, and have the extension "WarGame" (the lowercase extension, "wargame", would be used to save games in progress). The server would be started up in a separate process (task), and the WarGame.app would start up the client. In some cases, the client may be allowed to choose a particular bundle; otherwise, the server would tell the client to load the appropriate bundle after it connects. Note that this requires all players to have access to the relevant bundle. There would be three parts to the User Interface. First is a "Status" window, which shows the a log of messages (from the server or other users), and status information such as "Waiting for You to Move". This would be the fundamental - probably uncloseable - window. Secondly would the "View" windows. These could conceivably be part of the application, rather than the bundle. These would function as described in my last essay: users could scale, translate, and rotate these to focus on different parts of the WarWorld. They would also use this to select the "ActiveObject" to be Inspected. The final piece of the interface is the Inspector. There are basically two kinds of Inspection: General and Specific. I think they should be in one (Switchable) panel, but I'm not sure. General inspectors include things like unit statistics, moves in progress, relative rankings of sides. Specific Inspectors - which might vary from piece to piece - would include Status, MoveBuilding, and Attacking. Examples would be provided, but in general InspectorViews would be provided by the Bundle. In addition, the Bundle could add menu items which could bring up panels for additional information or functionality. Well, that's my vision of what a Bundle-based WarGame.app would look like. If I don't hear any complaints - and I don't get any new brainstorms - I'll try to start planning a roadmap to get us there. Ernie Prabhakar, January 20th, 1994