comparison anagram/guisupport/action.h @ 0:13d2b8934445

Import AnaGram (near-)release tree into Mercurial.
author David A. Holland
date Sat, 22 Dec 2007 17:52:45 -0500
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:13d2b8934445
1 /*
2 * AnaGram, A System for Syntax Directed Programming
3 * Copyright 1997-2002 Parsifal Software. All Rights Reserved.
4 * See the file COPYING for license and usage terms.
5 *
6 * action.h
7 */
8
9 #ifndef ACTION_H
10 #define ACTION_H
11
12 #include "agstack.h"
13
14
15 class AgAction {
16 public:
17
18 class Kernel {
19 private:
20 int useCount;
21 public:
22 virtual ~Kernel() {}
23 virtual void perform() const = 0;
24
25 Kernel() : useCount(0) {}
26 void lock() { useCount++; }
27 int unlock() { return --useCount <= 0; }
28 };
29
30 protected:
31 Kernel *kernel;
32 static int running;
33
34 static AgStack<AgAction> startupStack;
35
36 public:
37 AgAction() : kernel(0) {}
38 AgAction(AgAction::Kernel *kernel_) : kernel(kernel_) {
39 if (kernel) {
40 kernel->lock();
41 }
42 }
43 AgAction(const AgAction &a) : kernel(a.kernel) {
44 if (kernel) {
45 kernel->lock();
46 }
47 }
48 AgAction &operator = (const AgAction &a) {
49 if (kernel && kernel->unlock()) {
50 delete kernel;
51 }
52 kernel = a.kernel;
53 if (kernel) {
54 kernel->lock();
55 }
56 return *this;
57 }
58 ~AgAction() {
59 if (kernel && kernel->unlock()) {
60 delete kernel;
61 kernel = 0;
62 }
63 }
64 int exists() { return kernel != 0; }
65 void perform() const { if (kernel) kernel->perform(); }
66 void operator () () const { if (kernel) kernel->perform(); }
67 //void defer() const;
68 void performDeferred() const;
69 static void startup();
70 int operator < (const AgAction &a) const { return this < &a; }
71 };
72
73
74 template<class T>
75 class AgClassAction : public AgAction {
76 private:
77
78 class Kernel : public AgAction::Kernel {
79 private:
80 T &object;
81 void (T:: * memberFunction)();
82
83 public:
84 Kernel(T &object_, void (T:: * memberFunction_)()) :
85 object(object_) ,
86 memberFunction(memberFunction_)
87 {}
88 void perform() const {(object.*memberFunction)();}
89 };
90
91 public:
92 AgClassAction(T &object_, void (T:: * memberFunction_)()) :
93 AgAction(new AgClassAction<T>::Kernel(object_,memberFunction_))
94 {}
95 AgClassAction(const AgClassAction<T> &a) :
96 AgAction(a)
97 {}
98 };
99
100 template <class T>
101 AgAction actionObject(T *t, void (T:: * memberFunction)()) {
102 return AgClassAction<T>(*t, memberFunction);
103 }
104
105 void defer(void (*f)());
106
107 template <class T>
108 void defer(T *t, void (T:: * memberFunction)()) {
109 AgClassAction<T>(*t, memberFunction).performDeferred();
110 }
111
112 class AgSimpleAction : public AgAction {
113 private:
114
115 class Kernel : public AgAction::Kernel {
116 void (* function)();
117 public:
118 Kernel(void (* function_)()) :
119 function(function_)
120 {}
121 void perform() const {(*function)();}
122 };
123
124 public:
125 AgSimpleAction(void (* function_)()) :
126 AgAction(new AgSimpleAction::Kernel(function_))
127 {}
128 AgSimpleAction(const AgSimpleAction &a) :
129 AgAction(a)
130 {}
131 };
132
133 AgAction actionObject(void (* function)());
134
135
136 ////////////////////////////////////////////////////////////
137 //
138 // interaction with GUI event loop
139
140 // this must be provided by the GUI - see e.g. vaclgui/actionwin.cpp
141 // (not defined in action.cpp)
142 void AgActionEnqueueInGui(AgAction::Kernel *kernel);
143
144 // and the GUI should hand the object back to this function.
145 void AgActionDispatchFromGui(AgAction::Kernel *kernel);
146
147
148 #endif /* ACTION_H */