Main Page   Namespace List   Class Hierarchy   Compound List   File List   Compound Members   File Members  

world_template.h

Go to the documentation of this file.
00001 /*
00002         $Id: world_template.h,v 1.10 2001/03/20 13:22:20 mbn Exp $
00003 
00004         ------------------------------------------------------------------------
00005         ClanLib, the platform independent game SDK.
00006 
00007         This library is distributed under the GNU LIBRARY GENERAL PUBLIC LICENSE
00008         version 2. See COPYING for details.
00009 
00010         For a total list of contributers see CREDITS.
00011 
00012         ------------------------------------------------------------------------
00013 */
00014 
00015 #ifndef header_world_template
00016 #define header_world_template
00017 
00019 
00020 #include "../Core/System/cl_assert.h"
00021 #include "netobject_channel.h"
00022 #include "netobject.h"
00023 
00024 template<class World>
00025 class CL_GameObject
00026 //: Game object template.
00027 {
00028 // Predefined message types:
00029 public:
00030         enum EGameObjectMessageTypes
00031         {
00032                 msgtype_full_update = 0,
00033                 msgtype_tick_update = 1,
00034                 msgtype_destroy     = 2,
00035                 msgtype_user        = 1000 // reserve first 1000 entries for clanlib.
00036         };
00037 
00039 public:
00040         // server constructor.
00041         CL_GameObject(World *world, int object_type)
00042         : world(world), object_type(object_type), netobject(object_type, &world->get_netobject_channel())
00043         {
00044                 common_init();
00045         }
00046 
00047         // client construtor.
00048         CL_GameObject(World *world, int object_type, const CL_NetObject &netobject)
00049         : world(world), object_type(object_type), netobject(netobject)
00050         {
00051                 common_init();
00052         }
00053 
00054         virtual ~CL_GameObject() { return; }
00055 
00057 public:
00058         World *get_world() { return world; }
00059 
00060         bool get_destroy_flag() { return destroy_flag; }
00061 
00062         CL_NetObject &get_netobject() { return netobject; }
00063 
00064         int get_object_type() { return object_type; }
00065 
00067 public:
00068         void set_destroy_flag(bool new_value = true) { destroy_flag = new_value; }
00069 
00070         void set_tick_rate(float time_per_tick) { tick_rate = time_per_tick; }
00071 
00072         void send_full(const CL_NetComputer *dest = NULL)
00073         {
00074                 CL_OutputSource_Memory output;
00075                 output.write_int32(object_type);
00076                 write_full_update(output);
00077                 netobject.send(/*dest,*/ msgtype_full_update, output.get_data());
00078         }
00079 
00080         void send_tick(const CL_NetComputer *dest = NULL)
00081         {
00082                 CL_OutputSource_Memory output;
00083                 write_tick_update(output);
00084                 netobject.send(/*dest,*/ msgtype_tick_update, output.get_data());
00085         }
00086 
00087         void send_destroy(const CL_NetComputer *dest = NULL)
00088         {
00089                 CL_OutputSource_Memory output;
00090                 write_destroy(output);
00091                 netobject.send(/*dest,*/ msgtype_destroy, output.get_data());
00092         }
00093 
00094         void recv_full(CL_InputSource &message)
00095         {
00096                 int type = message.read_int32();
00097                 cl_assert(type == object_type);
00098                 read_full_update(message);
00099         }
00100 
00101         void recv_tick(CL_InputSource &message)
00102         {
00103                 read_tick_update(message);
00104         }
00105 
00106         void recv_destroy(CL_InputSource &message)
00107         {
00108                 read_destroy(message);
00109         }
00110 
00112 public:
00113         virtual void update(int time_elapsed)
00114         {
00115                 if (tick_rate > 0.0f)
00116                 {
00117                         tick_time += time_elapsed;
00118 
00119                         while (tick_time >= tick_rate)
00120                         {
00121                                 tick_time -= tick_rate;
00122                                 send_tick();
00123                         }
00124                 }
00125         }
00126 
00127         virtual void read_full_update(CL_InputSource &message) { return; }
00128 
00129         virtual void read_tick_update(CL_InputSource &message) { return; }
00130 
00131         virtual void read_destroy(CL_InputSource &message) { set_destroy_flag(); }
00132 
00133         virtual void write_full_update(CL_OutputSource &message) { return; }
00134 
00135         virtual void write_tick_update(CL_OutputSource &message) { return; }
00136 
00137         virtual void write_destroy(CL_InputSource &message) { return; }
00138 
00140 public:
00141         void common_init()
00142         {
00143                 destroy_flag = false;
00144                 tick_rate = 0.0f; // disable tick updates per default.
00145                 tick_time = 0.0f;
00146 
00147                 slot_full = netobject.connect(
00148                         msgtype_full_update,
00149                         CL_CreateSlot(this, &CL_GameObject<World>::recv_full));
00150 
00151                 slot_tick = netobject.connect(
00152                         msgtype_tick_update,
00153                         CL_CreateSlot(this, &CL_GameObject<World>::recv_tick));
00154 
00155                 slot_destroy = netobject.connect(
00156                         msgtype_destroy,
00157                         CL_CreateSlot(this, &CL_GameObject<World>::recv_destroy));
00158         }
00159 
00160         World *world;
00161         int object_type;
00162         bool destroy_flag;
00163         CL_NetObject netobject;
00164         float tick_rate;
00165         float tick_time;
00166 
00167         CL_Slot slot_full;
00168         CL_Slot slot_tick;
00169         CL_Slot slot_destroy;
00170 };
00171 
00172 template<class GameObject>
00173 class CL_World
00174 //: World template.
00175 {
00177 public:
00178         CL_World(CL_NetSession *session, int object_netchannel)
00179         :
00180                 session(session),
00181                 netobject_channel(session, object_netchannel),
00182                 last_time(CL_System::get_time()),
00183                 max_tick_elapsed(0.05f)
00184         {
00185                 slot_create_object = netobject_channel.sig_create_object().connect(
00186                         CL_CreateSlot(this, &CL_World<GameObject>::sig_create_object));
00187         }
00188 
00189         virtual ~CL_World()
00190         {
00191         }
00192 
00194 public:
00195         CL_NetObjectChannel &get_netobject_channel() { return netobject_channel; }
00196 
00197         CL_NetSession *get_session() { return session; }
00198 
00199         std::list<GameObject *> &get_objects() { return objects; }
00200 
00202 public:
00203         void set_max_tick_elapsed(float time) { max_tick_elapsed = time; }
00204 
00205         void add_object(GameObject *object) { objects.push_back(object); }
00206 
00207         void remove_object(GameObject *object) { objects.remove(object); }
00208 
00209         void update()
00210         {
00211                 float delta_time = (CL_System::get_time() - last_time);
00212                 last_time = CL_System::get_time();
00213 
00214                 for (; delta_time > 0; delta_time -= max_tick_elapsed)
00215                 {
00216                         float elapsed = (delta_time > max_tick_elapsed) ? max_tick_elapsed : delta_time;
00217 
00218                         std::list<GameObject *>::iterator it;
00219                         std::list<GameObject *> remove_list;
00220                         for (it = objects.begin(); it != objects.end(); it++)
00221                         {
00222                                 (*it)->update(delta_time);
00223                                 if ((*it)->get_destroy_flag()) remove_list.push_back(*it);
00224                         }
00225                                 
00226                         for (it = remove_list.begin(); it != remove_list.end(); it++)
00227                         {
00228                                 delete *it;
00229                         }
00230                 }
00231         }
00232 
00234 protected:
00235         virtual void on_create_object(
00236                 const CL_NetObject &netobj,
00237                 int msgType,
00238                 const std::string &message) { return; }
00239 
00241 private:
00242         void sig_create_object(
00243                 const CL_NetObject &netobj,
00244                 int msgType,
00245                 const std::string &message)
00246         {
00247                 // this function is needed because I'm not sure how to connect a signal to a virtual
00248                 // table function.
00249                 on_create_object(netobj, msgType, message);
00250         }
00251 
00252         std::list<GameObject *> objects;
00253         CL_NetSession *session;
00254         CL_NetObjectChannel netobject_channel;
00255         float max_tick_elapsed;
00256         unsigned long last_time;
00257         CL_Slot slot_create_object;
00258 };
00259 
00260 #endif

Generated at Wed Apr 4 19:54:04 2001 for ClanLib by doxygen1.2.6 written by Dimitri van Heesch, © 1997-2001