home *** CD-ROM | disk | FTP | other *** search
- /**********************************************************************
- *
- * NAME: test.cpp
- *
- * DESCRIPTION: test program for Task++
- *
- * copyright (c) 1991 J. Alan Eldridge
- *
- * M O D I F I C A T I O N H I S T O R Y
- *
- * when who what
- * -------------------------------------------------------------------
- * May 91 J. Alan Eldridge created
- *
- * 10/11/91 JAE modified class Killer to use the
- * keyboard reading task
- *
- *********************************************************************/
-
- #include "aedef.h"
- #include "task.h"
-
- #include "keybdtsk.h"
-
- class Killer: public Task {
- public:
- Killer(char *name): Task(name)
- { }
- void TaskMain();
- };
-
- void
- Killer::TaskMain()
- {
- uchar ch;
-
- for (;;) {
- ch = '\r';
- KbdPipe.recv(ch, 15000);
- if (ch == 0 || ch == 0xE0) {
- KbdPipe >> ch;
- scheduler(0);
- } else {
- TaskKill(&KbdTask);
- break;
- }
- }
- printf("task %s returning\n", name());
- }
-
- class Sender: public Task {
- public:
- Sender(char *name): Task(name)
- { }
- void TaskMain();
- };
-
- class Receiver: public Task {
- public:
- Receiver(char *name): Task(name)
- { }
- void TaskMain();
- };
-
- class Numbers: virtual public ChildTask {
- private:
- int cnt;
- public:
- Numbers(char *name, int n): ChildTask(name), cnt(n)
- { }
- virtual void TaskMain();
- };
-
- //----------------------------------------------------------------------
- //
- // a word about this structure, its constructors, and member functions,
- // and the problems inherent in trying to queue something that has an
- // assignment operator (and a copy constructor, presumably) and a destructor:
- //
- // To be placed on a CPipe, an object should have defined:
- //
- // 1. a default constructor with no args
- // 2. an assignment operator taking an argument of type "type&"
- // 3. an explicit destructor
- //
- // When receiving from the CPipe, you'll need a variable of the
- // appropriate type... it will have been initialized by the default
- // constructor. The receive function will destruct it before doing
- // the assignment. If you timeout on a receive, it will not have
- // been destroyed, so that we keep an even balance of constructors
- // (assignments) and destructors. (I know this is a little complex,
- // but I had to figure it out by experiment myself... it's not that
- // easy to figure out what calls the compiler is going to generate.)
- //
-
- struct TN {
- char name[ 32 ];
- TN() { printf("TN:default constructor\n"); name[0] = 0; }
- TN(char *s) { printf("TN:char* constructor\n"); strcpy(name, s); }
- ~TN() { printf("TN:destroying\n"); name[0] = 0; }
- TN(TN &tn) { printf("TN:calling copy\n"); strcpy(name, tn.name); }
- TN &operator=(TN &tn) { printf("TN:calling assign\n");
- strcpy(name, tn.name); return *this; }
- };
-
- declare(CPipe_,TN);
- implement(CPipe_,TN);
-
- typedef CPipe(TN) TNPipe;
-
- TNPipe tnp(10);
-
- void
- Sender::TaskMain()
- {
- TN tn(name());
-
- for (int n = 0; n < 20; n++) {
- printf("task %s sending (%d)\n", name(), n);
- tnp << tn;
- printf("task %s returned (%d)\n", name(), n);
- }
-
- printf("task %s spawning Numbers task\n", name());
-
- Numbers *pn = new Numbers(name(), 5);
- pn->wait();
- delete pn;
-
- printf("task %s returning\n", name());
- }
-
- void
- Receiver::TaskMain()
- {
- TN tn;
-
- priority(2);
-
- for (;;) {
- printf("task %s receiving\n", name());
- if (tnp.recv(tn, 2000) < 1)
- break;
- printf("task %s received <%s>\n", name(), tn.name);
- }
- printf("task %s returning\n", name());
- }
-
- void
- Numbers::TaskMain()
- {
- for (int i = 0; i < cnt; i++) {
- printf("Numbers %2d\n", i);
- suspend();
- }
- }
-
- Killer k("Killer");
-
- Sender s2("Sender#2");
- Sender s1("Sender#1");
-
- Receiver r1("Receiver#1");
-
- main()
- {
- printf("scheduler() returned %d\n", scheduler());
- return 0;
- }
-