--CDProperties.mesa   a Chipndale module
--by Ch. Jacobi   September 27, 1983 2:06 pm
--last edited Christian Jacobi   May 7, 1984 6:35:07 pm PDT
--Registration Rules for property names
--Using property names without following the rules is considered unfair.
--Atoms which start with the letters "CDX" or "CDx" (e.g. $CDxNMosTransitors)
--must be manual registered by the registrar and RegisterProperty must 
--not be used.
--Atoms which start with the letters "CDY" or "CDy" (e.g. $CDyNMosTransitors)
--must not be registered, and there is no waranty of non-conflict.
--These may be used for debugging only.
--Atoms which start with other letters must be registered with RegisterProperty.
--Other REF-types need not be registered, since no conflicts may occur.
--Every module is allowed to introduce only a finite (fixed at compile time) 
--number of "property names"s.
CDProperties: 
CEDAR 
DEFINITIONS 
IMPORTS Atom =
 
BEGIN
Properties: TYPE = CD.Properties;
RegisterProperty: 
PROC [prop: 
REF, registrationKey: 
REF←NIL] 
RETURNS [first: 
BOOLEAN];
--registers "prop" in a table; any program which wants to use an ATOM 
--as a "prop" gets to know if it is already in use. 
--if registrationKey#NIL and registrationKey is equal to registrationKey of previous 
--registration, a property may be multiple registered 
--may raise CD.Error[doubleRegistration] and others
 
--Property names cannot be removed, since they may reside somewhere in the
--stored data.  
--Usage
--Include (or remove) properties exclusively with PutProp; so the property-lists
--are monitored correctly;
--Properties hang on (if a REF ANY is used):
--CD.ApplicationPtr's
--CD.Design's
--CD.Technology's
--Atoms  [these properties are not shared to the module Atom]
-- the Atom need not be registered anywhere, the registration of the
-- propertynames is enough to prevent conflicts
 
--the REF ANY's must not be NIL
PutProp: 
PROC [onto: 
REF, prop: 
REF, val: 
REF←
NIL];
--a NIL val removes the property
 
GetProp: 
PROC [from: 
REF, prop: 
REF] 
RETURNS [
REF];
--NIL if prop is not found
 
GetPropFromList: 
PROC [propList: Properties, prop: 
REF] 
RETURNS [
REF] =
--NIL if prop is not found
--bypasses monitor lock; 
INLINE{RETURN[Atom.GetPropFromList[propList, prop]]};
 
--speed ups  
PutPropOnApplication: 
PROC [onto: 
CD.ApplicationPtr, prop: 
REF, val: 
REF←
NIL];
--a NIL val removes the property
 
PutPropOnDesign: 
PROC [onto: 
CD.Design, prop: 
REF, val: 
REF←
NIL];
--a NIL val removes the property
 
PutPropOnTechnology: 
PROC [onto: 
CD.Technology, prop: 
REF, val: 
REF←
NIL];
--a NIL val removes the property
 
PutPropOnAtom: 
PROC [onto: 
ATOM, prop: 
REF, val: 
REF←
NIL];
--this property is NOT fetchable with Atom.GetProp
--there is no registration need for the onto-Atom
--a NIL val removes the property
 
PutPropOnObject: 
PROC [onto: 
CD.ObPtr, prop: 
REF, val: 
REF←
NIL];
--a NIL val removes the property
--warning: different objects may share bits, property owners loose!
 
PutPropOnLevel: 
PROC [onto: 
CD.Level, prop: 
REF, val: 
REF←
NIL];
--a NIL val removes the property
 
GetPropFromApplication: 
PROC [from: 
CD.ApplicationPtr, prop: 
REF] 
RETURNS [
REF];
--NIL if prop is not found
 
GetPropFromDesign: 
PROC [from: 
CD.Design, prop: 
REF] 
RETURNS [
REF];
--NIL if prop is not found
 
GetPropFromTechnology: 
PROC [from: 
CD.Technology, prop: 
REF] 
RETURNS [
REF];
--NIL if prop is not found   
 
GetPropFromAtom: 
PROC [from: 
ATOM, prop: 
REF] 
RETURNS [
REF];
--does NOT fetch properties put with Atom.PutProp
--NIL if prop is not found   
 
GetPropFromObject: 
PROC [from: 
CD.ObPtr, prop: 
REF] 
RETURNS [
REF];
--NIL if prop is not found
--warning: different objects may share bits, property owners loose!
 
GetPropFromLevel: 
PROC [from: 
CD.Level, prop: 
REF] 
RETURNS [
REF];
--NIL if prop is not found
 
--property procedures
InstallProcs: 
PROC [prop: 
REF, new: PropertyProcsRec];
--prop must be registered and yours
--overwrites values for which new has non NIL entries
 
FetchProcs: 
PROC [prop: 
REF] 
RETURNS [PropertyProcs];
--never copy PropertyProcs^; it can be extended by future calls of InstallProcs 
 
PropertyProcs: TYPE = REF PropertyProcsRec;
PropertyProcsRec: 
TYPE = 
RECORD [ 
makeCopy: MakeCopyProc ← NIL,
internalWrite: InternalPWriteProc ← NIL,  
internalRead: InternalPReadProc ← NIL,
exclusive: BOOL ← FALSE, --the implementation requests others not too fool with
ownersData: REF ANY ← NIL, -- for the registrar of the property
myData: REF ANY ← NIL -- for CDProperties own implementation
];
 
MakeCopyProc: TYPE = PROC [prop: REF, val: REF] RETURNS [valCopy: REF];
InternalPWriteProc: TYPE = PROC [prop: REF, val: REF]; 
InternalPReadProc: TYPE = PROC [prop: ATOM] RETURNS [val: REF];
CopyProps: 
PROC [propList: Properties] 
RETURNS [copy: Properties];
--copies properties individually using their MakeCopyProc's and defaults for some types 
 
DontCopy: 
PROC [prop: 
REF, val: 
REF] 
RETURNS [nil: 
REF];
--to be shure that no copy is made; trivial procedure
 
CopyVal: 
PROC [prop: 
REF, val: 
REF] 
RETURNS [valCopy: 
REF];
--copy of val; trivial procedure; is for some types a default anyway
 
RopePWrite: PROC [prop: REF, val: REF];
RopePRead: PROC [prop: ATOM] RETURNS [val: REF];
IntPWrite: PROC [prop: REF, val: REF];
IntPRead: PROC [prop: ATOM] RETURNS [val: REF];
AtomPWrite: PROC [prop: REF, val: REF];
AtomPRead: PROC [prop: ATOM] RETURNS [val: REF];
SomePWrite: PROC [prop: REF, val: REF];
SomePRead: PROC [prop: ATOM] RETURNS [val: REF];
END.
Design consideration:
=  A registeration procedure for property names is needed to prevent the same 
property name beeing used by two independent modules.
=  Props are unique, and not used per technology since they hang on
objects where the technology does not hang and some procs havn't
a design or technology parameter. 
=  CDProperties serves for object classes with few numbers of properties,
CDValue serves for object classes with huge numbers of "properties"
User Requests:
=  Please tell me if you need other chunks of property actions monitored.
=  Please tell me if you need other property procedures.