Mercurial > ~dholland > hg > ag > index.cgi
view anagram/guisupport/action.h @ 15:f5acaf0c8a29
Don't cast through "volatile int". Causes a gcc warning nowadays.
XXX: should put something else back here to frighten the optimizer
author | David A. Holland |
---|---|
date | Tue, 31 May 2022 01:00:55 -0400 |
parents | 13d2b8934445 |
children |
line wrap: on
line source
/* * AnaGram, A System for Syntax Directed Programming * Copyright 1997-2002 Parsifal Software. All Rights Reserved. * See the file COPYING for license and usage terms. * * action.h */ #ifndef ACTION_H #define ACTION_H #include "agstack.h" class AgAction { public: class Kernel { private: int useCount; public: virtual ~Kernel() {} virtual void perform() const = 0; Kernel() : useCount(0) {} void lock() { useCount++; } int unlock() { return --useCount <= 0; } }; protected: Kernel *kernel; static int running; static AgStack<AgAction> startupStack; public: AgAction() : kernel(0) {} AgAction(AgAction::Kernel *kernel_) : kernel(kernel_) { if (kernel) { kernel->lock(); } } AgAction(const AgAction &a) : kernel(a.kernel) { if (kernel) { kernel->lock(); } } AgAction &operator = (const AgAction &a) { if (kernel && kernel->unlock()) { delete kernel; } kernel = a.kernel; if (kernel) { kernel->lock(); } return *this; } ~AgAction() { if (kernel && kernel->unlock()) { delete kernel; kernel = 0; } } int exists() { return kernel != 0; } void perform() const { if (kernel) kernel->perform(); } void operator () () const { if (kernel) kernel->perform(); } //void defer() const; void performDeferred() const; static void startup(); int operator < (const AgAction &a) const { return this < &a; } }; template<class T> class AgClassAction : public AgAction { private: class Kernel : public AgAction::Kernel { private: T &object; void (T:: * memberFunction)(); public: Kernel(T &object_, void (T:: * memberFunction_)()) : object(object_) , memberFunction(memberFunction_) {} void perform() const {(object.*memberFunction)();} }; public: AgClassAction(T &object_, void (T:: * memberFunction_)()) : AgAction(new AgClassAction<T>::Kernel(object_,memberFunction_)) {} AgClassAction(const AgClassAction<T> &a) : AgAction(a) {} }; template <class T> AgAction actionObject(T *t, void (T:: * memberFunction)()) { return AgClassAction<T>(*t, memberFunction); } void defer(void (*f)()); template <class T> void defer(T *t, void (T:: * memberFunction)()) { AgClassAction<T>(*t, memberFunction).performDeferred(); } class AgSimpleAction : public AgAction { private: class Kernel : public AgAction::Kernel { void (* function)(); public: Kernel(void (* function_)()) : function(function_) {} void perform() const {(*function)();} }; public: AgSimpleAction(void (* function_)()) : AgAction(new AgSimpleAction::Kernel(function_)) {} AgSimpleAction(const AgSimpleAction &a) : AgAction(a) {} }; AgAction actionObject(void (* function)()); //////////////////////////////////////////////////////////// // // interaction with GUI event loop // this must be provided by the GUI - see e.g. vaclgui/actionwin.cpp // (not defined in action.cpp) void AgActionEnqueueInGui(AgAction::Kernel *kernel); // and the GUI should hand the object back to this function. void AgActionDispatchFromGui(AgAction::Kernel *kernel); #endif /* ACTION_H */