[P2play-commit] SF.net SVN: p2play: [32] trunk/P2Play/src/org/p2play/region/impl
Status: Pre-Alpha
Brought to you by:
tisoft
|
From: <ti...@us...> - 2007-01-22 14:18:05
|
Revision: 32
http://p2play.svn.sourceforge.net/p2play/?rev=32&view=rev
Author: tisoft
Date: 2007-01-22 06:18:04 -0800 (Mon, 22 Jan 2007)
Log Message:
-----------
added test server implementation from uni cvs
Added Paths:
-----------
trunk/P2Play/src/org/p2play/region/impl/ServerHandler.java
trunk/P2Play/src/org/p2play/region/impl/SingleStaticNetworkRegionManager.java
Added: trunk/P2Play/src/org/p2play/region/impl/ServerHandler.java
===================================================================
--- trunk/P2Play/src/org/p2play/region/impl/ServerHandler.java (rev 0)
+++ trunk/P2Play/src/org/p2play/region/impl/ServerHandler.java 2007-01-22 14:18:04 UTC (rev 32)
@@ -0,0 +1,154 @@
+package org.p2play.region.impl;
+
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+import org.p2play.data.DataManager;
+import org.p2play.region.Client;
+import org.p2play.region.GameAction;
+import org.p2play.region.GameState;
+import org.p2play.region.Region;
+import org.p2play.region.RegionManager;
+import org.p2play.region.Server;
+import org.p2play.region.ServerFactory;
+import org.p2play.scripting.pnuts.object.GameStateObject;
+import org.p2play.util.ListMap;
+
+import rice.p2p.util.rawserialization.SimpleInputBuffer;
+import rice.p2p.util.rawserialization.SimpleOutputBuffer;
+
+public class ServerHandler implements Client {
+ private HashMap<Region, Server> serverMap;
+
+ private ServerFactory serverFactory;
+
+ private RegionManager regionManager;
+
+ private HashMap<Region, GameState> gameStateMap;
+
+ private ListMap<Region, GameAction> serverInteractionMap;
+
+ private Set<Region> serverSet;
+
+ public ServerHandler(RegionManager regionManager, DataManager dataManager,
+ ServerFactory serverFactory) {
+ super();
+ this.regionManager = regionManager;
+ this.serverFactory = serverFactory;
+ this.serverSet=new HashSet<Region>();
+
+ serverMap = new HashMap<Region, Server>();
+ gameStateMap = new HashMap<Region, GameState>();
+
+ serverInteractionMap = new ListMap<Region, GameAction>();
+ }
+
+ public void startServer(final Region region, final long gameTime) {
+ if (!serverSet.contains(region)) {
+ new Thread(new Runnable() {
+ public void run() {
+ Server server = serverMap.get(region);
+ if (server == null) {
+ server = serverFactory.getServer(region);
+
+ long randomSeed = 0;
+ try {
+ randomSeed = new DataInputStream(
+ new ByteArrayInputStream(
+
+ region.getRegionIdentifier().getBytes(
+ "UTF-8"))).readLong();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ GameState gameState = server.init(gameTime, randomSeed);
+ gameStateMap.put(region, gameState);
+
+ serverMap.put(region, server);
+
+ regionManager.joinRegion(region, ServerHandler.this);
+ }
+ }
+ }).start();
+ }
+
+ }
+
+ public Iterator<Region> iteratorOfRegions() {
+ return new HashSet<Region>(serverMap.keySet()).iterator();
+ }
+
+ public boolean hasServer(Region region) {
+ return serverMap.containsKey(region);
+ }
+
+ public boolean isIdle(Region region) {
+ return serverMap.get(region).isEmpty(getGameState(region));
+ }
+
+ public void handleGameStateChanged(Region region, GameState gameState) {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void handleRegionChange(Region oldRegion, Region newRegion, Object gameObject) {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void addGameAction(Region region, GameAction gameAction) {
+ serverInteractionMap.add(region, gameAction);
+ }
+
+ public int getHash(Region region) {
+ return getGameState(region).hash();
+ }
+
+ public GameState getGameState(Region region) {
+ return gameStateMap.get(region);
+ }
+
+ public void tick(Region region/* , long gameTime */) {
+ // TODO: tick to current
+
+ Server server = serverMap.get(region);
+ if (server != null) {
+ gameStateMap.put(region, server.tick(clone(gameStateMap.get(region)),
+ serverInteractionMap.remove(region)));
+
+ if (!isIdle(region)) {
+ // TODO: auch gefrickelt...
+ // join all neigbours
+ Iterator<Region> neighbouts = server
+ .getNeighbourRegionIdentifiers().iterator();
+ while (neighbouts.hasNext()) {
+ Region r = neighbouts.next();
+ regionManager.joinRegion(r, this);
+ }
+ }
+ }
+
+ }
+
+ private GameState clone(GameState state) {
+ GameState clone=null;
+
+ if (state instanceof GameStateObject) {
+ GameStateObject gso = (GameStateObject) state;
+ SimpleOutputBuffer buf=new SimpleOutputBuffer();
+ try{
+ gso.doSerialize(buf);
+ clone=new GameStateObject(new SimpleInputBuffer(buf.getBytes()));
+ }catch (Exception e) {
+ // TODO: handle exception
+ }
+ }
+
+ return clone;
+ }
+}
Added: trunk/P2Play/src/org/p2play/region/impl/SingleStaticNetworkRegionManager.java
===================================================================
--- trunk/P2Play/src/org/p2play/region/impl/SingleStaticNetworkRegionManager.java (rev 0)
+++ trunk/P2Play/src/org/p2play/region/impl/SingleStaticNetworkRegionManager.java 2007-01-22 14:18:04 UTC (rev 32)
@@ -0,0 +1,217 @@
+package org.p2play.region.impl;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.p2play.data.DataManager;
+import org.p2play.io.Serializer;
+import org.p2play.net.pastry.time.TimeManager;
+import org.p2play.region.Client;
+import org.p2play.region.GameAction;
+import org.p2play.region.GameState;
+import org.p2play.region.Region;
+import org.p2play.region.RegionManager;
+import org.p2play.region.ServerFactory;
+import org.p2play.region.message.GameActionMessage;
+import org.p2play.region.message.GameStateMessage;
+import org.p2play.region.message.JoinMessage;
+import org.p2play.region.message.RegionMessage;
+import org.p2play.scripting.pnuts.api.region.RegionChangeGameAction;
+import org.p2play.util.ListMap;
+
+import rice.environment.time.TimeSource;
+import rice.p2p.commonapi.Node;
+import rice.p2p.scribe.Scribe;
+import rice.p2p.scribe.ScribeImpl;
+
+public final class SingleStaticNetworkRegionManager implements Runnable,
+ RegionManager {
+ private ListMap<Region, Client> clientMap;
+
+ private HashMap<Region, GameState> gameStateMap;
+
+ private List<GameAction> clientInteractionQueue;
+
+ private NetworkHandler networkHandler;
+
+ private static int tickGap = 100;
+
+ private TimeManager timeManager;
+
+ private ServerHandler serverHandler;
+
+ private TimeSource timeSource;
+
+ public SingleStaticNetworkRegionManager(Serializer serializer, Node node, DataManager dataManager,
+ ServerFactory serverFactory) {
+
+ timeManager = TimeManager.create(node);
+
+ timeSource=node.getEnvironment().getTimeSource();
+
+ clientMap = new ListMap<Region, Client>();
+ gameStateMap = new HashMap<Region, GameState>();
+
+ clientInteractionQueue = new LinkedList<GameAction>();
+
+ networkHandler = new NetworkHandler(serializer, this, node);
+
+ Scribe scribe = new ScribeImpl(node, "gamestate");
+ serverHandler = new ServerHandler(this, dataManager, serverFactory);
+
+ new Thread(this).start();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see de.upb.mmog.net.region.RegionManager#joinRegion(java.lang.String,
+ * de.upb.mmog.net.region.Client)
+ */
+ public void joinRegion(Region region, Client client) {
+ if (client != serverHandler)
+ System.out.println(client + " joins " + region);
+ synchronized (clientMap) {
+ clientMap.add(region, client);
+ networkHandler.joinRegion(region, timeManager.getGameTime());
+ }
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see de.upb.mmog.net.region.RegionManager#leaveRegion(java.lang.String,
+ * de.upb.mmog.net.region.Client)
+ */
+ public void leaveRegion(Region region, Client client) {
+ if (client != serverHandler)
+ System.out.println(client + " leaves " + region);
+ synchronized (clientMap) {
+ clientMap.remove(region, client);
+
+ if (clientMap.isEmpty(region)) {
+ // leave the region, if no server process is running on us
+ if (!serverHandler.hasServer(region)) {
+ networkHandler.leaveRegion(region);
+ }
+ }
+ }
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see de.upb.mmog.net.region.RegionManager#scheduleInteraction(de.upb.mmog.net.region.Client,
+ * de.upb.mmog.net.region.Interaction)
+ */
+ public void scheduleInteraction(Client client, GameAction interaction) {
+ synchronized (clientInteractionQueue) {
+ clientInteractionQueue.add(interaction);
+ }
+ }
+
+ /**
+ * 1. execute server processes 2. update client processes with new game
+ * state 3. send game state change requests
+ */
+ @SuppressWarnings("unchecked")
+ public void run() {
+ while (true) {
+ long time = timeSource.currentTimeMillis();
+ Iterator<Region> servers = serverHandler.iteratorOfRegions();
+ while (servers.hasNext()) {
+ Region server = servers.next();
+
+ serverHandler.tick(server);
+
+ // only send if not emoty
+ networkHandler
+ .sendGameState(serverHandler.getGameState(server));
+ }
+ // TODO: clear old requests
+
+ // Iterate over the regions
+ synchronized (clientMap) {
+ Iterator<Region> regions = clientMap.keySet().iterator();
+
+ while (regions.hasNext()) {
+ Region region = regions.next();
+
+ GameState gameState = gameStateMap.get(region);// remove(region);
+
+ // Iterate over the controllers
+ Iterator<Client> clients = clientMap.iterator(region);
+ while (clients.hasNext()) {
+ Client client = clients.next();
+ // update the client with the current game state
+ if (region != null && gameState != null) {
+ client.handleGameStateChanged(region, gameState);
+ }
+ }
+ }
+
+ }
+
+ synchronized (clientInteractionQueue) {
+ Iterator<GameAction> requests = clientInteractionQueue
+ .iterator();
+ while (requests.hasNext()) {
+ GameAction request = requests.next();
+
+ networkHandler.sendInteraction(request);
+ requests.remove();
+ }
+ }
+
+ try {
+
+ timeSource.sleep(Math.max(1, tickGap + time
+ - timeSource.currentTimeMillis()));
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+
+ }
+ }
+
+ public void handleMessageReceived(RegionMessage message) {
+ if (message instanceof GameActionMessage) {
+ GameActionMessage im = (GameActionMessage) message;
+
+ // TODO gefuckelt
+ synchronized (clientMap) {
+ if (im.getGameAction() instanceof RegionChangeGameAction) {
+ RegionChangeGameAction rcga = (RegionChangeGameAction) im
+ .getGameAction();
+ System.out.println("!!!Got Regionchange: "
+ + rcga.getSourceRegion() + "->" + rcga.getRegion());
+ System.out.println(clientMap);
+ if (!rcga.getSourceRegion().equals(rcga.getRegion())) {
+ Iterator<Client> iterator = clientMap.clonedIterator(rcga
+ .getSourceRegion());
+ while (iterator.hasNext()) {
+ Client client = iterator.next();
+
+ client.handleRegionChange(rcga.getSourceRegion(), rcga.getRegion(), rcga
+ .getGameObject());
+ }
+ }
+ }
+ }
+
+ serverHandler.addGameAction(im.getRegion(), im.getGameAction());
+ } else if (message instanceof GameStateMessage) {
+ GameStateMessage gsm = (GameStateMessage) message;
+
+ gameStateMap.put(gsm.getRegion(), gsm.getGameState());
+ } else if (message instanceof JoinMessage) {
+ JoinMessage jm = (JoinMessage) message;
+
+ serverHandler.startServer(jm.getRegion(), jm.getGameTime());
+ }// TODO: add handling of leave message
+ }
+}
\ No newline at end of file
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|