Adonthell 0.4

event.cc

Go to the documentation of this file.
00001 /*
00002    $Id: event.cc,v 1.23 2003/02/10 20:01:13 ksterker Exp $
00003 
00004    Copyright (C) 2000/2001/2002/2003 Kai Sterker <kaisterker@linuxgames.com>
00005    Part of the Adonthell Project http://adonthell.linuxgames.com
00006 
00007    This program is free software; you can redistribute it and/or modify
00008    it under the terms of the GNU General Public License.
00009    This program is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY.
00011 
00012    See the COPYING file for more details.
00013 */
00014 
00015 /**
00016  * @file   event.cc
00017  * @author Kai Sterker <kaisterker@linuxgames.com>
00018  * 
00019  * @brief  Defines the base event class.
00020  */
00021 
00022 #include "event.h"
00023 #include "event_handler.h"
00024 
00025 // constructor
00026 event::event ()
00027 {
00028     Action = ACTION_NOTHING;
00029     Registered = false;
00030     Paused = false;
00031     Repeat = -1;
00032     Script = NULL;
00033     PyFunc = NULL;
00034     Args = NULL;
00035     List = NULL;
00036     Id = "";
00037 }
00038 
00039 // destructor
00040 event::~event ()
00041 {
00042     // automatically remove myself from the event_handler
00043     if (Registered) event_handler::remove_event (this);
00044     
00045     // ... and from the event_list
00046     if (List) List->remove_event (this);
00047         
00048     clear ();
00049 }
00050 
00051 // cleanup
00052 void event::clear ()
00053 {
00054     switch (Action)
00055     {
00056         // script attached
00057         case ACTION_SCRIPT:
00058         {
00059             delete Script;
00060             Py_XDECREF (Args);
00061             Args = NULL;
00062             Script = NULL;
00063             
00064             break;
00065         }
00066         
00067         // python callback attached
00068         case ACTION_PYFUNC:
00069         {
00070             delete PyFunc;
00071             PyFunc = NULL;
00072             
00073             break;
00074         }
00075         
00076         default: break;
00077     }
00078     
00079     Action = ACTION_NOTHING;
00080 }
00081 
00082 // set a script as event's action
00083 void event::set_script (std::string filename, PyObject * args)
00084 {
00085     // cleanup
00086     clear ();
00087     
00088     if (filename == "") return;
00089     
00090     Py_XINCREF (args);
00091     Args = args; 
00092        
00093     u_int16 argssize = args == NULL ? 1 : PyTuple_Size (args) + 1; 
00094     PyObject *theargs = PyTuple_New (argssize);
00095         
00096     // We can pass_instance directly 'cause PyTuple_SetItem steals a
00097     // reference to the result of pass_instance.
00098     PyTuple_SetItem (theargs, 0, python::pass_instance (this, "event"));
00099     for (u_int16 i = 1; i < argssize; i++)
00100     {
00101         PyObject *intref = PyTuple_GetItem (args, i - 1);
00102         Py_INCREF (intref); 
00103         PyTuple_SetItem (theargs, i, intref); 
00104     }
00105     
00106     Script = new py_object;
00107     Script->create_instance (EVENTS_DIR + filename, filename, theargs);
00108     Py_DECREF (theargs);
00109         
00110     Action = ACTION_SCRIPT;
00111 }
00112 
00113 // set a python callback as event's action
00114 void event::set_callback (PyObject *callback, PyObject *args)
00115 {
00116     // cleanup
00117     clear ();
00118     
00119     // create the callback
00120     PyFunc = new py_callback (callback, args);
00121     
00122     // tell the event what to do    
00123     Action = ACTION_PYFUNC;
00124 }
00125 
00126 // set a C/C++ callback as event's action
00127 void event::set_callback (const Functor0 & callback)
00128 {
00129     // cleanup
00130     clear ();
00131 
00132     Callback = callback;
00133     Action = ACTION_CPPFUNC;
00134 }
00135 
00136 // save the state of the script associated with the event
00137 void event::put_state (ogzstream & file) const
00138 {
00139     Type >> file;
00140     // Id >> file;
00141     Repeat >> file;
00142     Paused >> file;
00143     Action >> file;
00144     
00145     switch (Action)
00146     {
00147         // save script
00148         case ACTION_SCRIPT:
00149         {
00150             Script->class_name () >> file;
00151     
00152             if (Args)
00153             {
00154                 true >> file;
00155                 python::put_tuple (Args, file);
00156             }
00157             else false >> file;
00158             
00159             return;
00160         }
00161         
00162         // save python callback
00163         case ACTION_PYFUNC:
00164         {
00165             PyFunc->put_state (file);
00166             return;
00167         }
00168         
00169         default: return;
00170     }
00171 }
00172 
00173 // load the state of the script associated with the event 
00174 bool event::get_state (igzstream & file) 
00175 {
00176     // Note that »Type« is already read by event_list::load to
00177     // determine what event subclass to instanciate
00178     // Id << file;
00179     Repeat << file;
00180     Paused << file;
00181     Action << file;
00182     
00183     switch (Action)
00184     {
00185         // load script from file
00186         case ACTION_SCRIPT:
00187         {
00188             std::string name;
00189             bool has_args;
00190             PyObject * args = NULL;
00191 
00192             name << file;
00193             has_args << file;
00194     
00195             if (has_args) args = python::get_tuple (file);
00196     
00197             set_script (name, args);
00198             Py_XDECREF (args);
00199     
00200             return true;
00201         }
00202         
00203         // load python callback from file
00204         case ACTION_PYFUNC:
00205         {
00206             PyFunc = new py_callback;
00207             return PyFunc->get_state (file); 
00208         }
00209         
00210         default: return true;
00211     }
00212     
00213     return false;
00214 }
00215 
00216 // the event_list this event is kept in
00217 void event::set_list (event_list *l)
00218 {
00219     List = l;
00220 }
00221 
00222 // disable the event temporarily
00223 void event::pause ()
00224 {
00225     event_handler::remove_event (this);
00226     Paused = true;
00227 }
00228 
00229 // resume a disabled event
00230 void event::resume ()
00231 {
00232     event_handler::register_event (this);
00233     Paused = false;
00234 }
00235 
00236 // repeat an event
00237 s_int32 event::do_repeat ()
00238 {
00239     if (Repeat > 0) Repeat--;
00240     
00241     return Repeat;
00242 }