elcond@garnet.berkeley.edu (Gregory Dow) (07/21/88)
Given the number of inquiries I have received about "The Cruched Shell", I believe that a Net posting is appropriate. I appreciate all the offers to help out, and will try to send individual responses to everyone who replied in the next few days. Implementation of the Shell: All code is in LSC, and there is no preprocessor. You type your code in the LSC editor and run it. The Shell is not a separate application. It is a library of source code, which is designed to be easily extended and modified by using the standard object-oriented technique of overriding functions of superclasses. Classes are defined by using 3 source files: A .c file which contains the code for each of the class's methods, and two header files -- one which declares the class's instance variables and the other which defines the message names and data structures. Inheritance (single only) is achieved through the miracle of nested #include files. The header files for a class #include the header files of its superclass. A class inherits ALL the instance variables and methods of its superclass. Instances of classes, or objects, are allocated as relocatable blocks in the heap (handles). Messages are sent to objects with the following syntax: SendMsg(theObject, theMessage, arguments...); This corresponds to the theObject.message(arguments...) syntax of many object-oriented languages. Our code is standard C, so we use the standard function call syntax. The first instance variable of all objects is a pointer to what I call a "dispatcher" function for its class. SendMsg is implemented with in-line assembly language which just jumps to the dispatcher function. A dispatcher function consists mainly of a switch statement which invokes the proper method based on theMessage. Messages not handled by a specific class are passed on to its superclass. Creating a new object is somewhat awkward. The instance variables for an object are defined by a struct, whose first field is the aforementioned class dispatcher function. The syntax is: theObject = (ObjectHandle) NewObject(sizeof(ObjectStruct), ClassDispatcher); The function NewObject returns a handle to a newly created object (which must be typecast to the proper type) given the size of the object's instance variables and a pointer to its class dispatcher function. Although cumbersome, this implementation provides the most flexibility. I have considered setting up a scheme where all the classes are "installed" with some initialization code and given some sort of identifier (this may require a global variable for each class). Something like, ObjectName = InstallClass(sizeof(ObjectStruct), ClassDispatcher); once in an initialization routine and then, theObject = (ObjectHandle) NewObject(ObjectName); when one actually wants to create an object. I am open to opinions and suggestions on this point. Since objects are just handles, the resource manager may conveniently be used for saving and retrieving objects. To access an object stored as a resource, the syntax is theObject = (ObjectHandle) NewResObject(resType, resID, ClassDispatcher); For OOP gurus: Since we only send messages to handles to objects, only late binding is possible. Also, since this is standard C, there is really no easy way to implement data encapsulation and hiding. Instance variables are just fields in a struct, accessible to any function which knows about the struct. Private methods are implemented as calls to functions defined as "static" in the class's .c file. Class Hierarchy: Many people asked about how the classes compared to those in MacApp. I have purposely stayed away from MacApp and have never used it (to avoid any possible legal problems -- half a :^) ). I only know what I have read about it in Kurt Schmucker's book -- I guess he talks about some version of MacApp 1.0. I know absolutely nothing about MacApp 2.0. The main classes in The Shell at the moment are: (this is not a complete list) Application - initialization stuff and the event loop (full support of MultiFinder suspend, resume, and mouseMoved events) Window - All the basic window stuff not dealing with the content region. Supports floating windows (any number) which work "correctly" with Desk Accessories. Custom WDEF's are also supplied. View - The stuff that goes inside a window. You need a different subclass of a view for each type of information you want to display, i.e., text, picture, bitmap, etc. Windows may have multiple views. WorkSet - Ties together windows, views, files, and anything else that deals with the information an application manipulates. A WorkSet is sort of a supervisor which controls the communication between various objects. In a typical application, a WorkSet would be responsible for creating a window, installing views in that window, and creating a file (or document) which is associated with the window. Menu - Standard Mac menus, pull-down, heirarchical, and pop-up. A custom MDEF supports tear-off menus (they become floating windows after being torn off). The usual commands from the Apple, File, and Edit menu are supported. Control - Standard controls: buttons, check boxes, radio buttons, scroll bars ItemPalette - A palette of items, such as the Tools and Patterns in a drawing or painting program. An ItemPalette may be used as the basis for a custom menu (A tear-off palette as in HyperCard) or installed as a view in a window (As in MacDraw). Future Plans: We keep adding new objects whenever we can. The focus is currently on developing a utility to generate skeletal code for a class (the structure of the header files and dispatcher functions are highly standardized and must adhere to a rather rigid format) and on making new view subclasses which actually perform useful work (such as drawing, painting, and text editing). Color support is severely lacking (I've done most of the work on an SE). We plan to port The Shell to C++ when it becomes available (with LS Pascal 2.0 supporting object Pascal and LSC 3.0 released, I hope the next big project at THINK is LS C++). I am always open to suggestions for additional features and comments about the implementation. I am especially interested in hearing from people who have used MacApp. People have commented that they have had difficulties or are not satisfied with MacApp. Does anyone have any SPECIFIC gripes which they would like share? Please e-mail any questions, comments, or requests for further information. Gregory Dow ARPA: elcond@garnet.berkeley.edu Chemical Engineering Dept. UUCP: {uwvax, decvax, ihnp4, ...}!ucbvax University of California !elcond%garnet.berkeley.edu Berkeley, CA 94720 BITNET: POLYDOW@UCBCMSA
landman%hanami@Sun.COM (Howard A. Landman) (07/22/88)
In article <12362@agate.BERKELEY.EDU> elcond@garnet.berkeley.edu (Gregory Dow) writes: >Classes are defined by using 3 source files: A .c file which contains >the code for each of the class's methods, and two header files -- one >which declares the class's instance variables and the other which defines >the message names and data structures. Inheritance (single only) is >achieved through the miracle of nested #include files. The header files >for a class #include the header files of its superclass. A class inherits >ALL the instance variables and methods of its superclass. Gee - this sounds like you can get multiple inheritance just by nesting 2 or more include files. So why "single only"? (Assuming no conflicts.) Is it because you need to know which SuperClass to pass a message to if the local Class can't handle it, so the dispatcher would get more complicated? Howard A. Landman landman@hanami.sun.com UUCP: sun!hanami!landman
mce@tc.fluke.COM (Brian McElhinney) (07/28/88)
elcond@garnet.berkeley.edu (Gregory Dow) writes: > People have commented that they have had difficulties or are not satisfied > with MacApp. Does anyone have any SPECIFIC gripes which they would like > share? I have always been amazed that views (drawing areas inside windows) are tiled. Overlapping views would have been far more useful, an indeed are rumored to be a part of the next release (as are C++ and a symbolic debugger). Also, you should be able to nest views inside views. A "real" text class would be wonderful. It should be something like a text item in MacDraw. The dialog class has taken a beating at meetings and in the MacApp DA newsletter (so I have avoided it). It would be useful to have classes for each of the basic dialog items (buttons, check boxes, etc.) such that they can appear in any view. I think this is also in the next release. The only grouping mechanism is the list. To the programmer it appears to be a dynamic array, not a list (i.e there is no way to ask for the next object; you must keep an index yourself). Other data types would be useful, and I'm sure will appear as MacApp evolves and matures. The basic window class is, well, kind of basic. Multi-pane windows (such as in Excel) would be a great addition. MacApp is a great tool, as it handles everything a commercial grade application should (low memory, MultiFinder, printing), and makes many things much easier (undo, updating multiple views of the same data, menu enable/disable). Unfortunately, MacApp will not get the wide-spread use it deserves; not because of faults in MacApp itself, but because using it means using MPW (i.e.: slow and expensive). Now if there was such a thing as LightspeedC++ ... Brian McElhinney mce@tc.fluke.com
lsr@Apple.COM (Larry Rosenstein) (07/29/88)
In article <4581@fluke.COM> mce@tc.fluke.COM (Brian McElhinney) writes: >elcond@garnet.berkeley.edu (Gregory Dow) writes: >> People have commented that they have had difficulties or are not satisfied >> with MacApp. Does anyone have any SPECIFIC gripes which they would like >> share? > >I have always been amazed that views (drawing areas inside windows) are tiled. >Overlapping views would have been far more useful, an indeed are rumored to be >a part of the next release (as are C++ and a symbolic debugger). Also, you >should be able to nest views inside views. Overlapping views are not directly supported in MacApp 2.0. Views can overlap, but MacApp does nothing to prevent one view from interfering with another. The views will be drawn in a particular order and, one view will end up covering part of another. It should be easy to implement true overlapping views in the same way overlapping windows are implemented. You would have to maintain a visRgn for each view in the list, and override the Focus method to clip to the view's visRgn. MacApp 2.0 does support arbitrary hierarchy of views. The dialog unit is completely redone, and dialogs done with MacApp don't use the Dialog Manager. Instead they are regular windows. There are many view classes predefined in the Dialog units, to correspond to all the standard controls, as well as control-like objects that are not really controls (popup menus, pictures, icons, lists of items, etc.). The view hierarchy is defined by a resource, and there is work being done on a graphical editor for view resources. >The basic window class is, well, kind of basic. Multi-pane windows (such as >in Excel) would be a great addition. You can do this in MacApp 1.1, and it will be a bit easier to do in MacApp 2.0. MacApp directly supports windows with a fixed-size "palette" at the top or left of the window. More complicated window arrangements are possible if you override the window class and implement code to resize and move its subviews when the window resizes. MacApp 2.0 does not directly support splitting a view into independently scrollable parts that display the same information. Again, the view architecture in MacApp 2.0 makes this easier to implement than it was in the old MacApp. >of faults in MacApp itself, but because using it means using MPW (i.e.: slow >and expensive). Now if there was such a thing as LightspeedC++ ... Well eventually, there will be Lighspeed Pascal 2.0. Larry Rosenstein, Object Specialist Apple Computer, Inc. 20525 Mariani Ave, MS 46-B Cupertino, CA 95014 AppleLink:Rosenstein1 domain:lsr@Apple.COM UUCP:{sun,voder,nsc,decwrl}!apple!lsr