001 package com.croftsoft.apps.mars.net; 002 003 import java.io.*; 004 import java.net.*; 005 import java.util.*; 006 007 import com.croftsoft.core.io.SerializableCoder; 008 import com.croftsoft.core.lang.NullArgumentException; 009 import com.croftsoft.core.lang.lifecycle.Lifecycle; 010 import com.croftsoft.core.math.MathConstants; 011 import com.croftsoft.core.net.http.msg.HttpMessageClient; 012 import com.croftsoft.core.util.NullIterator; 013 import com.croftsoft.core.util.consumer.Consumer; 014 015 import com.croftsoft.apps.mars.model.GameAccessor; 016 import com.croftsoft.apps.mars.model.NullGameAccessor; 017 import com.croftsoft.apps.mars.model.TankAccessor; 018 import com.croftsoft.apps.mars.model.WorldAccessor; 019 import com.croftsoft.apps.mars.net.request.ViewRequest; 020 021 /********************************************************************* 022 * Network synchronizer. 023 * 024 * @version 025 * 2003-06-02 026 * @since 027 * 2003-04-06 028 * @author 029 * <a href="https://www.croftsoft.com/">David Wallace Croft</a> 030 *********************************************************************/ 031 032 public final class Synchronizer 033 implements GameAccessor, Lifecycle 034 ////////////////////////////////////////////////////////////////////// 035 ////////////////////////////////////////////////////////////////////// 036 { 037 038 private static final String DEFAULT_HOST = "localhost"; 039 040 private static final int DEFAULT_PORT = 8080; 041 042 private static final String SERVLET_PATH = "servlet"; 043 044 private static final String DEFAULT_PATH = "/mars/" + SERVLET_PATH; 045 046 private static final String USER_AGENT = "CroftSoft Mars"; 047 048 private static final String CONTENT_TYPE 049 = "application/octet-stream"; 050 051 private static final long POLLING_PERIOD_MIN 052 = 100; 053 054 private static final long POLLING_PERIOD_MAX 055 = MathConstants.MILLISECONDS_PER_DAY; 056 057 private static final long POLLING_PERIOD_INIT 058 = POLLING_PERIOD_MIN; 059 060 private static final double POLLING_PERIOD_MULT 061 = 2.0; 062 063 private static final double POLLING_PERIOD_DIVI 064 = Double.POSITIVE_INFINITY; 065 066 private static final long POLLING_PERIOD_INCR 067 = MathConstants.MILLISECONDS_PER_SECOND; 068 069 // 070 071 private final HttpMessageClient httpMessageClient; 072 073 // 074 075 private GameAccessor gameAccessor; 076 077 private int level; 078 079 ////////////////////////////////////////////////////////////////////// 080 ////////////////////////////////////////////////////////////////////// 081 082 public Synchronizer ( 083 String playerName, 084 URL codeBaseURL ) 085 throws IOException, MalformedURLException 086 ////////////////////////////////////////////////////////////////////// 087 { 088 NullArgumentException.check ( playerName ); 089 090 URL servletURL = null; 091 092 if ( codeBaseURL != null ) 093 { 094 servletURL = new URL ( codeBaseURL, SERVLET_PATH ); 095 } 096 else 097 { 098 servletURL 099 = new URL ( "http", DEFAULT_HOST, DEFAULT_PORT, DEFAULT_PATH ); 100 } 101 102 httpMessageClient = new HttpMessageClient ( 103 servletURL, 104 USER_AGENT, 105 SerializableCoder.INSTANCE, 106 SerializableCoder.INSTANCE, 107 CONTENT_TYPE, 108 SerializableCoder.INSTANCE.encode ( 109 new ViewRequest ( playerName ) ), 110 new Consumer ( ) 111 { 112 public void consume ( Object o ) 113 { 114 Synchronizer.this.consume ( o ); 115 } 116 }, 117 POLLING_PERIOD_MIN, 118 POLLING_PERIOD_MAX, 119 POLLING_PERIOD_INIT, 120 POLLING_PERIOD_MULT, 121 POLLING_PERIOD_DIVI, 122 POLLING_PERIOD_INCR ); 123 124 gameAccessor = NullGameAccessor.INSTANCE; 125 } 126 127 ////////////////////////////////////////////////////////////////////// 128 ////////////////////////////////////////////////////////////////////// 129 130 public void replace ( Object o ) 131 ////////////////////////////////////////////////////////////////////// 132 { 133 httpMessageClient.replace ( o ); 134 } 135 136 ////////////////////////////////////////////////////////////////////// 137 // interface GameAccessor methods 138 ////////////////////////////////////////////////////////////////////// 139 140 public int getLevel ( ) 141 ////////////////////////////////////////////////////////////////////// 142 { 143 return level; 144 } 145 146 public Iterator getPath ( ) 147 ////////////////////////////////////////////////////////////////////// 148 { 149 return NullIterator.INSTANCE; 150 } 151 152 public TankAccessor getPlayerTankAccessor ( ) 153 ////////////////////////////////////////////////////////////////////// 154 { 155 return gameAccessor.getPlayerTankAccessor ( ); 156 } 157 158 public WorldAccessor getWorldAccessor ( ) 159 ////////////////////////////////////////////////////////////////////// 160 { 161 return gameAccessor.getWorldAccessor ( ); 162 } 163 164 ////////////////////////////////////////////////////////////////////// 165 // interface Lifecycle methods 166 ////////////////////////////////////////////////////////////////////// 167 168 public void init ( ) 169 ////////////////////////////////////////////////////////////////////// 170 { 171 httpMessageClient.init ( ); 172 } 173 174 public void start ( ) 175 ////////////////////////////////////////////////////////////////////// 176 { 177 httpMessageClient.start ( ); 178 } 179 180 public void stop ( ) 181 ////////////////////////////////////////////////////////////////////// 182 { 183 httpMessageClient.stop ( ); 184 } 185 186 public void destroy ( ) 187 ////////////////////////////////////////////////////////////////////// 188 { 189 httpMessageClient.destroy ( ); 190 } 191 192 ////////////////////////////////////////////////////////////////////// 193 // private methods 194 ////////////////////////////////////////////////////////////////////// 195 196 private void consume ( Object o ) 197 ////////////////////////////////////////////////////////////////////// 198 { 199 gameAccessor = ( GameAccessor ) o; 200 201 level++; 202 } 203 204 ////////////////////////////////////////////////////////////////////// 205 ////////////////////////////////////////////////////////////////////// 206 }