1 
2 #ifndef HOOK_HPP
3 #define HOOK_HPP
4 
5 /* "Species" - a CoreWars evolver.  Copyright (C) 2003 'Varfar'
6  *
7  * This program is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU General Public License as published by the Free
9  * Software Foundation; either version 1, or (at your option) any later
10  * version.
11  *
12  * This program is distributed in the hope that it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15  * more details.
16  *
17  * You should have received a copy of the GNU General Public License along
18  * with this program; if not, write to the Free Software Foundation, Inc.,
19  * 675 Mass Ave, Cambridge, MA 02139, USA.
20  */
21 
22 // forwards
23 class CSpecies;
24 class CGenus;
25 class CHookable;
26 
27 /** class CHook
28  * This thin class provides a way to attach event listeners or information to objects in the Species hierarchy.
29  * Each genus and species can have a single hook attached.
30  * Important: The genus or species that has the hook attached 'owns' it.  You should not delete hooks elsewhere.
31  * When you assign a hook (or *0) to an object, the old hook will be deleted if set.
32  **/
33 class CHook {
34 	friend class CHookable;
35 	public:
~CHook()36 		virtual ~CHook() {}
37 		// actual event callbacks; override to listen in
38 	protected:
on_fight(const CSpecies &,const CSpecies &)39 		virtual void on_fight(const CSpecies &/*self*/,const CSpecies &/*other*/) {}
on_fight(const CGenus &,const CGenus &)40 		virtual void on_fight(const CGenus &/*self*/,const CGenus &/*other*/) {}
on_reproduction(const CSpecies &)41 		virtual void on_reproduction(const CSpecies &/*self*/) {}
on_reproduction(const CGenus &)42 		virtual void on_reproduction(const CGenus &/*self*/) {}
43 };
44 
45 /** class CHookable
46  * to make an object 'hookable', simply derive from this class.  In your code, call the appropriate notifiers
47  **/
48 class CHookable {
49 	public:
hook() const50 		CHook *hook() const { return _hook; }
has_hook() const51 		bool has_hook() const { return 0 != _hook; }
hook(CHook * newhook)52 		void hook(CHook *newhook) { delete _hook; _hook = newhook; }
53 	protected:
CHookable()54 		CHookable() { _hook = 0; }
~CHookable()55 		~CHookable() { delete _hook; }
notify_hook_fight(const CSpecies & self,const CSpecies & other)56 		void notify_hook_fight(const CSpecies &self,const CSpecies &other) {
57 			if(0 != _hook)
58 				_hook->on_fight(self,other);
59 		}
notify_hook_fight(const CGenus & self,const CGenus & other)60 		void notify_hook_fight(const CGenus &self,const CGenus &other) {
61 			if(0 != _hook)
62 				_hook->on_fight(self,other);
63 		}
notify_reproduction(const CSpecies & self)64 		void notify_reproduction(const CSpecies &self) {
65 			if(0 != _hook)
66 				_hook->on_reproduction(self);
67 		}
notify_reproduction(const CGenus & self)68 		void notify_reproduction(const CGenus &self) {
69 			if(0 != _hook)
70 				_hook->on_reproduction(self);
71 		}
72 	private:
73 		CHook *_hook;
74 };
75 
76 #endif // ifndef HOOK_HPP
77 
78 
79