home *** CD-ROM | disk | FTP | other *** search
/ Monster Media 1994 #1 / monster.zip / monster / PROG_C / CL187A.ZIP / EXAMP505.CPP < prev    next >
C/C++ Source or Header  |  1994-03-15  |  13KB  |  692 lines

  1. // examp505.cpp
  2. // compile: bcc -ml examp505 cl pitem graphics.lib
  3. // Container Lite (CL v 1.87a)
  4. // (C) Copyright 1994  John Webster Small
  5. // All rights reserved
  6.  
  7. #include "pitem.h"
  8. #define BGI_PATHNAME "\\bc4\\bgi"
  9. #include "gconsole.cpp"
  10.  
  11. #define ID_Shape 1U
  12.  
  13. class Shape : public Mutual  {
  14.  
  15.     int x, y;
  16.  
  17.     void init(
  18.         // Shape level initializers with
  19.         // defaults provided for each
  20.         int x = GETRANDX(),
  21.         int y = GETRANDY()
  22.     )
  23.     { this->x = x; this->y = y; }
  24.  
  25. protected:
  26.  
  27.     void assign(const Shape& s)
  28.         { Streamable::assign
  29.         (*(const Streamable *)&s);
  30.         x = s.x; y = s.y; }
  31.     Shape(defaultConstructor)
  32.         : Mutual(defaultConstruct)
  33.         { init(); }
  34.     virtual int put(ostream& os);
  35.     int    get(istream& is);
  36.     static    MutuaL extract(istream& is);
  37.  
  38. public:
  39.  
  40.  
  41.     static  int register_Class()
  42.         { return clasSv.regClass
  43.         (Shape::extract,ID_Shape); }
  44.  
  45.     Shape(const Shape& s) : Mutual(defaultConstruct)
  46.         { init(); assign(s); }
  47.     Shape(int x = GETRANDX(),
  48.         int y = GETRANDY())
  49.         : Mutual()
  50.         { init(x,y); }
  51.     virtual    int operator=(const Streamable& s)
  52.         { return 0; }
  53.     virtual    unsigned ID() const
  54.         { return ID_Shape; }
  55.     int getx() { return x; }
  56.     int gety() { return y; }
  57.     Shape&  setxy(int x = GETRANDX(),
  58.         int y = GETRANDY())
  59.         { this->x = x; this->y = y;
  60.         return *this; }
  61.     virtual void show(int color = GETRANDCOLOR(),
  62.         int xxpose = 0, int yxpose = 0,
  63.         int scale = 1)
  64.         { PUTPIX(x,y,color); }
  65.     virtual char * name()
  66.         { return "shape (pixel)"; }
  67.     virtual    ~Shape()  {}
  68.  
  69. };    /*  class Shape  */
  70.  
  71.  
  72. int Shape::put(ostream& os)
  73. {
  74. //    if (Mutual::put(os))  {
  75.         os << x << endm << y << endm;
  76.         if (os)
  77.             return 1;  // success
  78. //    }
  79.     return 0;
  80. }
  81.  
  82. int Shape::get(istream& is)
  83. {
  84. //    if (Mutual::get(is))  {
  85.         is >> x >> nextm >> y >> nextm;
  86.         if (is)
  87.             return 1;
  88. //    }
  89.     return 0;
  90. }
  91.  
  92.  
  93. MutuaL Shape::extract(istream& is)
  94. {
  95.     Shape* S;
  96.     S = new Shape(defaultConstruct);
  97.     if (S) if (S->get(is))
  98.         return (MutuaL) S;
  99.     else 
  100.         delete S;
  101.     return  MutuaL0;
  102. }
  103.  
  104. #define ID_Circle 2U
  105.  
  106. class Circle : public Shape  {
  107.  
  108. protected:
  109.  
  110.     int radius;
  111.  
  112. private:
  113.  
  114.     void init(int radius =
  115.          GETRANDY()/8+1)
  116.         { this->radius = radius; }
  117.  
  118. protected:
  119.  
  120.     void assign(const Circle& c)
  121.         { Shape::assign(*(const Shape *)&c);
  122.         radius = c.radius; }
  123.     Circle(defaultConstructor)
  124.         : Shape(defaultConstruct)
  125.         { init(); }
  126.     virtual int put(ostream& os);
  127.     int    get(istream& is);
  128.     static    MutuaL extract(istream& is);
  129.  
  130. public:
  131.  
  132.     static  int register_Class()
  133.         { return clasSv.regClass
  134.         (Circle::extract,ID_Circle); }
  135.  
  136.     Circle(const Circle& s) : Shape(defaultConstruct)
  137.         { init(); assign(s); }
  138.     Circle(int radius
  139.             =  GETRANDY()/8+1,
  140.         int x =  GETRANDX(),
  141.         int y =  GETRANDY())
  142.         : Shape(x,y)
  143.         { init(radius); }
  144.     virtual    unsigned ID() const
  145.         { return ID_Circle; }
  146.     virtual void show(int color, int xxpose,
  147.         int yxpose, int scale)
  148.         {
  149.             SETCOLOR(color);
  150.             CIRCLE(getx()+xxpose,
  151.                 gety()+yxpose,
  152.                 (radius*scale));
  153.         }
  154.     virtual char * name() { return "circle"; }
  155.     virtual    ~Circle()  {}
  156.  
  157. };    /*  class Circle  */
  158.  
  159.  
  160. int Circle::put(ostream& os)
  161. {
  162.     if (Shape::put(os))  {
  163.         os << radius << endm;
  164.         if (os)
  165.             return 1;  // success
  166.     }
  167.     return 0;
  168. }
  169.  
  170. int Circle::get(istream& is)
  171. {
  172.     if (Shape::get(is))  {
  173.         is >> radius >> nextm;
  174.         if (is)
  175.             return 1;
  176.     }
  177.     return 0;
  178. }
  179.  
  180. MutuaL Circle::extract(istream& is)
  181. {
  182.     Circle* S;
  183.     S = new Circle(defaultConstruct);
  184.     if (S) if (S->get(is))
  185.         return (MutuaL) S;
  186.     else
  187.         delete S;
  188.     return  MutuaL0;
  189. }
  190.  
  191.  
  192.  
  193. #define ID_Rectangle 3U
  194.  
  195. class Rectangle : public Shape  {
  196.  
  197.     int width, heighth;
  198.  
  199.     void init(
  200.         int width =
  201.              GETRANDX()/4+1,
  202.         int heighth =
  203.              GETRANDY()/4+1
  204.     )
  205.         { this->width = width;
  206.         this->heighth = heighth; }
  207.  
  208. protected:
  209.  
  210.     void assign(const Rectangle& r)
  211.         { Shape::assign(*(const Shape *)&r);
  212.         width = r.width;
  213.         heighth = r.heighth; }
  214.     Rectangle(defaultConstructor)
  215.         : Shape(defaultConstruct)
  216.         { init(); }
  217.     virtual int put(ostream& os);
  218.     int    get(istream& is);
  219.     static    MutuaL extract(istream& is);
  220.  
  221. public:
  222.  
  223.     static  int register_Class()
  224.         { return clasSv.regClass
  225.         (Rectangle::extract,ID_Rectangle); }
  226.  
  227.     Rectangle(const Rectangle& s)
  228.         : Shape(defaultConstruct)
  229.         { init(); assign(s); }
  230.     Rectangle(int width =
  231.              GETRANDX()/4+1,
  232.         int heighth =
  233.              GETRANDY()/4+1,
  234.         int x =  GETRANDX(),
  235.         int y =  GETRANDY()
  236.         ) : Shape(x,y)
  237.         { init(width,heighth); }
  238.  
  239.     virtual    unsigned ID() const
  240.         { return ID_Rectangle; }
  241.     virtual void show(int color, int xxpose,
  242.         int yxpose, int scale);
  243.     virtual char * name() { return "rectangle"; }
  244.     virtual    ~Rectangle()  {}
  245.  
  246. };    /*  class Rectangle  */
  247.  
  248.  
  249. int Rectangle::put(ostream& os)
  250. {
  251.     if (Shape::put(os))  {
  252.         os << width << endm << heighth << endm;
  253.         if (os)
  254.             return 1;  // success
  255.     }
  256.     return 0;
  257. }
  258.  
  259. int Rectangle::get(istream& is)
  260. {
  261.     if (Shape::get(is))  {
  262.         is >> width >> nextm
  263.             >> heighth >> nextm;
  264.         if (is)
  265.             return 1;
  266.     }
  267.     return 0;
  268. }
  269.  
  270. MutuaL Rectangle::extract(istream& is)
  271. {
  272.     Rectangle* S;
  273.     S = new Rectangle(defaultConstruct);
  274.     if (S) if (S->get(is))
  275.         return (MutuaL) S;
  276.     else
  277.         delete S;
  278.     return  MutuaL0;
  279. }
  280.  
  281. void Rectangle::show(int color, int xxpose,
  282.     int yxpose, int scale)
  283. {
  284.     int dw = (width/2*scale);
  285.     int dh = (heighth/2*scale);
  286.     SETCOLOR(color);
  287.     RECTANGLE(getx()+xxpose - dw,
  288.         gety()+yxpose - dh,
  289.         getx()+xxpose + dw,
  290.         gety()+yxpose + dh);
  291. }
  292.  
  293.  
  294. #define ID_PieSlice 4U
  295.  
  296. class PieSlice : public Circle
  297.  
  298. {
  299.  
  300.     int startAngle, endAngle;
  301.  
  302.     void init(
  303.         int startAngle =
  304.             GETRANDANGLE(),
  305.         int endAngle =
  306.             GETRANDANGLE()
  307.     );
  308.  
  309. protected:
  310.  
  311.     void assign(const PieSlice& i)
  312.         { Circle::assign(*(const Circle *)&i);
  313.         startAngle = i.startAngle;
  314.         endAngle = i.endAngle; }
  315.         // PieSlice level assignment
  316.     PieSlice(defaultConstructor)
  317.         : Circle(defaultConstruct)
  318.         { init(); }
  319.     virtual int put(ostream& os);
  320.     int    get(istream& is);
  321.     static    MutuaL extract(istream& is);
  322.  
  323. public:
  324.  
  325.     static  int register_Class()
  326.         { return clasSv.regClass
  327.         (PieSlice::extract,ID_PieSlice); }
  328.  
  329.     PieSlice(const PieSlice& s)
  330.         : Circle(defaultConstruct)
  331.         { init(); assign(s); }
  332.     PieSlice    (
  333.         int startAngle =
  334.             GETRANDANGLE(),
  335.         int endAngle =
  336.             GETRANDANGLE(),
  337.         int radius
  338.             =  GETRANDY()/8+1,
  339.         int x =  GETRANDX(),
  340.         int y =  GETRANDY())
  341.         : Circle (radius,x,y)
  342.         { init(startAngle,endAngle); }
  343.  
  344.  
  345.     virtual    unsigned ID() const
  346.         { return ID_PieSlice; }
  347.     virtual void show(int color, int xxpose,
  348.         int yxpose, int scale)
  349.         {
  350.             SETCOLOR(color);
  351.             PIESLICE(getx()+xxpose,
  352.                 gety()+yxpose,
  353.                 startAngle,
  354.                 endAngle,
  355.                 (radius*scale));
  356.         }
  357.     virtual char * name() { return "pie-slice"; }
  358.     virtual    ~PieSlice()  {}
  359.  
  360. };    /*  class PieSlice  */
  361.  
  362.  
  363. void PieSlice::init(int startAngle,
  364.     int endAngle)
  365. {
  366.     if (startAngle > endAngle)  {
  367.         this->startAngle = startAngle;
  368.         this->endAngle = endAngle;
  369.     }
  370.     else {
  371.         this->startAngle = endAngle;
  372.         this->endAngle = startAngle;
  373.     }
  374. }
  375.  
  376. int PieSlice::put(ostream& os)
  377. {
  378.     if (Circle::put(os))  {
  379.         os << startAngle << endm
  380.             << endAngle << endm;
  381.         if (os)
  382.             return 1;
  383.     }
  384.     return 0;
  385. }
  386.  
  387. int PieSlice::get(istream& is)
  388. {
  389.     if (Circle::get(is))  {
  390.         is >> startAngle >> nextm
  391.             >> endAngle >> nextm;
  392.         if (is)
  393.             return 1;
  394.     }
  395.     return 0;
  396. }
  397.  
  398. MutuaL PieSlice::extract(istream& is)
  399. {
  400.     PieSlice * S;
  401.     S = new PieSlice(defaultConstruct);
  402.     if (S) if (S->get(is))
  403.         return (MutuaL) S;
  404.     else
  405.         delete S;
  406.     return  MutuaL0;
  407. }
  408.  
  409.  
  410. #if defined(CL_NO_TEMPLATES)
  411.     #define CL_ALL_DEF
  412.     CL_PITEM(Shape,Mutual)
  413.     #define ITEM Shape
  414.     #define CL Shapes
  415.     #include "cl.hf"
  416. #else
  417.     CL_PITEM(Shape,Mutual)
  418.     #define Shapes CL<Shape>
  419. #endif
  420.  
  421.  
  422.  
  423. #define ID_Segment 5U
  424.  
  425. #define SGM_MAXSHAPES 20
  426.  
  427. class Segment : public Shape
  428.  
  429.     , public Shapes
  430.  
  431. {
  432.  
  433.     void init() {}
  434.  
  435. protected:
  436.  
  437.     void assign(const Segment& i)
  438.         { Shape::assign(*(const Shape *)&i);
  439.         Shapes::assign(*(const Shapes *)&i); }
  440.     Segment(defaultConstructor)
  441.         : Shape(defaultConstruct)
  442.         , Shapes(defaultConstruct)
  443.         { init(); }
  444.     virtual int put(ostream& os);
  445.     int    get(istream& is);
  446.     static    MutuaL extract(istream& is);
  447.  
  448. public:
  449.  
  450.     static  int register_Class()
  451.         { return clasSv.regClass
  452.         (Segment::extract,ID_Segment); }
  453.  
  454.     Segment(const Segment& s)
  455.         : Shape(defaultConstruct)
  456.         , Shapes(defaultConstruct)
  457.         { init(); assign(s); }
  458.     Segment    (int x =  0, int y =  0,
  459.         unsigned flags = CL_ANDS,
  460.         unsigned maxNodes = SGM_MAXSHAPES,
  461.         unsigned limit = CL_LIMIT,
  462.         unsigned delta = CL_DELTA
  463.         ) : Shape (x,y)
  464.         , Shapes (flags,maxNodes,limit,delta)
  465.         { init(); }
  466.  
  467.     virtual unsigned restream();
  468.  
  469.     virtual    unsigned ID() const
  470.         { return ID_Segment; }
  471.     virtual void show(int color, int xxpose,
  472.         int yxpose, int scale);
  473.     virtual char * name() { return "segment"; }
  474.     virtual    ~Segment()  {}
  475.  
  476. };    /*  class Segment  */
  477.  
  478.  
  479. int Segment::put(ostream& os)
  480. {
  481.     if (Shape::put(os))
  482.         return Shapes::put(os);
  483.     return 0;
  484. }
  485.  
  486. int Segment::get(istream& is)
  487. {
  488.     if (Shape::get(is))
  489.         return Shapes::get(is);
  490.     return 0;
  491. }
  492.  
  493. MutuaL Segment::extract(istream& is)
  494. {
  495.     Segment * S;
  496.     S = new Segment(defaultConstruct);
  497.     if (S) if (S->get(is))
  498.         return (MutuaL) S;
  499.     else
  500.         delete S;
  501.     return  MutuaL0;
  502. }
  503.  
  504. unsigned Segment::restream()
  505. {
  506.     unsigned underFlow = 0;
  507.     for (unsigned i = 0; i < Shapes::Nodes(); i++)
  508.         underFlow += (atGet(i)->restream());
  509.     return (underFlow + Shape::restream());
  510. }
  511.  
  512. #pragma argsused
  513. void Segment::show(int color, int xxpose,
  514.     int yxpose, int scale)
  515. {
  516.     for (unsigned i = 0; i < Nodes(); i++)
  517.         atGet(i)->show(color,getx()+xxpose,
  518.             gety()+yxpose,scale);
  519. }
  520.  
  521.  
  522. #define ID_SegRef 6U
  523.  
  524. class SegRef : public Shape
  525.  
  526.  
  527. {
  528.  
  529.     Segment * S;
  530.     void discardS();
  531.     void init(Segment * S = 0);
  532.  
  533. protected:
  534.  
  535.     void assign(const SegRef& i);
  536.     SegRef(defaultConstructor)
  537.         : Shape(defaultConstruct)
  538.         { init(); }
  539.     virtual int put(ostream& os);
  540.     int    get(istream& is);
  541.     static    MutuaL extract(istream& is);
  542.  
  543. public:
  544.  
  545.     static  int register_Class()
  546.         { return clasSv.regClass
  547.         (SegRef::extract,ID_SegRef); }
  548.  
  549.     SegRef(const SegRef& s) : Shape(defaultConstruct)
  550.         { init(); assign(s); }
  551.     SegRef(Segment * S = 0,
  552.         int x = GETRANDX(),
  553.         int y = GETRANDY())
  554.         : Shape(x,y)
  555.         { init(S); }
  556.     virtual unsigned restream();
  557.     virtual    StreamablE clone() const
  558.         { return (StreamablE)
  559.         new SegRef(*this); }
  560.     virtual    unsigned ID() const
  561.         { return ID_SegRef; }
  562.     virtual void show(int color = GETRANDCOLOR(),
  563.         int xxpose = 0, int yxpose = 0,
  564.         int scale = 1)
  565.         { if (S) S->show(color,getx()+xxpose,
  566.         gety()+yxpose,scale); }
  567.     virtual char * name()
  568.         { return "segment reference"; }
  569.     virtual    ~SegRef() { discardS(); }
  570.  
  571. };    /*  class SegRef  */
  572.  
  573. void SegRef::discardS()
  574. {
  575.     if (S)  {
  576.         S->unlink(this);
  577.         if (!S->RefCount())
  578.             delete S;
  579.         S = 0;
  580.     }
  581. }
  582.  
  583. void SegRef::init(Segment * S)
  584. {
  585.     this->S = 0;
  586.     if (S) if (S->link(this))
  587.         this->S = S;
  588. }
  589.  
  590. void SegRef::assign(const SegRef& i)
  591. {
  592.     Shape::assign(*(const Shape *)&i);
  593.     discardS();
  594.     init(i.S);
  595. }
  596.  
  597. int SegRef::put(ostream& os)
  598. {
  599.     if (Shape::put(os))  {
  600.         int Sok;
  601.         os << (Sok = (S != 0)) << endm;
  602.         if (Sok)
  603.             os << *(MutuaL)S << endm;
  604.         if (os)
  605.             return 1;
  606.     }
  607.     return 0;
  608. }
  609.  
  610. int SegRef::get(istream& is)
  611. {
  612.     if (Shape::get(is))  {
  613.         int Sok;
  614.         is >> Sok >> nextm;
  615.         if (Sok)  {
  616.             MutuaL M;
  617.             is >> M >> nextm;
  618.             S = (Segment *)M;
  619.             if (S)
  620.                 S->link(this);
  621.         }
  622.         if (is)
  623.             return 1;
  624.     }
  625.     return 0;
  626. }
  627.  
  628. MutuaL SegRef::extract(istream& is)
  629. {
  630.     SegRef * S;
  631.     S = new SegRef(defaultConstruct);
  632.     if (S) if (S->get(is))
  633.         return (MutuaL) S;
  634.     else
  635.         delete S;
  636.     return  MutuaL0;
  637. }
  638.  
  639. unsigned SegRef::restream()
  640. {
  641.     unsigned underFlow = 0U;
  642.     if (S) if (S->StreamPos())
  643.         underFlow = S->restream();
  644.     return (underFlow + Shape::restream());
  645. }
  646.  
  647. #define  ShapesFile "shapes.tmp"
  648.  
  649. main()
  650. {
  651.     openGraphics();
  652.     Shapes sb(CL_ANDS,5);
  653.     Segment * S = new Segment();
  654.     if (!S)  {
  655.         closeGraphics();
  656.         return 1;
  657.     }
  658.     *S
  659.         << new PieSlice(60,300,
  660.             GETMAXY()/16,0,0)
  661.         << new Circle(GETMAXY()/8,0,0)
  662.         << new Rectangle(GETMAXX()/8,
  663.                 GETMAXY()/8,0,0);
  664.     SegRef * SR = new SegRef(S);
  665.     if (!SR)  {
  666.         delete S;
  667.         closeGraphics();
  668.         return 1;
  669.     }
  670.     sb << SR;
  671.     while (sb.insQ(SR = new SegRef(S)));
  672.     delete SR;
  673.     Register_Class(Shape);
  674.     Register_Class(Circle);
  675.     Register_Class(Rectangle);
  676.     Register_Class(PieSlice);
  677.     Register_Class(Segment);
  678.     Register_Class(SegRef);
  679.     sb.save(ShapesFile);
  680.     for (sb.setCurNode(); ++sb;
  681.         sb.get()->restream());
  682.     sb.allDel();
  683.     sb.load(ShapesFile);
  684.     Restream();
  685.     while (++sb)
  686.         sb.get()->show(GETRANDCOLOR());
  687.     cout << "Press <enter> to exit"  << endl;
  688.     (void) cin.get();
  689.     closeGraphics();
  690.     return 0;
  691. }
  692.