\begindata{text,538611048} \textdsversion{12} \template{default}

advertisement
\begindata{text,538611048}
\textdsversion{12}
\template{default}
\majorheading{ASlot - Class for Widget Attributes}
ASlot and classes derived from it form a family of types and slots for
AWidget attributes. New types can be added in separate source files.
The
files aslot.H and aslot.C define these classes:
\leftindent{ASlotInt, ASlotReal, ASlotString, ASlotFile, ASlotPtr, \
ASlotATK, ASlotFunction, ASlotDataObj, ASlotFigure
}
(Moreover, ASlotBoolean is defined to be ASlotInt).
\
Appropriate conversions and assignments between ASlot values and C++
values
are supported for
\indent{int, long, double , const char *, const char, void *, ATK *,
aaction *, dataobject *, text *, figure} *
Objects of type aaction can be called as functions.
\section{Examples}
Usually a slot is part of an AWidget object or an object in a class
derived
from AWidget. Let us suppose we are deriving class GoodWidget from
AWidget
and GoodWidget is to have an integer slot "elasticity". The declaration
of
GoodWidget would include:
goodwidget.H
#include <awidget.H>
class GoodWidget : AWidget \{
. . .
ASlotInt elasticity;
. . .
\}
Slots behave like C++ values.
have:
For instance a client of GoodWidget could
client.C:
#include <goodwidget.H>
. . .
GoodWidget *obj = . . . ;
int size = obj->elasticity * localsize;
obj->elasticity = 1;
If the elasticity slot is private in goodwidget.H, accessor functions can
be provided.
goodwidget.H
inline int GetElasticity() \
\{return elasticity;\}
inline void SetElasticity(int v)
\{elasticity = v; \}
client.C:
AWidget *obj = . . .;
int size = obj->GetElasticity() * localsize;
obj->SetElasticity(1);\}
\section{Slot Names}
Slots can have names that are usable at runtime, although these are of
little value until the slot is incorporated in a collection as in an
AVarSet. A slot name is an atom. To simplify constructing and declaring
slot names in code, aslot.H defines three features:
\bold{ASlot_NAME(name)}
\leftindent{This macro creates an atom for "name" and makes it the value
of
a const identifier, slot_name. A name for the elasticity slot would be
declared
\leftindent{Aslot_NAME(elasticity);}
The resulting declared name constant is "slot_elasticity".}
\bold{ASlot_NameVar}
\leftindent{It is possible to declare a variable to hold a slot name.
The
type of this variable should be ASlot_NameVar. This is NOT used for
function parameters.}
\bold{ASlot_NameParam}
\leftindent{If a slot name is to be passed to a function, its type should
be ASlot_NameParam.}
The value assigned to an ASlot_NameVar or passed to an ASlot_NameParam
can
be another such value or an atom, an atom *, a const atom *, an atom_def,
or even a plain string:
ASlot_NAME(elasticity);
// slot_elasticity
ASlot_NameVar nv;
nv = slot_elasticity;
// ok
nv = atom_def("elasticity"); // ok
nv = "elasticity";
// even this is okay
\section{ASlot public methods }\
\bold{static void Init()}
This function must be called during initialization of any module which
uses
one of the ASlot::xxxreg values.
\bold{ASlot()}
Constructor
\bold{virtual ~ASlot()}
Destructor\bold{
}
\bold{virtual ASlot &Default()}
\leftindent{Sets slot to its default value.
Usually zero.}
\bold{virtual boolean IsDefault()}
\leftindent{TRUE iff latest assign is via Default()}
\bold{operator avalue_u()}
\leftindent{Returns value as an avalue_u.}
\bold{virtual ASlot &operator=(const ASlot *v)} \
\leftindent{Assigns value of one slot to another.
must
accept type of source.}
Type of destination
\subsection{Input/output}
A line written has the form:
\
slot-name : ( type ) string-basis-for-value \\n
where type is the suffix after "ASlot" in the class name.
\bold{void Write(FILE *fp)}
Writes a string representation to a file stream
\bold{static ASlot *Read(FILE *fp)}
Reads a representation from the file stream.
// value<->string conversion
caller of ReadValue or WriteValue should check the newline
avoid duplication from WriteValue
do NOT send it to ReadValue
\bold{virtual void WriteValue(AString *dest)}
\leftindent{Writes the value as a string to dest.
type. No trailing newline.}
No slotname, colon, or
\bold{virtual boolean ReadValue(const char *src)}
\leftindent{Reads value from src.
trailing newline.}
No slotname, colon, or type.
No
// each function converts from its argument to a string
//
and calls ReadValue on the string
// interprets TAGS on the front of strings
\bold{virtual boolean EatString(const char *src)}
\bold{virtual boolean EatAaction(const aaction *act)}
\bold{virtual boolean EatATK(const ATK *obj)}
\bold{virtual boolean EatAvalue(const avalue *v)}
\leftindent{A derived class should override any of these if it can do a
better job of interpreting a string than the default would do. For
instance, if this derived type stores ATK values in some special way, it
would override EatATK to interpret the object for itself. }\
\leftindent{The default behaviors are these: \
\indent{EatString - checks the string for an initial tag of PROC, NESS,
NESSEXP, or FILE and calls the function or reads the file to get a string
for further processing.
EatAaction - execute the function and call EatAvalue on the result.
EatAvalue - for a string or atom value, call EatString on the value;
for
ATK values, call EatATK;
otherwise fail.
EatATK -if value is a text or simpletext, EatString is called on the
text;
if the value is an aaction, EatAaction is called on the result; otherwise
fail.}}
\
// Flags: the next two set/reset the todatastream flag
//
it will be set again if fromresources is true \
//
and the value is modified
\bold{void Remember()}
\leftindent{Sets flags to cause attribute to be written to data stream.}
void\bold{ DisRemember()}
Sets flags so the attribute will not be written to data stream.
// ASlot: The following are for AWidget and other driver modules
// Normal clients should not need these
\bold{static const char *ASlotPrefix(const char *name)}
// returns name prefixed with "ASlot"
\bold{const char *GetSlotType()}
// could be \{return GetTypeName();\}
// but strip off leading "ASlot"
\bold{static ATKregistryEntry *LoadType(const char *typenm)}
// for AWidget::AddSlot(atom *name, char *typenm)
//
creates a slot of the named type
// almost is:
\{return ATK::LoadClass(typenm);\}
// but have to prefix typename w/ "ASlot"
\bold{static ASlot *NewASlot(const char *typenm)}
// typenm does not have leading "ASlot"
\bold{void SetName(ASlot_NameParam nm)}
\bold{ASlot_NameVar GetName()}
\bold{void SetSource(const char *src)}
set string that will be written to data stream
uses NewString to make a copy of its argument
\bold{const char *GetSource()}
returns a pointer to the string \
that will be written to the data stream
\bold{void SetAssign(aaction *newset)}
sets the setit function associated with the slot
deletes the old (assumes ownership)
\bold{aaction *GetAssign()}
\bold{void UseOnlyFromAnAssignFunction
(const avalue_u *src)}
\leftindent{a setit functionshould use this function todo the actual
assignment of a new value to the slot}
the setit function for an ASlotString slot should NOT use NewString
the setit function for an ASlotFile slot should NOT use NewString
// ASlotAssign - class for aactions supplied as Assign function
\bold{DEFINE_AACTION_FUNC_CLASS(ASlotAssign, ASlot);}
\bold{inline char *Client(const char *objnm) }\
saves the objname for use in error messages
objname string continues to be owned by the caller,
but must not be deallocated until a call \
has been made to restore the old value, \
establish a new value, or clear the client \
string (via ASlot::ClearClient()).
\bold{inline void ClearClient() }\
Forgets about the client.
Error messages will be anonymous.
the client is assumed to own the string
intention is that Client() is called on entry
to a function like Update and the old value is restored on exit
\bold{void DumpSlot()}
\bold{static const char *Client(const char *objnm)}
// ASlot: Operations on flags
\
\bold{void EnableFlags(unsigned short f)}
\bold{void DisableFlags(unsigned short f)}
\bold{unsigned int GetFlags(unsigned short mask =~0)}
// ASlot: Constants for flag values.
\bold{static const unsigned short fromresources;}
// value came from resource file or inherited in tree
\bold{static const unsigned short todatastream;}
// will save in datastream
\bold{static const unsigned short isowner;}
// ~ASlot must free val.obj
\bold{static const unsigned short isdefault;}
// most recent value given by Default()
// ASlot: operator typenm() conversions
//
must be overridden to be useful
\bold{virtual operator int()
virtual operator long()
virtual operator double()
virtual operator char()
virtual operator const()
virtual operator void()
virtual operator ATK()
virtual operator aaction()
virtual operator dataobject()
virtual operator text()
virtual operator figure()}
// ASlot: operator=(type)
//
conversions
must be overridden to be useful
\bold{virtual ASlot & operator= (typenm v);
virtual ASlot & operator= (int v)
virtual ASlot & operator= (long v)
virtual ASlot & operator= (double v)
virtual ASlot & operator= (char v)
virtual ASlot & operator= (const char *v)
virtual ASlot & operator= (void *v)
virtual ASlot & operator= (ATK *v)
virtual ASlot & operator= (aaction *v)
virtual ASlot & operator= (proctable_Entry *v)
virtual ASlot & operator= (figure *v)}
// ASlot: Function call operations
(using aaction)
// no in or out
virtual avalue operator()(ATK *obj=NULL)
// no out
virtual avalue operator()(ATK *obj, const avalueflex &in)
// both in and out supplied
virtual avalue operator()(ATK *obj, \
const avalueflex &in, avalueflex &out)
\bold{static atom *in0type}
\section{ASlotInt }\
\bold{#define ASlotBoolean ASlotInt}
\bold{ASlotInt() \{ val.integer = -999; \}}
\bold{ASlotInt(int i)}
\bold{ASlotInt(atom *name) \{ val.integer = -999;}
\bold{ASlotInt(atom *name, int i) }\
\bold{ASlot &Default()}
\bold{operator int()}
\bold{operator long()}
\bold{ASlot &operator=(long i) }\
\
\bold{ASlot &operator=(int i)}
\bold{void WriteValue(AString *dest)}
\bold{boolean ReadValue(const char *src)}
\bold{boolean EatAvalue(const avalue *v)}
\section{ASlotReal}
\bold{ASlotReal() \{ val.real = -999.0; \}}
\bold{ASlotReal(double r)}
\bold{ASlotReal(atom *name) }\
\bold{ASlotReal(atom *name, double r) }\
\bold{ASlot &Default(); }\
\bold{operator double()}
\bold{ASlot &operator=(double r) }\
\bold{void WriteValue(AString *dest);}
\bold{boolean ReadValue(const char *src);}
\bold{boolean EatAvalue(const avalue *v);}
\section{ASlotString}
conversion to char gives first char
value will never be NULL.
\
At smallest it is "", the empty string.
if there is no (type) in a resource line, string is used
in that case, \
leading whitespace is stripped from the string value
\bold{ASlotString() \{ val.cstr = empty; \}}
\bold{ASlotString(const char*s) }\
\bold{ASlotString(atom *name) }\
\bold{ASlotString(atom *name, const char *s) }\
\bold{virtual ~ASlotString() }\
\bold{ASlot &Default();}
\bold{operator const char () // 1st ch.}
\bold{operator const char *()}
\bold{ASlot &operator=(const ASlot *s);}
\bold{ASlot &operator=(const char *s);}
\bold{ASlot &operator=(const char s) }\
\{ char buf[2]; buf[0]=s; buf[1]='\\0';
\
*this = (const char *)buf; \}
\bold{void WriteValue(AString *dest);}
\bold{boolean ReadValue(const char *src);}
\section{ASlotFile }\
// ASlotFile holds a string value during execution
//
it overrides ReadValue and WriteValue and \
//
saves various access paths to file
// Default is /dev/null
If ReadFile or Open fails, the string name is \
replaced with the default.
ReadFile
Open(flags)
Exactly one of these three is needed:
O_RDONLY,
O_WRONLY,
O_RDWR
This is needed if the file may not already exist:
O_CREAT
(mode 644)
This is needed if writing to the end of file is desired:
O_APPEND
O_TRUNC
Use this with O_WRONLY or O_RDWR
to cause an existing file to be truncated when opened.
These are probably not useful:
O_NDELAY,
O_SYNC,
O_NOCTTY,
O_NONBLOCK,
O_EXCL \
string value will be actual file name
that's all that's needed internally
init to ""
set up string (and save info) on any assign to the field
file format saves various ways of addressing the file:
absolute, relative, $HOME, $ANDREWDIR
/usr/local, ...
Created by WriteValue
Interpreted by ReadValue
(anything that can be resolved by UnfoldPathName)
ASlot and derived classes form a family of types and slots
for AWidget attributes.
The design permits a typed attribute \
to be added to an AWidget even if that widget was compiled
before the particular ASlot derived class was implemented.
ASlotBoolean (#defined to ASlotInt)
XXX ??? Should constructors with initializations
use operator= (as they do now) \
or assign directly to val.obj ???
\bold{ASlotFile() \{ val.cstr = devnull; \}}
\bold{ASlotFile(const char *s)
\{val.cstr = devnull; *this = s;\}}
\bold{ASlotFile(atom *name) }\
\bold{ASlotFile(atom *name, const char *s) }\
\bold{virtual ~ASlotFile() }\
\bold{ASlot &Default()}
\bold{ASlot &operator=(const ASlot *s);}
\bold{ASlot &operator=(const char *s);}
\bold{operator const char *()}
\bold{void WriteValue(AString *dest);}
\bold{boolean ReadValue(const char *src);}
\bold{virtual boolean ReadFile(AString *dest);}
// read the entire file into dest
// returns FALSE for failure
\bold{virtual int OpenFile(int flags)}
// return a file descriptor for the file (or -1)
\{ const char *nm = *this; \
return (nm) ? open(nm, flags, 0644) : -1; \}
\section{ASlotPtr}
\bold{ASlotPtr()}
\bold{ASlotPtr(atom *n)}
\bold{ASlotPtr(void *s)}
\bold{ASlotPtr(atom *n, void *s)}
// There is no destructor to free the pointee
\bold{ASlot &Default();}
\bold{virtual operator void *()}
\bold{virtual operator ATK *();}
\bold{virtual ASlot &operator=(void *s) }\
\bold{virtual ASlot &operator=(long s);}
\bold{virtual ASlot &operator=(int s)}
\bold{void WriteValue(AString *dest);}
// Derived classes MUST override WriteValue & ReadValue.
\bold{boolean EatAvalue(const avalue *v);}
\bold{boolean EatATK(const ATK *obj);}
\section{ASlotATK}
sole advantage is that it is convertible to an ATK* value
there is no test to ensure that value really is ATK*
\bold{ASlotATK()}
\bold{ASlotATK(ATK *s)}
\bold{ASlotATK(atom *n)}
\bold{ASlotATK(atom *n, ATK *s)
}\
\bold{operator ATK *()}
\bold{operator figure *();}
\bold{operator text *();}
\bold{operator dataobject *();}
\bold{ASlot &operator= (ATK *s) }\
\bold{boolean EatAvalue(const avalue *v);}
\bold{boolean EatATK(const ATK *obj);}
\section{ASlotDataObj}
\bold{ASlotDataObj() \{ val.obj = NULL; \}}
\bold{ASlotDataObj(dataobject *s) }\
\bold{ASlotDataObj(atom *n) }\
\bold{ASlotDataObj(atom *n, dataobject *s)
\bold{virtual ~ASlotDataObj();}
\bold{ASlot &Default();}
}\
\bold{operator dataobject *() }\
\bold{ASlot &operator=(const void *a) }\
\bold{ASlot &operator=(dataobject *s);}
\bold{ASlot &operator=(ASlot *src); }\
\bold{void WriteValue(AString *dest);}
\bold{boolean ReadValue(const char *src);}
\bold{virtual boolean EatATK(const ATK *obj);}
\section{ASlotFigure}
\bold{ASlotFigure()}
\bold{ASlotFigure(atom *n)}
\bold{ASlotFigure(figure *s)}
\bold{ASlotFigure(atom *n, figure *s) }\
\bold{operator figure *()}
\bold{ASlot &operator=(figure *s);}
\bold{virtual ASlot &operator=(ASlot *src);}
\bold{virtual boolean EatATK(const ATK *obj);}
\section{ASlotFunction}
can assign:
aaction *
proctable_Entry *
char *
If string begins with "proc:", \
the name is that of a proctable function.
Otherwise, sets to Default.
the aaction remains owned by the caller, but the value
must not be deleted until the callee is finished with
(UGH)
\section{ASlotColor}
\section{ASlotBool}
\section{ASlotFont}
\subsection{Function Call}
An aaction value is a function and can be called in one of these forms:
aaction(obj)
aaction(obj, inflex)
aaction(obj, inflex, outflex);
An inflex may be a single value, or "avalueflex()|" followed by a
sequence
of values separated with '|'. The outflex should be an empty avalueflex.
It will be assigned the return values(s). If there are any return
values,
the first is returned by the function call in the form of an avalue.
Suppose we have
ASlotFunction f;
avalueflex out;
then we can make these calls
(*f)()
// no object, no arguments, no result
(*f)(this)
(*f)(this, 9L)
// pass only an (ATK *) object (maybe NULL)
// pass an (ATK *) object & another arg
(*f)(this, avalueflex()|9L|2)
\
// pass an (ATK *) object and multiple arguments
(*f)(this, 9L, out)
// pass an (ATK *) object and an argument
// expect back one or more values in 'out'
The use of 'L' after integers avoids an ambiguity with real values.
alternative is to use a cast: (int)9.
\bold{ASlotFunction();}
\bold{ASlotFunction(atom *n);}
\bold{ASlotFunction(aaction *s);}
\bold{ASlotFunction(atom *n, aaction *s);}
\bold{virtual ~ASlotFunction() }\
\bold{ASlot &Default();}
\bold{operator aaction *()}
\bold{ASlot &operator=(const void *a) }\
\bold{ASlot &operator=(const aaction *a);}
\bold{ASlot &operator=(proctable_Entry *p);}
\bold{ASlot &operator=(const char *s);}
\bold{ASlot &operator=(const ASlotFunction *s);}
\bold{ASlot &operator=(const ASlotString *s);}
\bold{ASlot &operator=(const ASlotFile *s);}
\bold{void WriteValue(AString *dest);}
\bold{boolean ReadValue(const char *src);}
\bold{boolean EatAaction(const aaction *act);}
The
\bold{boolean EatATK(const ATK *obj);}
\begindata{bp,538912840}
Version 2
n 0
\enddata{bp,538912840}
\view{bpv,538912840,1,0,0}
\section{Adding New Types}
A class derived from ASlot must have a name beginning "ASlot". It may
override or supply the following items
ATKregistryEntry *ATKregistry();
// ATK standard
(Required in every derived class.)
ASlotXxx(); // constructor
Set `val` to its default value.
The class may add additional \
constructors which have appropriate arguments and create \
values of the given type.
If no name is given to the slot,
it will have the name "NO_NAME".
Before the constructor is called, the constructor for ASlot and
other base
classes will have been called. All the fields of the slot will be
initialized as though the slot has the value zero. If it should have
some
other value, that value should be established by direct assignment to the
val field.
A constructor should NOT use one of the assignment functions
to give a value to the slot because that will interfere with the
'isdefault' flag which has been set by the constructor for ASlot.
~ASlotXxx();
// destructor
If the val field is assigned a pointer to data elsewhere,
the destructor ~ASlotXxx
must destroy that data.
(Required only if data must be deallocated.)
(The source field is destroyed by ASlot::~ASlot().)
ASlot Default()
Sets the slot to the default value for its type.
This may be used for initialization, error handling, \
or whatever.
Preferably, the default value does not \
require memory allocation or the presence of \
any particular library or server.
(ASlot::ASlot initializes val.obj to NULL.)
(Warning: Default returns an ASlot even though it actually retuirns the
object that has been defaulted. A cast will be needed to get back to the
object's type.)
operator type() const
// value access
This returns 'val', but first checks or converts its type.
(May be provided for any number of types.)
inline ASlot &operator=(<appropriate type> src) \
Assigns the src value to the aslot.
The implementation
should use Assign to actually set values because
it maintains flags and calls setit.
(May be provided for any number of types.)
(Warning: Operator= returns an ASlot even though it actually retuirns
the
object that has been defaulted. A cast will be needed to get back to the
object's type.)
void WriteValue(AString *dest) const;
The dest will be empty initially.
The method fills it with
a string representing the value such that the same string
can be parsed by ReadValue to produce the same value.
(Must override in every derived class.)
boolean ReadValue(const AString *src);
Read characters from src and produce an appropriate val
value.
\
The value should be such that a subsequent
WriteValue and ReadValue will reconstruct the same value.
Return TRUE iff parse succeeds, else FALSE.
(Must override in every derived class.)
Derived classes may define additional conversions and operations on the
type.
Accessible field:
val
the value itself as an avalue_u.
Other methods (especially operator=) should use Assign() to modify val.
Most classes derived from ASlot will use the (void *) member in val's
avalue_u.
source
string or object from which value is derived
If the value stored in val is derived from some non-obvious string,
that string can be presereved here for later writing out the data stream.
The source has three options, which appear as alternatives in a union.
The choice between them is made by the SourceType bits of the flags,
values of which are SourceNone, SourceString, SourceFormula, and
SourceFile.
source.original
- a string
Example: the val for ASlotColor might be a \
class color object.
Its file definition could be \
saved in source.original.
source.formula - ASlotFunction
The function computes the val value.
source.file - ASlotFile
The val value is fetched from the named file.
ASlot protected
avalue_u val;
// the actual value
ASlot &Assign(const avalue_u *src);
// used by derived classes to perform assignment
// uses setit, if defined
// clears source
ASlot &Assign(const ASlot *src);
// uses setit;
retains source
virtual void CantTake(const char *invalid);
// string is invalid for type
virtual void CantTake(const ASlot *got);
// got is an incorrect type for assignment to dest
virtual void InvalidAs(const char *desiredtype) const;
// slot cannot be converted to desiredtype
There are additional methods which should be of use only to widget
drivers
like AWidget:
ASlot::ASlotPrefix,
GetSlotType,
LoadType,
\
ASlot::NewASlot, EnableFlags, DisableFlags,
GetFlags, SetName,
GetName,
SetAssign, ()()
virtual boolean EatString(const char *src)
virtual boolean EatAaction(const aaction *act)
virtual boolean EatATK(const ATK *obj)
virtual boolean EatAvalue(const avalue *v)
The EatXxxx methods have a value as an argument and
conspire to transform that value into one suitable for storage
in *this.
They return FALSE if that cannot be done.
In general, it is better to call EatXxxx(string) rather than
ReadValue because EatXxxx \
interprets TAGS at the beginning of the string
PROC:
NESS:
NESSEXPR:
STRING:
FILE:
no prefix
PROC: remainder of string is a proctable entry name
NESS: remainder of string is a ness function
NESSEXPR: remainder of string is a ness expression
STRING: remainder of string is the string value
FILE: remainder of string specifies a file
no prefix:
whole string is the string value
\enddata{text,538611048}
Download