001 package com.croftsoft.apps.chat.model.seri; 002 003 import java.io.*; 004 import java.util.*; 005 006 import com.croftsoft.core.animation.clock.SystemClock; 007 import com.croftsoft.core.animation.clock.Timekeeper; 008 import com.croftsoft.core.animation.model.Model; 009 import com.croftsoft.core.animation.model.ModelId; 010 import com.croftsoft.core.lang.NullArgumentException; 011 import com.croftsoft.core.util.consumer.Consumer; 012 import com.croftsoft.core.util.queue.Queue; 013 014 import com.croftsoft.apps.chat.ChatConstants; 015 import com.croftsoft.apps.chat.model.ChatGame; 016 import com.croftsoft.apps.chat.model.ChatWorld; 017 import com.croftsoft.apps.chat.model.ChatWorldAccessor; 018 import com.croftsoft.apps.chat.model.seri.SeriChatWorld; 019 import com.croftsoft.apps.chat.request.CreateModelRequest; 020 import com.croftsoft.apps.chat.request.KillRequest; 021 import com.croftsoft.apps.chat.request.MoveRequest; 022 import com.croftsoft.apps.chat.request.Request; 023 import com.croftsoft.apps.chat.request.TalkRequest; 024 import com.croftsoft.apps.chat.request.ViewRequest; 025 import com.croftsoft.apps.chat.response.UnknownRequestResponse; 026 import com.croftsoft.apps.chat.server.CreateModelServer; 027 import com.croftsoft.apps.chat.server.KillServer; 028 import com.croftsoft.apps.chat.server.MoveServer; 029 import com.croftsoft.apps.chat.server.TalkServer; 030 import com.croftsoft.apps.chat.server.RequestServer; 031 import com.croftsoft.apps.chat.server.ViewServer; 032 import com.croftsoft.apps.chat.user.User; 033 import com.croftsoft.apps.chat.user.UserId; 034 import com.croftsoft.apps.chat.user.UserStore; 035 import com.croftsoft.apps.chat.user.seri.SeriUserStore; 036 037 /********************************************************************* 038 * A Serializable ChatGame implementation. 039 * 040 * @version 041 * 2003-09-10 042 * @since 043 * 2003-06-06 044 * @author 045 * <a href="https://www.croftsoft.com/">David Wallace Croft</a> 046 *********************************************************************/ 047 048 public final class SeriChatGame 049 implements Serializable, ChatGame 050 ////////////////////////////////////////////////////////////////////// 051 ////////////////////////////////////////////////////////////////////// 052 { 053 054 private static final long serialVersionUID = 0L; 055 056 // 057 058 private static final double TIME_DELTA_MAX = 0.2; 059 060 private static final double TIME_FACTOR = 1.0; 061 062 // 063 064 private final UserStore userStore; 065 066 private final ChatWorld chatWorld; 067 068 private final Timekeeper timekeeper; 069 070 private final Map classToRequestServerMap; 071 072 ////////////////////////////////////////////////////////////////////// 073 // static methods 074 ////////////////////////////////////////////////////////////////////// 075 076 /* 077 public static void main ( String [ ] args ) 078 ////////////////////////////////////////////////////////////////////// 079 { 080 Queue requestQueue = new ListQueue ( ); 081 082 ChatGame chatGame = new SeriChatGame ( 083 requestQueue, 084 new Consumer ( ) 085 { 086 public void consume ( Object o ) 087 { 088 System.out.println ( o ); 089 } 090 } ); 091 092 final String USERNAME = "Test User"; 093 094 requestQueue.append ( new CreateRequest ( USERNAME ) ); 095 096 int x = 0; 097 098 int y = 0; 099 100 while ( true ) 101 { 102 chatGame.update ( ); 103 104 requestQueue.append ( new MoveRequest ( USERNAME, x, y ) ); 105 106 x++; 107 108 y++; 109 } 110 } 111 */ 112 113 ////////////////////////////////////////////////////////////////////// 114 // constructor methods 115 ////////////////////////////////////////////////////////////////////// 116 117 public SeriChatGame ( UserStore userStore ) 118 ////////////////////////////////////////////////////////////////////// 119 { 120 NullArgumentException.check ( this.userStore = userStore ); 121 122 Consumer eventConsumer = 123 new Consumer ( ) 124 { 125 public void consume ( Object o ) 126 { 127 broadcast ( o ); 128 } 129 }; 130 131 chatWorld = new SeriChatWorld ( eventConsumer ); 132 133 timekeeper = new Timekeeper ( SystemClock.INSTANCE, TIME_FACTOR ); 134 135 classToRequestServerMap = new HashMap ( ); 136 137 /* 138 classToRequestServerMap.put ( 139 KillRequest.class, 140 new KillServer ( chatWorld ) ); 141 */ 142 143 classToRequestServerMap.put ( 144 CreateModelRequest.class, 145 new CreateModelServer ( chatWorld ) ); 146 147 classToRequestServerMap.put ( 148 MoveRequest.class, 149 new MoveServer ( chatWorld ) ); 150 151 classToRequestServerMap.put ( 152 TalkRequest.class, 153 new TalkServer ( eventConsumer ) ); 154 155 classToRequestServerMap.put ( 156 ViewRequest.class, 157 new ViewServer ( ( SeriChatWorld ) chatWorld ) ); 158 } 159 160 public SeriChatGame ( ) 161 ////////////////////////////////////////////////////////////////////// 162 { 163 this ( new SeriUserStore ( ) ); 164 } 165 166 ////////////////////////////////////////////////////////////////////// 167 ////////////////////////////////////////////////////////////////////// 168 169 public ChatWorldAccessor getChatWorldAccessor ( ) 170 ////////////////////////////////////////////////////////////////////// 171 { 172 return chatWorld; 173 } 174 175 public ChatWorld getChatWorld ( ) 176 ////////////////////////////////////////////////////////////////////// 177 { 178 return chatWorld; 179 } 180 181 ////////////////////////////////////////////////////////////////////// 182 ////////////////////////////////////////////////////////////////////// 183 184 public void update ( ) 185 ////////////////////////////////////////////////////////////////////// 186 { 187 chatWorld.prepare ( ); 188 189 Model [ ] models = chatWorld.getModels ( ); 190 191 for ( int i = 0; i < models.length; i++ ) 192 { 193 Model model = models [ i ]; 194 195 if ( !model.isActive ( ) ) 196 { 197 chatWorld.removeModel ( model.getModelId ( ) ); 198 } 199 } 200 201 UserId [ ] userIds = userStore.getUserIds ( ); 202 203 for ( int i = 0; i < userIds.length; i++ ) 204 { 205 User user = userStore.getUser ( userIds [ i ] ); 206 207 if ( user == null ) 208 { 209 continue; 210 } 211 212 if ( System.currentTimeMillis ( ) 213 >= user.getLastRequestTime ( ) + ChatConstants.USER_TIMEOUT ) 214 { 215 removeUser ( user ); 216 217 continue; 218 } 219 220 Queue requestQueue = user.getRequestQueue ( ); 221 222 Request request = ( Request ) requestQueue.poll ( ); 223 224 if ( request == null ) 225 { 226 continue; 227 } 228 229 RequestServer requestServer = ( RequestServer ) 230 classToRequestServerMap.get ( request.getClass ( ) ); 231 232 if ( requestServer == null ) 233 { 234 queue ( user, new UnknownRequestResponse ( request ) ); 235 } 236 237 Object response = requestServer.serve ( user, request ); 238 239 if ( response != null ) 240 { 241 queue ( user, response ); 242 } 243 } 244 245 timekeeper.update ( ); 246 247 double timeDelta = timekeeper.getTimeDelta ( ); 248 249 if ( timeDelta > TIME_DELTA_MAX ) 250 { 251 timeDelta = TIME_DELTA_MAX; 252 } 253 254 chatWorld.update ( timeDelta ); 255 } 256 257 ////////////////////////////////////////////////////////////////////// 258 // private methods 259 ////////////////////////////////////////////////////////////////////// 260 261 private void queue ( 262 User user, 263 Object message ) 264 ////////////////////////////////////////////////////////////////////// 265 { 266 Queue messageQueue = user.getMessageQueue ( ); 267 268 try 269 { 270 messageQueue.replace ( message ); 271 } 272 catch ( IndexOutOfBoundsException ex ) 273 { 274 removeUser ( user ); 275 } 276 } 277 278 private void broadcast ( Object o ) 279 ////////////////////////////////////////////////////////////////////// 280 { 281 UserId [ ] userIds = userStore.getUserIds ( ); 282 283 for ( int i = 0; i < userIds.length; i++ ) 284 { 285 User user = userStore.getUser ( userIds [ i ] ); 286 287 if ( user == null ) 288 { 289 continue; 290 } 291 292 queue ( user, o ); 293 } 294 } 295 296 private void removeUser ( User user ) 297 ////////////////////////////////////////////////////////////////////// 298 { 299 userStore.removeUser ( user.getUserId ( ) ); 300 301 ModelId modelId = user.getModelId ( ); 302 303 if ( modelId != null ) 304 { 305 chatWorld.removeModel ( modelId ); 306 } 307 } 308 309 ////////////////////////////////////////////////////////////////////// 310 ////////////////////////////////////////////////////////////////////// 311 }