home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Supreme Volume 6 #1
/
swsii.zip
/
swsii
/
215
/
DDJ9210.ZIP
/
PLUGS.ASC
< prev
next >
Wrap
Text File
|
1992-08-26
|
14KB
|
496 lines
_OBJECT-ORIENTED PROGRAM CONSTRUCTION_
by William Wong
[LISTING ONE]
//***** PLUGS.H -- by William G. Wong, Copyright (c) June 1992 *****
#if !defined(_PLUGS_H_)
#define _PLUGS_H_
// ---- Plug Class Definition Macros ----
// DECLARE_CONNECTION(abstractPlug1,base1,abstractPlug2,base2)
// DECLARE_PLUG(plug,abstractPlug)
// DECLARE_REDIRECTOR(redirector,abstractPlug)
//
// ---- Plug Class Implementation Macros ----
// IMPLEMENT_PLUG(plug)
// void plug::afterConnect () {}
// void plug::beforeDisconnect () {}
// IMPLEMENT_SIMPLE_PLUG(plug)
// IMPLEMENT_REDIRECTOR(redirector)
//
// ---- plugCheck alternate definition ----
// Define a check macro if you want to check for invalid access using ->.
#if !defined(plugCheck)
#define plugCheck(ptr)
#endif
// ---- Simple plug macro definitions ----
#define IMPLEMENT_SIMPLE_PLUG(c1,p1)\
IMPLEMENT_PLUG(c1,p1)\
void c1::afterConnect () {}\
void c1::beforeDisconnect () {}
#if !defined(NULL)
#define NULL ((void *)0)
#endif
#if !defined(FALSE)
#define FALSE 0
#endif
#if !defined(TRUE)
#define TRUE 1
#endif
#define DECLARE_CONNECTION(p1,b1,p2,b2)\
class p1##HiddenRedirector;\
class p2##HiddenRedirector;\
class p2;\
DECLARE_ABSTRACT_PLUG(p1,b1,p1##HiddenRedirector,p2)\
DECLARE_ABSTRACT_PLUG(p2,b2,p2##HiddenRedirector,p1)\
DECLARE_ABSTRACT_REDIRECTOR(p1##HiddenRedirector,p1)\
DECLARE_ABSTRACT_REDIRECTOR(p2##HiddenRedirector,p2)
#define DECLARE_ABSTRACT_PLUG(p1,b1,r1,p2)\
typedef r1 rd##p1 ;\
typedef p2 px##p1 ;\
class p1 : public b1\
{\
friend class r1;\
friend class p2;\
public:\
virtual ~p1 () {-- * this;}\
virtual int isRedirector () = 0 ;\
virtual int connected () = 0 ;\
virtual int usable () = 0 ;\
virtual void operator <= (px##p1 & newEnd) = 0 ;\
virtual px##p1 * operator -> () = 0 ;\
virtual px##p1 * operator - () = 0 ;\
virtual void operator -- () = 0 ;\
virtual void afterConnect () = 0 ;\
virtual void beforeDisconnect () = 0 ;\
virtual void addBefore ( px##p1 * inner, p1 * newEnd ) = 0 ;\
virtual void addAfter ( px##p1 * inner, p1 * newEnd ) = 0 ;\
virtual rd##p1 * getRedirector() = 0 ;\
virtual void setRedirector ( rd##p1 * newRedirector ) = 0 ;\
virtual p1 * connectedto ( px##p1 * newEnd ) = 0 ;\
virtual void disconnectedFree () = 0 ;\
virtual void disconnected () = 0 ;\
};
#define DECLARE_ABSTRACT_REDIRECTOR(r1,p1)\
class r1 : public p1\
{\
public:\
virtual p1 * operator = ( p1 * newPlug ) = 0 ;\
virtual void resetRedirection () = 0 ;\
};
#define DECLARE_PLUG(c1,p1)\
class c1 : public p1\
{\
public:\
c1 () {myPlug=NULL;myRedirector=NULL;}\
virtual ~c1 () {-- (* this);}\
virtual int isRedirector () {return TRUE;}\
virtual int connected () ;\
virtual int usable () ;\
virtual void operator <= (px##p1 & newEnd) ;\
virtual px##p1 * operator -> () ;\
virtual px##p1 * operator - () ;\
virtual void operator -- () ;\
virtual void addBefore ( px##p1 * inner, p1 * newEnd ) ;\
virtual void addAfter ( px##p1 * inner, p1 * newEnd ) ;\
virtual rd##p1 * getRedirector () ;\
virtual void setRedirector ( rd##p1 * newRedirector ) ;\
virtual p1 * connectedto ( px##p1 * newEnd ) ;\
virtual void disconnectedFree () ;\
virtual void disconnected () ;\
virtual void afterConnect () ;\
virtual void beforeDisconnect () ;\
rd##p1 * myRedirector ;\
px##p1 * myPlug ;\
};
#define DECLARE_REDIRECTOR(r1,p1)\
class r1 : public p1##HiddenRedirector\
{\
public:\
virtual p1 * operator = ( p1 * newPlug ) ;\
virtual void resetRedirection () ;\
r1 () {myPlug=NULL;myRedirector=NULL;}\
virtual ~r1 () {(* this) = NULL;}\
virtual int isRedirector () {return TRUE;}\
virtual int connected () ;\
virtual int usable () ;\
virtual void operator <= (px##p1 & newEnd) ;\
virtual px##p1 * operator -> () ;\
virtual px##p1 * operator - () ;\
virtual void operator -- () ;\
virtual void addBefore ( px##p1 * inner, p1 * newEnd ) ;\
virtual void addAfter ( px##p1 * inner, p1 * newEnd ) ;\
virtual rd##p1 * getRedirector() ;\
virtual void setRedirector ( rd##p1 * newRedirector ) ;\
virtual p1 * connectedto ( px##p1 * newEnd ) ;\
virtual void disconnectedFree () ;\
virtual void disconnected () ;\
virtual void afterConnect () ;\
virtual void beforeDisconnect () ;\
rd##p1 * myRedirector ;\
p1 * myPlug ;\
};
// ---- Implementation definitions ----
#define IMPLEMENT_PLUG(c1,p1)\
int c1::connected () {return myPlug != NULL;}\
int c1::usable () {return TRUE;}\
void c1::operator <= (px##p1 & newEnd)\
{\
if (myPlug != NULL)\
myPlug -> disconnectedFree () ;\
if ((& newEnd) != NULL)\
{\
myPlug = newEnd.connectedto ( this ) ;\
if (myPlug)\
{\
(*myPlug).afterConnect();\
(*this).afterConnect() ;\
}\
}\
}\
px##p1 * c1::operator -> () {return myPlug;}\
px##p1 * c1::operator - ()\
{\
px##p1 * prior = myPlug ;\
if ( prior != NULL )\
{\
beforeDisconnect();\
prior -> beforeDisconnect();\
disconnected () ;\
prior -> disconnected () ;\
}\
return prior ;\
}\
void c1::operator -- ()\
{\
px##p1 * prior = - (* this) ;\
if (prior) prior -> disconnectedFree () ;\
}\
void c1::addBefore ( px##p1 * inner, p1 * newEnd )\
{\
rd##p1 * oldRedirector = myRedirector ;\
addAfter ( inner, newEnd ) ;\
if (oldRedirector!=NULL)\
{\
oldRedirector -> resetRedirection () ;\
(* oldRedirector) = newEnd ;\
}\
}\
void c1::addAfter ( px##p1 * inner, p1 * newEnd )\
{\
if (myPlug && newEnd)\
(* newEnd) <= (* (- (* this))) ;\
(* this) <= (* inner) ;\
}\
rd##p1 * c1::getRedirector () {return myRedirector;}\
void c1::setRedirector ( rd##p1*newRedirector ) {myRedirector=newRedirector;}\
p1 * c1::connectedto ( px##p1 * newEnd )\
{\
if (myPlug)\
-- (* myPlug) ;\
myPlug = newEnd ;\
return this ;\
}\
void c1::disconnectedFree () {myPlug=NULL;}\
void c1::disconnected () {myPlug=NULL;}
// ---- Define for redirector methods -----
#define IMPLEMENT_REDIRECTOR(r1,p1)\
p1 * r1::operator = ( p1 * newPlug )\
{\
p1 * prior = myPlug ;\
resetRedirection () ;\
if (newPlug != NULL)\
{\
myPlug = newPlug ;\
newPlug -> setRedirector(this) ;\
}\
return prior ;\
}\
void r1::resetRedirection () {myPlug=NULL;}\
int r1::connected ()\
{ return (myPlug == NULL) ? FALSE : myPlug -> connected () ; }\
int r1::usable ()\
{ return (myPlug == NULL) ? FALSE : myPlug -> usable () ; }\
void r1::operator <= (px##p1 & newEnd)\
{if (myPlug) (* myPlug) <= newEnd ;}\
px##p1 * r1::operator -> ()\
{return (myPlug) ? myPlug -> operator -> () : NULL ;}\
px##p1 * r1::operator - ()\
{return (myPlug) ? - * myPlug : NULL ;}\
void r1::operator -- ()\
{if (myPlug) -- * myPlug ;}\
void r1::addBefore ( px##p1 * inner, p1 * newEnd )\
{\
if (myPlug)\
{\
myPlug -> setRedirector (NULL) ;\
(* myPlug).addBefore ( inner, newEnd ) ;\
}\
if (newEnd)\
newEnd -> setRedirector ( this ) ;\
myPlug = newEnd ;\
}\
void r1::addAfter ( px##p1 * inner, p1 * newEnd )\
{\
if (myPlug)\
(* myPlug).addAfter ( inner, newEnd ) ;\
}\
rd##p1 * r1::getRedirector () {return myRedirector;}\
void r1::setRedirector ( rd##p1 * newRedirector )\
{myRedirector=newRedirector;}\
p1 * r1::connectedto ( px##p1 * newEnd )\
{return (myPlug) ? (* myPlug).connectedto(newEnd) : NULL ;}\
void r1::disconnectedFree ()\
{if (myPlug) myPlug -> disconnectedFree();}\
void r1::disconnected ()\
{if (myPlug) myPlug -> disconnected();}\
void r1::afterConnect ()\
{if (myPlug) myPlug -> afterConnect();}\
void r1::beforeDisconnect ()\
{if (myPlug) myPlug -> beforeDisconnect();}
#endif
[LISTING TWO]
// *** PLUGS.CPP--Example of Use of Plugs by WIlliam G. Wong Copyright 1992 ***
// ****************************************************************
#include "plugs.h"
// ==== Class definitions ====
//
// These definitions are normally found in a header file.
//
// ---- Simple abstract plug that can link to objects link itself ----
class plugXBase // simple accessible class
{
public :
int plugXBaseCommonItem ;
} ;
class plugYBase {} ; // nothing provided here
// plug used to access plugXBase only
// ---- Declare plugs ----
DECLARE_CONNECTION(plugX,plugXBase,plugY,plugYBase)
DECLARE_PLUG(aPlugX,plugX)
DECLARE_PLUG(aPlugY,plugY)
DECLARE_REDIRECTOR(plugXRedirector,plugX)
// ---- Dynamic allocation example ----
//
// This pair of plug classes work like plugX except that a single
// plug creates a new object each time a connection is made. The
// plug object is freed when the connection is broken.
//
// Both <= and connectedto must be redefined because a connection
// will come through one or the other depending upon which side the
// multiPlugX object is when the initial connection is initiated.
class dynamicPlugX : public aPlugX
{
public:
void disconnectedFree () { delete this ; } ;
} ;
class multiPlugX : public aPlugX
{
public:
void operator <= ( plugY & newEnd )
{ newEnd <= * new dynamicPlugX ; }
plugX * connectedto ( plugY * newEnd )
{ return (* new dynamicPlugX).connectedto ( newEnd ) ; }
};
// ---- sample1 to sample2 connection ----
class sample1Base
{
public:
aPlugX x, y ;
} ;
class sample2Base {} ;
// ---- Declare plugs ----
DECLARE_CONNECTION(Sample1,sample1Base,Sample2,sample2Base)
DECLARE_PLUG(sample1,Sample1)
DECLARE_PLUG(sample2,Sample2)
// ---- A slightly more complex plug base ----
class myPlugBase
{
public:
int i ;
virtual void read ( int x ) { i = x ; } ;
virtual void write ( int x ) { i = x ; } ;
myPlugBase () { i = 1 ; } ;
} ;
// ---- Declare plugs ----
DECLARE_CONNECTION(MyPlug1,myPlugBase,MyPlug2,myPlugBase)
DECLARE_PLUG(myPlug1,MyPlug1)
DECLARE_PLUG(myPlug2,MyPlug2)
// ==== Implementation Definitions ====
IMPLEMENT_PLUG(aPlugX,plugX)
IMPLEMENT_PLUG(aPlugY,plugY)
void aPlugX::afterConnect ()
{
// initial connection code goes here
}
void aPlugX::beforeDisconnect ()
{
// disconnect code goes here
}
void aPlugY::afterConnect ()
{
// initial connection code goes here
}
void aPlugY::beforeDisconnect ()
{
// disconnect code goes here
}
IMPLEMENT_REDIRECTOR(plugXRedirector,plugX)
// ---- Implementation for simple plugs ----
//
// Generates null afterConnect and beforeDisconnect functions.
IMPLEMENT_SIMPLE_PLUG(sample1,Sample1)
IMPLEMENT_SIMPLE_PLUG(sample2,Sample2)
// ---- Implementat plugs ----
//
// myPlug1a and myPlug1b redifine methods from the base class.
IMPLEMENT_SIMPLE_PLUG(myPlug1,MyPlug1)
IMPLEMENT_SIMPLE_PLUG(myPlug2,MyPlug2)
class myPlug1a : public myPlug1
{
public :
int i1 ;
virtual void write ( int x ) { i1 = x ; } ;
} ;
class myPlug2a : public myPlug2
{
public :
int i2 ;
virtual void write ( int x ) { i2 = x ; } ;
} ;
// ==== Sample program ====
void test ( myPlug1 & pp1 )
{
aPlugX x1, x2, x3 ;
plugX * ppx ;
plugXRedirector rx1, rx2 ;
aPlugY y1, y2, y3 ;
sample1 s1 ;
sample2 s2 ;
myPlug1a p1 ;
myPlug2a p2 ;
multiPlugX mpx ;
// ---- General connections ----
x1 <= y1 ; // connect x1 and y1
y1 <= x2 ; // disconnect x1
// connect y1 and x2
s1 <= s2 ; // connect types must match
// ---- Compound linkages ----
s2 -> x <= y1 ; // linking s1.x to y1
s2 -> y <= y2 ; // linking s2.y to y2
// ---- Redirector examples ----
rx1 = & x1 ; // setup redirector
rx1 <= y1 ; // connect x1 to y1 through r1
y1 -> plugXBaseCommonItem = 1 ;
// access item at other end
rx1.addBefore ( & y2, & x3 ) ;// rx1 redirects x3, x1 connected to y2
// and x3 is attached to y1
rx2 = & x3 ; // setup a different redirector type
rx2 <= y2 ; // connects y2 to x3 through r2
rx2 = NULL ; // reset redirector
// ---- Multiplug examples ----
// This generates two new objects and deletes them when they are
// no longer of use. Note how pp is used to keep around a reference
// to (mp<=a) (the one created for a) which is later used to link to c.
mpx <= y1 ; // y1 connected to new object
mpx <= y2 ; // y2 connected to different object
ppx = - y1 ; // disconnect but keep around object
(* ppx ) <= y3 ; // link object to y3
-- x2 ; // free up the other end of x2
ppx = - y3 ; // - disconnects and returns pointer
-- * ppx ; // -- * frees result
// ---- Plugs with different variables or methods ----
p1 <= p2 ;
p1 -> read ( p1 -> i ) ; // using read and i from p2
pp1 <= p2 ; // connects pp1 to p2
// disconnects p1
// ---- Explicit disconnects ----
-- s2 ; // forced disconnect
-- s1 ;
if (x1.connected()) // determine if connection exists
-- x1 ;
// ---- Implicit disconnects for locally defined objects ----
}
// ------------main()--------
void main ()
{
myPlug1a p1 ;
test ( p1 ) ;
}
================================================================