package example;
import gdwUtils.DefaultCharSet;
import java.nio.ByteBuffer;
import java.util.LinkedList;
/**
* Speziell:
* Beispielimplementierung für eine CoreLoop auf der Serverseite. Es werden die Nachrichten von den Verbunden Clients abgefragt
* und Nachrichten verteilt.
*
* Allgemein:
* Eine so genannten CoreLoop ist eine Endlosschleife, die praktische in jedem Spiel anwendung findet.
* Sie bildet die Grundeinheit und besteht aus normalerweise aus:
* - update(hole Spielereingaben, zb; von Tastatur. Simuliere weiter das Spielgeschehen)
* - draw(Zeichne das aktuelle Spielgeschehen)
*
* @author firen
*
*/
public class ServerCoreLoop extends Thread
{
/**
* Die Nicknames, der Clients, die seit dem letzten Durchlauf die Verbindung geschlossen haben.
*/
private final LinkedList<String> leaverNames;
/**
* Die Nicknames, der Clients, die seit dem letzten Durchlauf die Verbinung aufgebaut haben.
*/
private final LinkedList<String> joinerNames;
/**
* Alle gesammelten Chatnachrichten der Clients seit dem letzten Durchlauf.
*/
private final LinkedList<String> messageQeueu;
private final ChatServer ref;
public ServerCoreLoop(ChatServer ref)
{
this.ref = ref;
this.leaverNames = new LinkedList<String>();
this.joinerNames = new LinkedList<String>();
this.messageQeueu = new LinkedList<String>();
}
@Override
public void run()
{
while (!this.isInterrupted())
{
try
{
//sonst läuft sonst zu schnell, da nicht gezeichnet wird...
sleep(250);
} catch (InterruptedException e)
{
}
// ruf die updateMethode vom Server auf, es werden keinen eingehenden Verbindungen geblockt
this.ref.proccedInputData();
// überpüfen ob jemand dazu kam
if (!this.joinerNames.isEmpty())
{
// lass dir einen ByteBuffer für Nachrichten geben
ByteBuffer buf = this.ref.getMessageBuffer();
//fürge den code für Spielerbeitritt dazu
buf.put(MyMessageConstants.PlayerConnected);
//rufe pack methode auf
packListInBytBuffer(this.joinerNames, buf);
// sende an alle per UDP (ohne Ausfallsicherheit)
this.ref.sendToAll(buf, true);
}
if (!this.leaverNames.isEmpty())
{
//selbe wie eingehende nur mit verlasende
ByteBuffer buf = this.ref.getMessageBuffer();
buf.put(MyMessageConstants.PlayerDisconnected);
packListInBytBuffer(this.leaverNames, buf);
this.ref.sendToAll(buf, true);
}
if (!this.messageQeueu.isEmpty())
{
//dito
ByteBuffer buf = this.ref.getMessageBuffer();
buf.put(MyMessageConstants.ChatMessage);
packListInBytBuffer(this.messageQeueu, buf);
this.ref.sendToAll(buf, true);
}
}
}
/**
* Eine Verpacktmethode für die Liste die diese Klasse verwendet.
* @param list die Liste die durchgearbeitet werden soll
* @param buf der ByteBuffer welcher befüllt wird
*/
private void packListInBytBuffer(LinkedList<String> list, ByteBuffer buf)
{
// füge Anzahl der Elemente der Liste ein
buf.put((byte) list.size());
//so lange Liste nicht leer
while (!list.isEmpty())
{
//nehme erstes Element heraus
String elem = list.pop();
// lese das byte-array, welches den string repräsentiert
byte[] arr = elem.getBytes(DefaultCharSet.getDefaultCharset());
//schreibe länge des byte-arrays
buf.put((byte) arr.length);
//schreibe das array hinein
buf.put(arr);
}
}
/**
* fügt einen Namen zur "Leaverlist" hinzu
* @param name der Name
*/
public void addLeaverName(String name)
{
this.leaverNames.add(name);
}
/**
* fügt einen Namen zur "Joinerliste" hinzu
* @param name der Name
*/
public void addJoinerName(String name)
{
this.joinerNames.add(name);
}
/**
* fügt eine Nachricht an zur Nachrichtenliste hinzu
* @param msg die Nachricht
*/
public void addMessage(String msg)
{
this.messageQeueu.add(msg);
}
}