/[adonthell]/adonthell/src/event/listener.cc
ViewVC logotype

Diff of /adonthell/src/event/listener.cc

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.5 by ksterker, Tue Dec 7 16:46:27 2004 UTC revision 1.6 by ksterker, Tue Mar 8 09:43:36 2005 UTC
# Line 1  Line 1 
1  /*  /*
2     $Id$     $Id$
3    
4     Copyright (C) 2004 Kai Sterker <kaisterker@linuxgames.com>     Copyright (C) 2004/2005 Kai Sterker <kaisterker@linuxgames.com>
5     Part of the Adonthell Project http://adonthell.linuxgames.com     Part of the Adonthell Project http://adonthell.linuxgames.com
6    
7     Adonthell is free software; you can redistribute it and/or modify     Adonthell is free software; you can redistribute it and/or modify
8     it under the terms of the GNU General Public License as published by     it under the terms of the GNU General Public License as published by
9     the Free Software Foundation; either version 2 of the License, or     the Free Software Foundation; either version 2 of the License, or
10     (at your option) any later version.     (at your option) any later version.
11    
12     Adonthell is distributed in the hope that it will be useful,     Adonthell is distributed in the hope that it will be useful,
13     but WITHOUT ANY WARRANTY; without even the implied warranty of     but WITHOUT ANY WARRANTY; without even the implied warranty of
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15     GNU General Public License for more details.     GNU General Public License for more details.
16    
17     You should have received a copy of the GNU General Public License     You should have received a copy of the GNU General Public License
18     along with Adonthell; if not, write to the Free Software     along with Adonthell; if not, write to the Free Software
19     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  */  */
21    
22  /**  /**
23   * @file   event/listener.cc   * @file   event/listener.cc
24   * @author Kai Sterker <kaisterker@linuxgames.com>   * @author Kai Sterker <kaisterker@linuxgames.com>
25   *   *
26   * @brief  Declares the %listener class.   * @brief  Declares the %listener class.
27   *   *
28   */   */
29    
30  #include "python/pool.h"  #include "python/pool.h"
31  #include "event/manager.h"  #include "event/manager.h"
32  #include "event/listener.h"  #include "event/listener.h"
33    
34  using events::factory;  using events::factory;
35  using events::listener;  using events::listener;
36    
37  // Array with callbacks to return a newly instanciated event  // ctor
38  new_event listener::instanciate_event[MAX_EVENTS];  listener::listener (factory *f, event *e)
39    {
40  // ctor      Registered = false;
41  listener::listener (factory *f, event *e)      Method = NULL;
42  {      Args = NULL;
43      Registered = false;      Factory = f;
44      Method = NULL;      Event = e;
45      Args = NULL;      Paused = 0;
46      Factory = f;      Id = "";
47      Event = e;  }
48      Paused = 0;  
49      Id = "";  // destructor
50  }  listener::~listener ()
51    {
52  // destructor      // automatically remove myself from the event manager
53  listener::~listener ()      if (Registered) manager::remove (this);
54  {      // ... and from the factory
55      // automatically remove myself from the event manager      if (Factory) Factory->remove (this);
56      if (Registered) manager::remove (this);      
57      // ... and from the factory      delete Event;
58      if (Factory) Factory->remove (this);      
59            // we no longer use the callback
60      delete Event;      delete Method;
61            // ... and the arguments neither
62      // we no longer use the callback      Py_XDECREF (Args);
63      delete Method;  }
64      // ... and the arguments neither  
65      Py_XDECREF (Args);  // set python method to be called when the event occurs
66  }  bool listener::connect_callback (const string & file, const string & classname, const string & callback, PyObject *args)
67    {
68  // set python method to be called when the event occurs      u_int16 size;
69  bool listener::connect_callback (const string & file, const string & classname, const string & callback, PyObject *args)      
70  {      // cleanup
71      u_int16 size;      delete Method;
72            
73      // cleanup      // just disconnect the callback
74      delete Method;      if (file == "")
75            {
76      // just disconnect the callback          Method = NULL;
77      if (file == "")          return false;
78      {      }
79          Method = NULL;      
80          return false;      // create the callback
81      }      Method = python::pool::connect (EVENTS_DIR + file, classname, callback);
82            if (!Method)
83      // create the callback      {
84      Method = python::pool::connect (EVENTS_DIR + file, classname, callback);          fprintf (stderr, "*** listener::connect_callback: connecting callback failed!\n");
85      if (!Method)          return false;
86      {      }
87          fprintf (stderr, "*** listener::connect_callback: connecting callback failed!\n");      
88          return false;      // make sure the given arguments are a tuple
89      }      if (!args || !PyTuple_Check (args))
90            {
91      // make sure the given arguments are a tuple          if (args) fprintf (stderr, "*** warning: listener::connect_callback: argument must be a tuple!\n");
92      if (!args || !PyTuple_Check (args))          size = 2;
93      {      }
94          if (args) fprintf (stderr, "*** warning: listener::connect_callback: argument must be a tuple!\n");      else size = PyTuple_GET_SIZE (args) + 2;
95          size = 2;      
96      }      // keep old argument tuple, if possible
97      else size = PyTuple_GET_SIZE (args) + 2;      if (!Args || PyTuple_GET_SIZE (Args) != size)
98            {
99      // keep old argument tuple, if possible          // free old args
100      if (!Args || PyTuple_GET_SIZE (Args) != size)          Py_XDECREF (Args);
101      {  
102          // free old args          // prepare callback arguments
103          Py_XDECREF (Args);          Args = PyTuple_New (size);
104        
105          // prepare callback arguments          // first argument is the listener itself
106          Args = PyTuple_New (size);          PyTuple_SET_ITEM (Args, 0, python::pass_instance (this));
107            }
108          // first argument is the listener itself      
109          PyTuple_SET_ITEM (Args, 0, python::pass_instance (this));      // second argument will be the event that triggered the callback
110      }      for (u_int16 i = 2; i < size; i++)
111            {
112      // second argument will be the event that triggered the callback          // copy remaining arguments, if any
113      for (u_int16 i = 2; i < size; i++)          PyObject *arg =  PyTuple_GET_ITEM (args, i-2);
114      {          Py_INCREF (arg);
115          // copy remaining arguments, if any          PyTuple_SET_ITEM (Args, i, arg);
116          PyObject *arg =  PyTuple_GET_ITEM (args, i-2);      }
117          Py_INCREF (arg);      return true;
118          PyTuple_SET_ITEM (Args, i, arg);  }
119      }  
120      return true;  // execute callback for given event
121  }  s_int32 listener::raise_event (const event* evnt)
122    {
123  // execute callback for given event      if (Method && Event->repeat ())
124  s_int32 listener::raise_event (const event* evnt)      {
125  {          // make sure that arguments remain valid while the script executes
126      if (Method && Event->repeat ())          PyObject *args = Args;
127      {          Py_INCREF (args);
128          // make sure that arguments remain valid while the script executes          
129          PyObject *args = Args;          // event that triggered the script is 2nd argument of callback
130          Py_INCREF (args);          PyTuple_SET_ITEM (args, 1, python::pass_instance ((event*) evnt));
131                    
132          // event that triggered the script is 2nd argument of callback          // adjust repeat count
133          PyTuple_SET_ITEM (args, 1, python::pass_instance ((event*) evnt));          Event->do_repeat ();
134                    
135          // adjust repeat count          // execute callback
136          Event->do_repeat ();          Method->execute (args);
137                    
138          // execute callback          // clean up
139          Method->execute (args);          Py_DECREF (PyTuple_GET_ITEM (args, 1));
140                    Py_DECREF (args);
141          // clean up      }
142          Py_DECREF (PyTuple_GET_ITEM (args, 1));      else
143          Py_DECREF (args);      {
144      }          if (!Method) fprintf (stderr, "*** warning: listener::raise_event: no callback connected\n");
145      else          return 0;
146      {      }
147          if (!Method) fprintf (stderr, "*** warning: listener::raise_event: no callback connected\n");      
148          return 0;      // return whether event needs be repeated or not
149      }      return Event->repeat ();
150        }
151      // return whether event needs be repeated or not  
152      return Event->repeat ();  // disable the event temporarily
153  }  void listener::pause (const u_int16 & level)
154    {
155  // disable the event temporarily      if (Paused == 0) manager::remove (this);
156  void listener::pause (const u_int16 & level)      Paused += level;
157  {  }
158      if (Paused == 0) manager::remove (this);  
159      Paused += level;  // resume a disabled event
160  }  void listener::resume ()
161    {
162  // resume a disabled event      if (Paused == 0)
163  void listener::resume ()      {
164  {          fprintf (stderr, "*** warning: listener::resume: listener was not paused!\n");
165      if (Paused == 0)          if (!Registered) manager::add (this);
166      {      }
167          fprintf (stderr, "*** warning: listener::resume: listener was not paused!\n");      else
168          if (!Registered) manager::add (this);      {
169      }          Paused--;
170      else          if (Paused == 0) manager::add (this);
171      {      }
172          Paused--;  }
173          if (Paused == 0) manager::add (this);  
174      }  // save the state of the script associated with the event
175  }  void listener::put_state (base::flat & out) const
176    {
177  // save the state of the script associated with the event      base::flat listener;
178  void listener::put_state (base::flat & out) const      
179  {      listener.put_string ("lid", Id);
180      base::flat listener;      listener.put_uint16 ("lps", Paused);
181            listener.put_bool ("lmt", Method != NULL);
182      listener.put_string ("lid", Id);  
183      listener.put_uint16 ("lps", Paused);      if (Method != NULL)
184      listener.put_bool ("lmt", Method != NULL);      {
185            Method->put_state (listener);
186      if (Method != NULL)          python::put_tuple (Args, listener, 2);
187      {      }
188          Method->put_state (listener);      
189          python::put_tuple (Args, listener, 2);      listener.put_bool ("lev", Event != NULL);
190      }      if (Event != NULL) Event->put_state (listener);
191            
192      listener.put_bool ("lev", Event != NULL);      out.put_flat ("", listener);
193      if (Event != NULL) Event->put_state (listener);  }
194        
195      out.put_flat ("", listener);  // load the state of the script associated with the event
196  }  bool listener::get_state (base::flat & in)
197    {
198  // load the state of the script associated with the event      Id = in.get_string ("lid");
199  bool listener::get_state (base::flat & in)      Paused = in.get_uint16 ("lps");
200  {      
201      Id = in.get_string ("lid");      // load callback
202      Paused = in.get_uint16 ("lps");      if (in.get_bool ("lmt") == true)
203            {
204      // load callback          Method = new python::method ();
205      if (in.get_bool ("lmt") == true)          if (Method->get_state (in) == false)
206      {          {
207          Method = new python::method ();              fprintf (stderr, "*** listener::get_state: restoring callback failed!\n");
208          if (Method->get_state (in) == false)              return false;
209          {          }
210              fprintf (stderr, "*** listener::get_state: restoring callback failed!\n");          
211              return false;          Args = python::get_tuple (in, 2);
212          }          PyTuple_SET_ITEM (Args, 0, python::pass_instance (this));
213                }
214          Args = python::get_tuple (in, 2);  
215          PyTuple_SET_ITEM (Args, 0, python::pass_instance (this));      // load event structure
216      }      if (in.get_bool ("lev") == true)
217        {
218      // load event structure          std::string type = in.get_string ("etp");
219      if (in.get_bool ("lev") == true)          
220      {          // Instanciate an event of the given type
221          u_int8 type = in.get_uint8 ("etp");          Event = event_type::instanciate_event (type);
222            
223          // Instanciate an event of the given type          // try to load it
224          if (type < MAX_EVENTS && instanciate_event[type] != NULL)          if (Event == NULL || Event->get_state (in) == false)
225              Event = instanciate_event[type]();          {
226                fprintf (stderr, "*** listener::get_state: could not load event of type '%s'!\n", type.c_str ());
227          // try to load it              return false;
228          if (Event == NULL || Event->get_state (in) == false)          }    
229          {      }
230              fprintf (stderr, "*** listener::get_state: could not load event of type %i!\n", type);  
231              return false;      return in.success ();
232          }      }
233      }  
234    
     return in.success ();  
 }  
   
 // Register an event for loading  
 void listener::register_event (u_int8 type, new_event e)  
 {  
     if (type < MAX_EVENTS)  
         instanciate_event[type] = e;  
 }  
   

Legend:
Removed from v.1.5  
changed lines
  Added in v.1.6

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26