00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
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
00027 {
00028
00029 public:
00030 enum EGameObjectMessageTypes
00031 {
00032 msgtype_full_update = 0,
00033 msgtype_tick_update = 1,
00034 msgtype_destroy = 2,
00035 msgtype_user = 1000
00036 };
00037
00039 public:
00040
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
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( 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( 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( 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;
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
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
00248
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