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         }