-- File: Nut.mesa
-- Implemented by: NutImpl and NutDefaultImpl in Squirrel package
-- Contents: An interface to allow Cypress application programs for different database
-- entity types to call each other without knowing about each other beforehand. Each
-- application implements one or more "nut" types; nuts are viewers on Cypress entities.
-- Created by: Rick Cattell on 11-Dec-81 12:29:29

-- Last edited by:
-- Rick Cattell on July 22, 1983 2:31 pm
-- Willie-Sue on January 21, 1983 8:48 am
-- Jim Donahue on June 16, 1983 2:42 pm

DIRECTORY
DB, Rope, ViewerClasses;

Nut: CEDAR DEFINITIONS =

BEGIN OPEN DB;

ROPE: TYPE = Rope.ROPE;
Viewer: TYPE = ViewerClasses.Viewer;

-- Interaction between nuts: these are implemented in NutImpl.mesa
-- Each nut implementation registers itself as knowing how to display, edit, query, etc. some
-- set of domains (a domain is a type of entity, see DB), with the Register proc. Any
-- application (or the user through Squirrel) can then call one of the following procs to
-- invoke whoever has registered himself for an entity type (or the default implementations
-- provided by Squirrel if no one is registered).

Register: PROC[
domain: ROPE,
segment: DB.Segment,
display: DisplayProc← NIL, -- proc to make displayer for entity in domain
edit: EditProc← NIL, -- proc to make editor for new or old entity in domain
query: QueryProc← NIL, -- proc to make queryer on domain
create: CreateProc← NIL, -- proc to create viewer for above (defaults to container)
update: UpdateProc← NIL, -- proc to call when relation referencing this domain is updated
transaction: TransactionProc← NIL -- proc to call when the transaction for the segment is
-- opened, closed, or aborted by the SquirrelTool (which can have hands into most anything)
];
-- Registers a display, create, query, create, update, and/or transaction proc for given domain.
-- These will supersede any previous registrations for this domain except where new procs NIL.

DeRegister: PROC[segment: DB.Segment, domain: ROPE];
-- Deregisters all procs for this domain


Display: PROC[ e: DB.Entity, seg: DB.Segment ← NIL,
     parent: Viewer← NIL, method: Method ← spawned ] RETURNS[ v: Viewer ];
-- Creates a nut viewing entity e. If a nut implementation has
-- registered itself for e's type, that implementation will be called, else the
-- default Squirrel implementation will be used. If method=replace, replaces parent with the
-- new viewer. IF method#replace AND parent#NIL, use the last viewer spawned
-- from parent. If there isn't one and method=oneOnly, look to see if there is already a viewer
-- for this entity. The seg argument is only necessary for system entities, which have
-- no implicit segment.

Edit: PROC[ d: DB.Domain, eName: ROPE, seg: DB.Segment ← NIL,
    parent: Viewer← NIL, method: Method ← spawned ] RETURNS[ v: Viewer ];
-- Creates a nut for editing the entity with name eName in domain d.
-- If method=replace, replaces parent with the new viewer.
-- IF method#replace AND parent#NIL, use the last viewer spawned from parent.
-- If there isn't one and method=oneOnly, see if there is already a viewer for this entity.
-- As with displayer, either a registered implementation or the default editor
-- will be invoked. The user will be prompted for any other info that an entity from e's
-- domain can have.

Query: PROC[d: DB.Domain, seg: DB.Segment ← NIL] RETURNS[ v: Viewer ];
-- Creates a queryer viewer on domain d. No default yet implemented.

Method: TYPE = {replace, oneOnly, spawned}; -- method used to determine new viewer

DisplayProc: TYPE = PROC[e: DB.Entity, newV: Viewer, seg: DB.Segment ← NIL];
-- Should set up an application's newV to display entity e and its fields.

EditProc: TYPE = PROC[d: DB.Domain, eName: ROPE, newV: Viewer, seg: DB.Segment ← NIL];
-- Should set up newV to edit entity eName in domain d.

QueryProc: TYPE = PROC[d: DB.Domain, newV: Viewer, segment: DB.Segment ← NIL];
-- Should set up a queryer on domain d. An application-defined data structure
-- can be passed in init if some data is needed to set up the query.

CreateProc: TYPE = PROC[ nutType: NutType, d: Domain, eName: ROPE, seg: DB.Segment ← NIL,
column: ViewerClasses.Column ← left ] RETURNS [v: Viewer];
-- Should create a viewer WITHOUT filling it in and painting it yet. Viewer is for new
-- nut of the given type. The default CreateProc creates a container viewer.

Update: PROC[updateType: UpdateType, tuple: Relship];
-- Tells Squirrel that entity e has been edited or changed in some way. Everyone who has
-- registered an update proc will be notified of the change, to allow them to update
-- their viewer or whatever.

UpdateType: TYPE = { create, destroy };

NutType: TYPE = { displayer, editor, queryer };

UpdateProc: TYPE = PROC[updateType: UpdateType, tuple: Relship];
-- A notification that entity eName in domain d has been modified in some way

Notify: PROC[ segment: DB.Segment, type: TransactionType ];
-- Notify everyone who is interested that the transaction for this segment has been
-- changed (opened, closed, or aborted). This procedure simply passes the arguments on to
-- all those procedures registered for the segment.

TransactionProc: TYPE = PROC[segment: DB.Segment, fileName: ROPE, type: TransactionType];
-- A notification that a transaction has been opened, closed, or aborted.
-- The client procedure is called after an open or close occurs. In the case of a transaction
-- abort, the client procedure is called after the abort AND re-open of transaction, so client
-- can simply re-display windows. We will probably need a more complex notification in
-- the future, but this is better than nothing till we understand what we want.

TransactionType: TYPE = {open, close, abort};


-- ********************************************************
-- Miscellaneous (defined in NutDefaultImpl)
-- ********************************************************

debug: BOOLEAN; -- TRUE => use the default procedures instead of registered proc

DefaultDisplay: DisplayProc;
-- Creates a browser viewer display the given entity.

DefaultEdit: EditProc;
-- Creates a browser viewer display the given entity, and prompts for
-- all the relationships an entity of this type can participate in.

DefaultQuery: QueryProc;
-- Creates default a queryer.

DefaultCreate: CreateProc;
-- Creates a default viewer for a nut, a Container with default menu and title

END. . .

Change Log:

Edited by Rick on March 18, 1982 11:50 am: Major reorganization. Register now allows registration of all or some of the three procedures, and replaces any previous registration for that domain with the new one. Edit take init REF ANY. DisplayProc, EditProc, QueryProc take new viewer on calls out from Nut, old viewer on calls into Nut. Added close and open notify procs.

Edited by Rick on March 25, 1982 4:29 pm: Added user interaction procs section, dump and load stuff.

WSH on April 1, 1982: added MessageConfirm

Rick on April 3, 1982 4:29 pm: added width option to button. Added CreateProc feature.

Willie-Sue on July 8, 1982: changed EnumerateNutList, created NutPrivate.mesa, NutListImpl.mesa

Willie-Sue on July 27, 1982: changed EnumerateNutList to return LIST OF NutRec.

Cattell on August 5, 1982 7:11 pm: added init parm to Display, Create procs. Added GetDBTransaction proc.

Maxwell on September 8, 1982 9:29 am: moved procedures to Palm and SquirrelOps

Cattell on April 12, 1983 1:16 pm: fixed up some outdated comments.