From ba4eb0d2d98188b54f58b0f8ea0f7fb9e1e7e699 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20V=C3=B6gele?= Date: Wed, 30 Apr 2014 17:28:58 +0200 Subject: [PATCH 01/12] Erste Gui Version. Es wird lediglich die Map gezeichnet. Das Backend ist angeschlossen --- DummyBackend.cs | 11 -- ParserTest.cs | 257 --------------------------------------- inf3.csproj | 15 ++- src/Backend.cs | 29 +++-- src/Buffer.cs | 73 +++++++---- src/BufferManuel.cs | 56 --------- src/Buffer_Wafa.cs | 44 ------- src/Entity.cs | 8 +- src/Gui/Gui.cs | 107 ++++++++++++++++ src/Gui/IBackend.cs | 8 ++ src/Gui/IGui.cs | 8 ++ src/Gui/IPositionable.cs | 26 ++++ src/Gui/ITile.cs | 17 +++ src/Gui/Program.cs | 20 +++ src/Map.cs | 4 +- src/Parser.cs | 62 ++++------ src/Receiver.cs | 6 +- src/Sender.cs | 20 ++- src/Tile.cs | 105 +++++++--------- 19 files changed, 363 insertions(+), 513 deletions(-) delete mode 100644 DummyBackend.cs delete mode 100644 ParserTest.cs delete mode 100644 src/BufferManuel.cs delete mode 100644 src/Buffer_Wafa.cs create mode 100644 src/Gui/Gui.cs create mode 100644 src/Gui/IBackend.cs create mode 100644 src/Gui/IGui.cs create mode 100644 src/Gui/IPositionable.cs create mode 100644 src/Gui/ITile.cs create mode 100644 src/Gui/Program.cs diff --git a/DummyBackend.cs b/DummyBackend.cs deleted file mode 100644 index f4dfa1c..0000000 --- a/DummyBackend.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace inf3 -{ - class DummyBackend - { - } -} diff --git a/ParserTest.cs b/ParserTest.cs deleted file mode 100644 index 08c08ad..0000000 --- a/ParserTest.cs +++ /dev/null @@ -1,257 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Frontend; -using WorldOfPeacecraft; -using System.Threading; - -namespace inf3 -{ - public class ParserTest - { - static void Main() - { - Parser p = new Parser(); - - p.AddToBuffer("begin:5"); - //Console.WriteLine(p.getBuffer().Dequeue()); - p.AddToBuffer("begin:upd"); - p.AddToBuffer("begin:player"); - p.AddToBuffer("id:3"); - p.AddToBuffer("typ:Player"); - p.AddToBuffer("busy:false"); - p.AddToBuffer("desc:Player3"); - p.AddToBuffer("x:3"); - p.AddToBuffer("y:15"); - p.AddToBuffer("points:0"); - p.AddToBuffer("end:player"); - p.AddToBuffer("end:upd"); - p.AddToBuffer("end:5"); - - /* - p.AddToBuffer("begin:24"); - p.AddToBuffer("begin:players"); - p.AddToBuffer("begin:player"); - p.AddToBuffer("id:3"); - p.AddToBuffer("typ:Player"); - p.AddToBuffer("busy:false"); - p.AddToBuffer("desc:Player3"); - p.AddToBuffer("x:3"); - p.AddToBuffer("y:15"); - p.AddToBuffer("pnts:0"); - p.AddToBuffer("end:player"); - p.AddToBuffer("begin:player"); - p.AddToBuffer("id:6"); - p.AddToBuffer("typ:Player"); - p.AddToBuffer("busy:false"); - p.AddToBuffer("desc:Player6"); - p.AddToBuffer("x:17"); - p.AddToBuffer("y:13"); - p.AddToBuffer("pnts:0"); - p.AddToBuffer("end:player"); - p.AddToBuffer("end:players"); - p.AddToBuffer("end:24"); - */ - - -/*begin:14 -begin:map -width:5 -height:5 -begin:cells -begin:cell -row:0 -col:0 -begin:props -WALL -end:props -end:cell -begin:cell -row:0 -col:1 -begin:props -WALL -end:props -end:cell -begin:cell -row:0 -col:2 -begin:props -WALL -end:props -end:cell -begin:cell -row:0 -col:3 -begin:props -WALL -end:props -end:cell -begin:cell -row:0 -col:4 -begin:props -WALL -end:props -end:cell -begin:cell -row:1 -col:0 -begin:props -WALL -end:props -end:cell -begin:cell -row:1 -col:1 -begin:props -WALKABLE -end:props -end:cell -begin:cell -row:1 -col:2 -begin:props -FOREST -WALKABLE -end:props -end:cell -begin:cell -row:1 -col:3 -begin:props -FOREST -WALKABLE -end:props -end:cell -begin:cell -row:1 -col:4 -begin:props -FOREST -WALKABLE -end:props -end:cell -begin:cell -row:2 -col:0 -begin:props -WALL -end:props -end:cell -begin:cell -row:2 -col:1 -begin:props -WALKABLE -end:props -end:cell -begin:cell -row:2 -col:2 -begin:props -FOREST -WALKABLE -end:props -end:cell -begin:cell -row:2 -col:3 -begin:props -FOREST -WALKABLE -end:props -end:cell -begin:cell -row:2 -col:4 -begin:props -FOREST -WALKABLE -end:props -end:cell -begin:cell -row:3 -col:0 -begin:props -WALL -end:props -end:cell -begin:cell -row:3 -col:1 -begin:props -WALKABLE -end:props -end:cell -begin:cell -row:3 -col:2 -begin:props -FOREST -WALKABLE -end:props -end:cell -begin:cell -row:3 -col:3 -begin:props -WALL -end:props -end:cell -begin:cell -row:3 -col:4 -begin:props -WALL -end:props -end:cell -begin:cell -row:4 -col:0 -begin:props -WALL -end:props -end:cell -begin:cell -row:4 -col:1 -begin:props -WALKABLE -end:props -end:cell -begin:cell -row:4 -col:2 -begin:props -FOREST -WALKABLE -end:props -end:cell -begin:cell -row:4 -col:3 -begin:props -FOREST -WALKABLE -end:props -end:cell -begin:cell -row:4 -col:4 -begin:props -FOREST -WALKABLE -end:props -end:cell -*/ - - Thread.Sleep(1000); - - Console.WriteLine(p.getDummyPlayer().ToString()); - Console.ReadLine(); - - } - } -} diff --git a/inf3.csproj b/inf3.csproj index 6f41c4a..9f8ef15 100644 --- a/inf3.csproj +++ b/inf3.csproj @@ -39,9 +39,6 @@ - - - @@ -69,10 +66,18 @@ - - + + + + + + + + + + \ No newline at end of file diff --git a/src/Backend.cs b/src/Backend.cs index a098793..aa443e9 100644 --- a/src/Backend.cs +++ b/src/Backend.cs @@ -2,25 +2,32 @@ using System.Net.Sockets; using System.Collections.Generic; using WorldOfPeacecraft; -namespace Frontend +namespace WorldOfPeacecraft { public class Backend : IBackend { + private Sender Send; private Receiver Rec; private Parser Parse; private TcpClient Client; private Dictionary Dragons; private Dictionary Players; private Map Map; - private Buffer Buffer; + private Buffer SenderBuffer; + private IGui Gui; - public Backend () + public Backend (IGui gui) { - Parse = new Parser (Buffer); - Client = new TcpClient ("localhost", 9999); - Rec = new Receiver (Client, Buffer); + Gui = gui; Dragons = new Dictionary (); Players = new Dictionary (); + Client = new TcpClient ("localhost", 9999); + Buffer receiverBuffer = new Buffer(10000); + SenderBuffer = new Buffer(100); + Parse = new Parser (this, receiverBuffer); + Rec = new Receiver (Client, receiverBuffer); + Send = new Sender (Client, SenderBuffer); + SenderBuffer.AddLine("get:map"); } public IEnumerable getDragons () @@ -83,8 +90,11 @@ namespace Frontend this.Map = map; } - public ITile[,] getMap () + public ITile[,] GetMap () { + if (Map == null) { + return null; + } return Map.GetTiles (); } @@ -95,5 +105,10 @@ namespace Frontend public void sendChat (string message) { } + + public void RefreshGui() + { + Gui.PerformRefresh(); + } } } diff --git a/src/Buffer.cs b/src/Buffer.cs index a10d9a7..6bf6612 100644 --- a/src/Buffer.cs +++ b/src/Buffer.cs @@ -1,35 +1,56 @@ -using System; using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Threading; namespace WorldOfPeacecraft { - public class Buffer - { - private Queue RawBuffer = new Queue(); - private AutoResetEvent BufferFilledEvent = new AutoResetEvent (false); - int size; + public class Buffer + { + private Queue Lines = new Queue(); + private int MaxSize; + private AutoResetEvent QueueFullLock = new AutoResetEvent(false); + private AutoResetEvent QueueEmptyLock = new AutoResetEvent(false); - public Buffer(int size) - { - this.size=size; - } - - - public void AddToBuffer (string s) + public Buffer (int maxSize) { - if (RawBuffer.Count >= size){ + this.MaxSize = maxSize; + } - } - else{ - lock (RawBuffer) { - RawBuffer.Enqueue (s); - BufferFilledEvent.Set (); - } - } - - } - } + public void AddLine (string line) + { + bool waitRequired = false; + lock (Lines) { + if (Lines.Count >= MaxSize) { + waitRequired = true; + QueueFullLock.Reset (); + } + } + if (waitRequired) { + QueueFullLock.WaitOne (); + } + lock (Lines) { + Lines.Enqueue (line); + QueueEmptyLock.Set(); + } + } + + public string NextLine () + { + bool waitRequired = false; + string line; + lock (Lines) { + if (Lines.Count == 0) { + waitRequired = true; + QueueEmptyLock.Reset (); + } + } + if (waitRequired) { + QueueEmptyLock.WaitOne (); + } + lock (Lines) { + line = Lines.Dequeue(); + QueueFullLock.Set (); + } + return line; + } + } } diff --git a/src/BufferManuel.cs b/src/BufferManuel.cs deleted file mode 100644 index 45d33f3..0000000 --- a/src/BufferManuel.cs +++ /dev/null @@ -1,56 +0,0 @@ -using System.Collections.Generic; -using System.Threading; - -namespace WorldOfPeacecraft -{ - class BufferManuel - { - private Queue Lines = new Queue(); - private int MaxSize; - private AutoResetEvent QueueFullLock = new AutoResetEvent(false); - private AutoResetEvent QueueEmptyLock = new AutoResetEvent(false); - - public BufferManuel (int maxSize) - { - this.MaxSize = maxSize; - } - - public void AddLine (string line) - { - bool waitRequired = false; - lock (Lines) { - if (Lines.Count >= MaxSize) { - waitRequired = true; - QueueFullLock.Reset (); - } - } - if (waitRequired) { - QueueFullLock.WaitOne (); - } - lock (Lines) { - Lines.Enqueue (line); - QueueEmptyLock.Set(); - } - } - - public string NextLine () - { - bool waitRequired = false; - string line; - lock (Lines) { - if (Lines.Count == 0) { - waitRequired = true; - QueueEmptyLock.Reset (); - } - } - if (waitRequired) { - QueueEmptyLock.WaitOne (); - } - lock (Lines) { - line = Lines.Dequeue(); - QueueFullLock.Set (); - } - return line; - } - } -} diff --git a/src/Buffer_Wafa.cs b/src/Buffer_Wafa.cs deleted file mode 100644 index 3ee9b43..0000000 --- a/src/Buffer_Wafa.cs +++ /dev/null @@ -1,44 +0,0 @@ -using System; -using System.Collections.Generic; - -namespace WorldOfPeacecraft -{ - public class Buffer_Wafa - { - private Queue DotA2 = new Queue (); - private int sizelimit; - - public Buffer_Wafa (int limit) - { - sizelimit = limit; - } - - bool isEmpty(){ - if (DotA2.Count == 0) - return true; - else - return false; - } - - bool isFull(){ - if (DotA2.Count >= sizelimit) - return true; - else - return false; - } - - string popMessage(){ - //TODO - } - - void enqueueMessage (string servermessage){ - bool varIsFull = isFull(); - if (varIsFull == false) { - DotA2.Enqueue (servermessage); - } else { - //this is else - } - } - } -} - diff --git a/src/Entity.cs b/src/Entity.cs index d81589e..a3a6187 100644 --- a/src/Entity.cs +++ b/src/Entity.cs @@ -32,22 +32,22 @@ namespace WorldOfPeacecraft return Id; } - public void SetPosX (int x) + public void SetX (int x) { this.Coord.X = x; } - public int getXPosition () + public int GetX () { return Coord.X; } - public void SetPosY (int y) + public void SetY (int y) { this.Coord.Y = y; } - public int getYPosition () + public int GetY () { return Coord.Y; } diff --git a/src/Gui/Gui.cs b/src/Gui/Gui.cs new file mode 100644 index 0000000..670b643 --- /dev/null +++ b/src/Gui/Gui.cs @@ -0,0 +1,107 @@ +using System; +using System.Drawing; +using System.Windows.Forms; +using System.Runtime.InteropServices; + +namespace WorldOfPeacecraft +{ + class Gui : Form, IGui + { + private const int tileSize = 16; + private const int entitySize = 10; + private IBackend Backend; + + private Panel Board = new Panel(); + + public Gui () + { + AllocConsole(); + InitializeComponents(); + } + + public void SetBackend (IBackend backend) + { + Backend = backend; + } + + public void InitializeComponents () + { + this.SuspendLayout(); + this.Size = new Size(400, 400); + Board.Location = new Point(0,0); + Board.Size = new Size(400, 400); + Board.Paint += DoPaint; + this.DoubleBuffered = true; + this.MaximizeBox = false; + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; + this.Name = "WorldOfPeacecraft"; + this.ShowIcon = false; + + this.Controls.Add(Board); + this.ResumeLayout(); + this.PerformLayout(); + } + + public void DoPaint (object source, PaintEventArgs args) + { + BufferedGraphics buffer = BufferedGraphicsManager.Current.Allocate (Board.CreateGraphics (), Board.DisplayRectangle); + Graphics g = buffer.Graphics; + PaintMap(g); + buffer.Render(); + } + + public void PaintMap (Graphics g) + { + ITile[,] Map = Backend.GetMap (); + if (Map != null) { + for (int y = 0; y < Map.GetLength(1); y++) { + for (int x = 0; x < Map.GetLength(0); x++) { + PaintTile (g, Map [x, y], x, y); + } + } + } + else { + g.FillRectangle(new SolidBrush(Color.White), Board.DisplayRectangle); + } + } + + public void PaintTile (Graphics g, ITile tile, int x, int y) + { + int posx = x * tileSize; + int posy = y * tileSize; + Color color; + if (tile.IsForest ()) { + color = Color.Green; + } // Stupid parenthesis + else if (tile.IsHuntable ()) { + color = Color.BurlyWood; + } else if (tile.IsWalkable ()) { + color = Color.Yellow; + } else if (tile.IsWall ()) { + color = Color.DarkGray; + } else if (tile.IsWater ()) { + color = Color.Blue; + } else { + color = Color.Black; + } + g.FillRectangle(new SolidBrush(color), posx, posy, tileSize, tileSize); + } + + public void PerformRefresh () + { + ITile[,] map = Backend.GetMap(); + int mapWidth = (map.GetLength(0)) * tileSize; + int mapHeight = (map.GetLength(1)) * tileSize; + this.SuspendLayout(); + this.ClientSize = new Size(mapWidth, mapHeight); + Board.Size = new Size(mapWidth, mapHeight); + this.ResumeLayout(); + this.PerformLayout(); + this.Refresh(); + } + + [DllImport("kernel32.dll", SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + static extern bool AllocConsole(); + } +} diff --git a/src/Gui/IBackend.cs b/src/Gui/IBackend.cs new file mode 100644 index 0000000..1ec4fc5 --- /dev/null +++ b/src/Gui/IBackend.cs @@ -0,0 +1,8 @@ + +namespace WorldOfPeacecraft +{ + public interface IBackend + { + ITile[,] GetMap(); + } +} diff --git a/src/Gui/IGui.cs b/src/Gui/IGui.cs new file mode 100644 index 0000000..4a0a446 --- /dev/null +++ b/src/Gui/IGui.cs @@ -0,0 +1,8 @@ +namespace WorldOfPeacecraft +{ + public interface IGui + { + void PerformRefresh(); + void SetBackend(IBackend backend); + } +} diff --git a/src/Gui/IPositionable.cs b/src/Gui/IPositionable.cs new file mode 100644 index 0000000..4f586a4 --- /dev/null +++ b/src/Gui/IPositionable.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace WorldOfPeacecraft +{ + /// + /// Interface your positionable objects should implement. Such as the dragons and players. + /// This enables the frontend to determine the current position of said objects to render them at the correct space. + /// + public interface IPositionable + { + /// + /// Getter for the x-position + /// + /// the x-position + int GetX(); + /// + /// Getter for the y-position + /// + /// the y-position + int GetY(); + } +} diff --git a/src/Gui/ITile.cs b/src/Gui/ITile.cs new file mode 100644 index 0000000..cd61a15 --- /dev/null +++ b/src/Gui/ITile.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace WorldOfPeacecraft +{ + public interface ITile : IPositionable + { + bool IsWalkable(); + bool IsWall(); + bool IsForest(); + bool IsHuntable(); + bool IsWater(); + } +} diff --git a/src/Gui/Program.cs b/src/Gui/Program.cs new file mode 100644 index 0000000..014673c --- /dev/null +++ b/src/Gui/Program.cs @@ -0,0 +1,20 @@ +using System; +using System.Windows.Forms; + +namespace WorldOfPeacecraft +{ + public class Program + { + static void Main() + { + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + + Gui gui = new Gui(); + Backend backend = new Backend(gui); + gui.SetBackend(backend); + Application.Run (gui); + } + } +} + diff --git a/src/Map.cs b/src/Map.cs index 65f368e..f61bf76 100644 --- a/src/Map.cs +++ b/src/Map.cs @@ -13,8 +13,8 @@ namespace WorldOfPeacecraft public void SetTile (Tile t) { - int x = t.getX (); - int y = t.getY (); + int x = t.GetX (); + int y = t.GetY (); map [x, y] = t; } diff --git a/src/Parser.cs b/src/Parser.cs index b470f3f..5524a24 100644 --- a/src/Parser.cs +++ b/src/Parser.cs @@ -49,47 +49,31 @@ namespace WorldOfPeacecraft public const string MessPlayers = "players"; public const string MessDragon = "dragon"; public const string MessMapcell = "cell"; - private Buffer MonsterBuffer; + private Buffer InputBuffer; private Thread ParserThread; private LinkedList Message; private Regex LastLineRegex; - private Backend backend; + private Backend Backend; - public Parser (Buffer b) + public Parser (Backend backend, Buffer buffer) { - MonsterBuffer = b; - ParserThread = new Thread (new ThreadStart (this.RunParser)); - ParserThread.Start(); + InputBuffer = buffer; + Backend = backend; Message = new LinkedList (); LastLineRegex = new Regex ("^end:[0-9]+$"); + ParserThread = new Thread (new ThreadStart (this.RunParser)); + ParserThread.Start(); } private void RunParser () - {/* + { while (true) { - bool waitRequired = false; - lock (MonsterBuffer) { - if (MonsterBuffer.Count == 0) { - waitRequired = true; - BufferFilledEvent.Reset (); - } - } - if (waitRequired) { - BufferFilledEvent.WaitOne (); - } - lock (Buffer) { - Message.AddLast (Buffer.Dequeue ()); - } + Message.AddLast (InputBuffer.NextLine ()); if (IsCompletePackage ()) { Parse (); } - }*/ + } } - - public Player getDummyPlayer() - { - return DummyPlayer; - } private void Parse () { @@ -188,11 +172,11 @@ namespace WorldOfPeacecraft switch (block.GetName ()) { case MessPlayer: Player player = MapPlayer (block); - backend.removePlayer (player); + Backend.removePlayer (player); break; case MessDragon: Dragon dragon = MapDragon (block); - backend.removeDragon (dragon); + Backend.removeDragon (dragon); break; default: ThrowUnknownBlockException(deleteBlock, block); @@ -215,7 +199,8 @@ namespace WorldOfPeacecraft foreach (Block cell in cellsBlock.GetBlocks()) { map.SetTile(MapMapcell(cell)); } - backend.SetMap(map); + Backend.SetMap(map); + Backend.RefreshGui(); } private void ProcessMessage (Block mesBlock) @@ -286,7 +271,6 @@ namespace WorldOfPeacecraft break; default: throw new ParsingException("Invalid type"); // TODO Better message - break; } bool accepted = challengeBlock.GetBoolValue("accepted"); Challenge c = new Challenge(id, type, accepted); @@ -295,12 +279,12 @@ namespace WorldOfPeacecraft private void ProcessPlayer (Block playerBlock) { - backend.SetPlayer(MapPlayer(playerBlock)); + Backend.SetPlayer(MapPlayer(playerBlock)); } private void ProcessMapcell (Block mapcellBlock) { - backend.getMapObject().SetTile(MapMapcell(mapcellBlock)); + Backend.getMapObject().SetTile(MapMapcell(mapcellBlock)); } private void ProcessYourid (Block yourIdBlock) @@ -329,15 +313,15 @@ namespace WorldOfPeacecraft private void ProcessEntities (Block entitiesBlock) { - backend.clearDragons (); - backend.clearPlayers (); + Backend.clearDragons (); + Backend.clearPlayers (); foreach (Block entityBlock in entitiesBlock.GetBlocks ()) { switch (entityBlock.GetName()) { case MessPlayer: - backend.SetPlayer(MapPlayer(entityBlock)); + Backend.SetPlayer(MapPlayer(entityBlock)); break; case MessDragon: - backend.SetDragon(MapDragon(entityBlock)); + Backend.SetDragon(MapDragon(entityBlock)); break; default: ThrowUnknownBlockException(entitiesBlock, entityBlock); @@ -348,15 +332,15 @@ namespace WorldOfPeacecraft private void ProcessPlayers (Block playersBlock) { - backend.clearPlayers (); + Backend.clearPlayers (); foreach (Block playerBlock in playersBlock.GetBlocks ()) { - backend.SetPlayer(MapPlayer(playerBlock)); + Backend.SetPlayer(MapPlayer(playerBlock)); } } private void ProcessDragon (Block dragonBlock) { - backend.SetDragon(MapDragon(dragonBlock)); + Backend.SetDragon(MapDragon(dragonBlock)); } private Dragon MapDragon (Block dragonBlock) diff --git a/src/Receiver.cs b/src/Receiver.cs index f2428ff..a66e957 100644 --- a/src/Receiver.cs +++ b/src/Receiver.cs @@ -9,13 +9,13 @@ namespace WorldOfPeacecraft { private TcpClient Client; private StreamReader Reader; - private Buffer KillerBuffer; + private Buffer ReceiverBuffer; private Thread ReceiverThread; public Receiver (TcpClient client, Buffer buffer) { this.Client = client; - this.KillerBuffer = buffer; + this.ReceiverBuffer = buffer; ReceiverThread = new Thread(new ThreadStart(this.doReceive)); ReceiverThread.Start(); } @@ -29,7 +29,7 @@ namespace WorldOfPeacecraft { this.Reader = new StreamReader (Client.GetStream ()); while (true) { - KillerBuffer.AddToBuffer(Receive()); + ReceiverBuffer.AddLine(Receive()); } } diff --git a/src/Sender.cs b/src/Sender.cs index b61dd1e..93b1ce0 100644 --- a/src/Sender.cs +++ b/src/Sender.cs @@ -2,16 +2,22 @@ using System; using System.IO; using System.Net.Sockets; using System.Text; +using System.Threading; namespace WorldOfPeacecraft { public class Sender { private TcpClient Client; + private Buffer Buffer; + private Thread SenderThread; - public Sender (TcpClient client) + public Sender (TcpClient client, Buffer buffer) { this.Client = client; + this.Buffer = buffer; + this.SenderThread = new Thread(new ThreadStart(this.threadStart)); + SenderThread.Start(); } public void Send (String message) @@ -20,5 +26,17 @@ namespace WorldOfPeacecraft writer.WriteLine (message); writer.Flush (); } + + private void threadStart () + { + while (true) { + Send (Buffer.NextLine()); + } + } + + public void stop() + { + SenderThread.Abort(); + } } } \ No newline at end of file diff --git a/src/Tile.cs b/src/Tile.cs index bfe40db..fcc5697 100644 --- a/src/Tile.cs +++ b/src/Tile.cs @@ -5,115 +5,104 @@ namespace WorldOfPeacecraft { public class Tile : ITile { - public int x; - public int y; - public Entity entity; - public bool walkable; - public bool wall; - public bool forest; - public bool huntable; - public bool water; + public int X; + public int Y; + public Entity Entity; + public bool Walkable; + public bool Wall; + public bool Forest; + public bool Huntable; + public bool Water; public Tile (int posX, int posY, bool walkable, bool wall, bool forest, bool huntable, bool water) { - this.setX (posX); - this.setY (posY); - this.setWalkable (walkable); - this.setWall(wall); - this.setForest (forest); - this.setHuntable (huntable); - this.setWater (water); + this.SetX (posX); + this.SetY (posY); + this.SetWalkable (walkable); + this.SetWall(wall); + this.SetForest (forest); + this.SetHuntable (huntable); + this.SetWater (water); } - public void setX (int x) + public void SetX (int x) { - this.x = x; + this.X = x; } - public int getX () + public int GetX () { - return x; + return X; } - public int getXPosition () + public void SetY (int y) { - return x; + this.Y = y; } - public void setY (int y) + public int GetY () { - this.y = y; + return Y; } - public int getY () + public void SetEntity (Entity entity) { - return y; + this.Entity = entity; } - public int getYPosition () + public Entity GetEntity () { - return y; + return Entity; } - public void setEntity (Entity entity) + public void SetWalkable (bool walkable) { - this.entity = entity; + this.Walkable = walkable; } - public Entity getEntity () + public bool IsWalkable () { - return entity; + return Walkable; } - public void setWalkable (bool walkable) - { - this.walkable = walkable; - } - - public bool isWalkable () - { - return walkable; - } - - public void setWall(bool wall) + public void SetWall(bool wall) { - this.wall = wall; + this.Wall = wall; } - public bool isWall() + public bool IsWall() { - return wall; + return Wall; } - - public void setForest (bool forest) + public void SetForest (bool forest) { - this.forest = forest; + this.Forest = forest; } - public bool isForest () + public bool IsForest () { - return forest; + return Forest; } - public void setHuntable (bool huntable) + public void SetHuntable (bool huntable) { - this.huntable = huntable; + this.Huntable = huntable; } - public bool isHuntable () + public bool IsHuntable () { - return huntable; + return Huntable; } - public void setWater (bool water) + public void SetWater (bool water) { - this.water = water; + this.Water = water; } - public bool isWater () + public bool IsWater () { - return water; + return Water; } } } \ No newline at end of file From 2f233aa2269048cd14e5f6d059bb8a395bdd9dc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20V=C3=B6gele?= Date: Wed, 30 Apr 2014 17:50:47 +0200 Subject: [PATCH 02/12] SetClientSizeCore statt direktzugriff auf ClientSize --- src/Gui/Gui.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Gui/Gui.cs b/src/Gui/Gui.cs index 670b643..58e5871 100644 --- a/src/Gui/Gui.cs +++ b/src/Gui/Gui.cs @@ -93,7 +93,7 @@ namespace WorldOfPeacecraft int mapWidth = (map.GetLength(0)) * tileSize; int mapHeight = (map.GetLength(1)) * tileSize; this.SuspendLayout(); - this.ClientSize = new Size(mapWidth, mapHeight); + this.SetClientSizeCore(mapWidth, mapHeight); Board.Size = new Size(mapWidth, mapHeight); this.ResumeLayout(); this.PerformLayout(); From ac5aca6dcaf0a27c8aa8d81e666ed91caa1de2c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20V=C3=B6gele?= Date: Wed, 30 Apr 2014 18:03:20 +0200 Subject: [PATCH 03/12] (Hoffentlich) Windows-Fix --- src/Gui/Gui.cs | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/Gui/Gui.cs b/src/Gui/Gui.cs index 58e5871..0858fb7 100644 --- a/src/Gui/Gui.cs +++ b/src/Gui/Gui.cs @@ -89,15 +89,18 @@ namespace WorldOfPeacecraft public void PerformRefresh () { - ITile[,] map = Backend.GetMap(); - int mapWidth = (map.GetLength(0)) * tileSize; - int mapHeight = (map.GetLength(1)) * tileSize; - this.SuspendLayout(); - this.SetClientSizeCore(mapWidth, mapHeight); - Board.Size = new Size(mapWidth, mapHeight); - this.ResumeLayout(); - this.PerformLayout(); - this.Refresh(); + this.BeginInvoke(new MethodInvoker(delegate + { + ITile[,] map = Backend.GetMap(); + int mapWidth = (map.GetLength(0)) * tileSize; + int mapHeight = (map.GetLength(1)) * tileSize; + this.SuspendLayout(); + this.SetClientSizeCore(mapWidth, mapHeight); + Board.Size = new Size(mapWidth, mapHeight); + this.ResumeLayout(); + this.PerformLayout(); + this.Refresh(); + })); } [DllImport("kernel32.dll", SetLastError = true)] From 3be391802aa3fa9cf7d744e464bf6465ec9301ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20V=C3=B6gele?= Date: Wed, 30 Apr 2014 18:28:26 +0200 Subject: [PATCH 04/12] Tile size 32x32 --- src/Gui/Gui.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Gui/Gui.cs b/src/Gui/Gui.cs index 0858fb7..8adfd09 100644 --- a/src/Gui/Gui.cs +++ b/src/Gui/Gui.cs @@ -7,7 +7,7 @@ namespace WorldOfPeacecraft { class Gui : Form, IGui { - private const int tileSize = 16; + private const int tileSize = 32; private const int entitySize = 10; private IBackend Backend; From 3b6f407e1c812ee2dd81273b8485f41757b21bcb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20V=C3=B6gele?= Date: Thu, 1 May 2014 00:57:00 +0200 Subject: [PATCH 05/12] Terminate application after window close --- src/Backend.cs | 7 +++++++ src/Gui/Gui.cs | 6 ++++++ src/Gui/IBackend.cs | 2 ++ src/Sender.cs | 2 +- 4 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/Backend.cs b/src/Backend.cs index aa443e9..b302473 100644 --- a/src/Backend.cs +++ b/src/Backend.cs @@ -110,5 +110,12 @@ namespace WorldOfPeacecraft { Gui.PerformRefresh(); } + + public void Stop() { + Parse.Stop (); + Send.Stop (); + Rec.Stop (); + System.Windows.Forms.Application.Exit (); + } } } diff --git a/src/Gui/Gui.cs b/src/Gui/Gui.cs index 8adfd09..6121d8f 100644 --- a/src/Gui/Gui.cs +++ b/src/Gui/Gui.cs @@ -42,6 +42,12 @@ namespace WorldOfPeacecraft this.PerformLayout(); } + protected override void OnClosing (System.ComponentModel.CancelEventArgs e) + { + base.OnClosing (e); + Backend.Stop (); + } + public void DoPaint (object source, PaintEventArgs args) { BufferedGraphics buffer = BufferedGraphicsManager.Current.Allocate (Board.CreateGraphics (), Board.DisplayRectangle); diff --git a/src/Gui/IBackend.cs b/src/Gui/IBackend.cs index 1ec4fc5..85fe8cb 100644 --- a/src/Gui/IBackend.cs +++ b/src/Gui/IBackend.cs @@ -4,5 +4,7 @@ namespace WorldOfPeacecraft public interface IBackend { ITile[,] GetMap(); + + void Stop(); } } diff --git a/src/Sender.cs b/src/Sender.cs index 93b1ce0..72252e4 100644 --- a/src/Sender.cs +++ b/src/Sender.cs @@ -34,7 +34,7 @@ namespace WorldOfPeacecraft } } - public void stop() + public void Stop() { SenderThread.Abort(); } From 98f50d349092baeac610b88b4e3b973a3aa4a623 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20V=C3=B6gele?= Date: Thu, 1 May 2014 02:09:17 +0200 Subject: [PATCH 06/12] =?UTF-8?q?Zugriffe=20auf=20die=20Datenstrukturen=20?= =?UTF-8?q?des=20Backends=20werden=20jetzt=20=C3=BCber=20locks=20synchroni?= =?UTF-8?q?siert.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Gui/Gui.cs | 4 ++- src/Parser.cs | 67 +++++++++++++++++++++++++++++++++----------------- 2 files changed, 48 insertions(+), 23 deletions(-) diff --git a/src/Gui/Gui.cs b/src/Gui/Gui.cs index 6121d8f..e9f345a 100644 --- a/src/Gui/Gui.cs +++ b/src/Gui/Gui.cs @@ -52,7 +52,9 @@ namespace WorldOfPeacecraft { BufferedGraphics buffer = BufferedGraphicsManager.Current.Allocate (Board.CreateGraphics (), Board.DisplayRectangle); Graphics g = buffer.Graphics; - PaintMap(g); + lock (Backend) { + PaintMap (g); + } buffer.Render(); } diff --git a/src/Parser.cs b/src/Parser.cs index 5524a24..87aa864 100644 --- a/src/Parser.cs +++ b/src/Parser.cs @@ -172,11 +172,15 @@ namespace WorldOfPeacecraft switch (block.GetName ()) { case MessPlayer: Player player = MapPlayer (block); - Backend.removePlayer (player); + lock (Backend) { + Backend.removePlayer (player); + } break; case MessDragon: Dragon dragon = MapDragon (block); - Backend.removeDragon (dragon); + lock (Backend) { + Backend.removeDragon (dragon); + } break; default: ThrowUnknownBlockException(deleteBlock, block); @@ -199,7 +203,9 @@ namespace WorldOfPeacecraft foreach (Block cell in cellsBlock.GetBlocks()) { map.SetTile(MapMapcell(cell)); } - Backend.SetMap(map); + lock (Backend) { + Backend.SetMap (map); + } Backend.RefreshGui(); } @@ -279,12 +285,17 @@ namespace WorldOfPeacecraft private void ProcessPlayer (Block playerBlock) { - Backend.SetPlayer(MapPlayer(playerBlock)); + lock (Backend) { + Backend.SetPlayer (MapPlayer (playerBlock)); + } } private void ProcessMapcell (Block mapcellBlock) { - Backend.getMapObject().SetTile(MapMapcell(mapcellBlock)); + Tile tile = MapMapcell (mapcellBlock); + lock (Backend) { + Backend.getMapObject ().SetTile (tile); + } } private void ProcessYourid (Block yourIdBlock) @@ -313,34 +324,46 @@ namespace WorldOfPeacecraft private void ProcessEntities (Block entitiesBlock) { - Backend.clearDragons (); - Backend.clearPlayers (); - foreach (Block entityBlock in entitiesBlock.GetBlocks ()) { - switch (entityBlock.GetName()) { - case MessPlayer: - Backend.SetPlayer(MapPlayer(entityBlock)); - break; - case MessDragon: - Backend.SetDragon(MapDragon(entityBlock)); - break; - default: - ThrowUnknownBlockException(entitiesBlock, entityBlock); - break; + // This lock can be placed more efficiently. Does it make sense? + lock (Backend) { + Backend.clearDragons (); + Backend.clearPlayers (); + foreach (Block entityBlock in entitiesBlock.GetBlocks ()) { + switch (entityBlock.GetName ()) { + case MessPlayer: + lock (Backend) { + Backend.SetPlayer (MapPlayer (entityBlock)); + } + break; + case MessDragon: + Backend.SetDragon (MapDragon (entityBlock)); + break; + default: + ThrowUnknownBlockException (entitiesBlock, entityBlock); + break; + } } + Backend.RefreshGui(); } } private void ProcessPlayers (Block playersBlock) { - Backend.clearPlayers (); - foreach (Block playerBlock in playersBlock.GetBlocks ()) { - Backend.SetPlayer(MapPlayer(playerBlock)); + // This lock can be placed more efficiently. Does it make sense? + lock (Backend) { + Backend.clearPlayers (); + foreach (Block playerBlock in playersBlock.GetBlocks ()) { + Backend.SetPlayer (MapPlayer (playerBlock)); + } } } private void ProcessDragon (Block dragonBlock) { - Backend.SetDragon(MapDragon(dragonBlock)); + Dragon dragon = MapDragon (dragonBlock); + lock (Backend) { + Backend.SetDragon (dragon); + } } private Dragon MapDragon (Block dragonBlock) From 4b8d4d002d570eaddaaab4d315cd195be7971672 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20V=C3=B6gele?= Date: Thu, 1 May 2014 02:20:56 +0200 Subject: [PATCH 07/12] =?UTF-8?q?Parser=20ruft=20nun=20=C3=BCberall=20Back?= =?UTF-8?q?end.RefreshGui()=20auf,=20wo=20daten=20im=20Backend=20ver=C3=A4?= =?UTF-8?q?ndert=20werden.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Parser.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Parser.cs b/src/Parser.cs index 87aa864..882de3a 100644 --- a/src/Parser.cs +++ b/src/Parser.cs @@ -175,12 +175,14 @@ namespace WorldOfPeacecraft lock (Backend) { Backend.removePlayer (player); } + Backend.RefreshGui (); break; case MessDragon: Dragon dragon = MapDragon (block); lock (Backend) { Backend.removeDragon (dragon); } + Backend.RefreshGui (); break; default: ThrowUnknownBlockException(deleteBlock, block); @@ -288,6 +290,7 @@ namespace WorldOfPeacecraft lock (Backend) { Backend.SetPlayer (MapPlayer (playerBlock)); } + Backend.RefreshGui (); } private void ProcessMapcell (Block mapcellBlock) @@ -296,6 +299,7 @@ namespace WorldOfPeacecraft lock (Backend) { Backend.getMapObject ().SetTile (tile); } + Backend.RefreshGui (); } private void ProcessYourid (Block yourIdBlock) @@ -343,8 +347,8 @@ namespace WorldOfPeacecraft break; } } - Backend.RefreshGui(); } + Backend.RefreshGui(); } private void ProcessPlayers (Block playersBlock) @@ -356,6 +360,7 @@ namespace WorldOfPeacecraft Backend.SetPlayer (MapPlayer (playerBlock)); } } + Backend.RefreshGui (); } private void ProcessDragon (Block dragonBlock) @@ -364,6 +369,7 @@ namespace WorldOfPeacecraft lock (Backend) { Backend.SetDragon (dragon); } + Backend.RefreshGui (); } private Dragon MapDragon (Block dragonBlock) From 85102482a5579e85763cf2fca8aac8b5177ba9ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20V=C3=B6gele?= Date: Thu, 1 May 2014 02:22:00 +0200 Subject: [PATCH 08/12] Entities werden nun auf die Map gezeichnet --- src/Backend.cs | 7 ++++--- src/Gui/Gui.cs | 25 +++++++++++++++++++++++++ src/Gui/IBackend.cs | 5 +++++ 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/src/Backend.cs b/src/Backend.cs index b302473..d80c5e4 100644 --- a/src/Backend.cs +++ b/src/Backend.cs @@ -27,15 +27,16 @@ namespace WorldOfPeacecraft Parse = new Parser (this, receiverBuffer); Rec = new Receiver (Client, receiverBuffer); Send = new Sender (Client, SenderBuffer); - SenderBuffer.AddLine("get:map"); + SenderBuffer.AddLine ("get:map"); + SenderBuffer.AddLine ("get:ents"); } - public IEnumerable getDragons () + public IEnumerable GetDragons () { return Dragons.Values; } - public IEnumerable getPlayers () + public IEnumerable GetPlayers () { return Players.Values; } diff --git a/src/Gui/Gui.cs b/src/Gui/Gui.cs index e9f345a..80c918d 100644 --- a/src/Gui/Gui.cs +++ b/src/Gui/Gui.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Drawing; using System.Windows.Forms; using System.Runtime.InteropServices; @@ -54,6 +55,7 @@ namespace WorldOfPeacecraft Graphics g = buffer.Graphics; lock (Backend) { PaintMap (g); + PaintEntities (g); } buffer.Render(); } @@ -95,11 +97,34 @@ namespace WorldOfPeacecraft g.FillRectangle(new SolidBrush(color), posx, posy, tileSize, tileSize); } + public void PaintEntities (Graphics g) + { + IEnumerable dragons = Backend.GetDragons (); + IEnumerable players = Backend.GetPlayers (); + foreach (IPositionable dragon in dragons) { + PaintEntity (g, dragon); + } + foreach (IPositionable player in players) { + PaintEntity (g, player); + } + } + + public void PaintEntity (Graphics g, IPositionable entity) + { + int x = entity.GetX () * tileSize + tileSize / 2 - entitySize / 2; + int y = entity.GetY () * tileSize + tileSize / 2 - entitySize / 2; + g.FillRectangle (new SolidBrush (Color.Red), x, y, entitySize, entitySize); + g.DrawRectangle (new Pen( new SolidBrush (Color.Black)), x, y, entitySize, entitySize); + } + public void PerformRefresh () { this.BeginInvoke(new MethodInvoker(delegate { ITile[,] map = Backend.GetMap(); + if (map == null) { + return; + } int mapWidth = (map.GetLength(0)) * tileSize; int mapHeight = (map.GetLength(1)) * tileSize; this.SuspendLayout(); diff --git a/src/Gui/IBackend.cs b/src/Gui/IBackend.cs index 85fe8cb..81c818f 100644 --- a/src/Gui/IBackend.cs +++ b/src/Gui/IBackend.cs @@ -1,3 +1,4 @@ +using System.Collections.Generic; namespace WorldOfPeacecraft { @@ -5,6 +6,10 @@ namespace WorldOfPeacecraft { ITile[,] GetMap(); + IEnumerable GetPlayers(); + + IEnumerable GetDragons(); + void Stop(); } } From 9bf7abb46553be7c5d04438bbcd554d7cce3fbe6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20V=C3=B6gele?= Date: Thu, 1 May 2014 17:51:22 +0200 Subject: [PATCH 09/12] =?UTF-8?q?Kleines=20TODO=20f=C3=BCr=20sp=C3=A4ter?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Parser.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Parser.cs b/src/Parser.cs index 882de3a..1fc5fbb 100644 --- a/src/Parser.cs +++ b/src/Parser.cs @@ -213,6 +213,7 @@ namespace WorldOfPeacecraft private void ProcessMessage (Block mesBlock) { + // TODO Ausnahmebehandlung von mehrzeiligen Nachrichten? int srcid = mesBlock.GetIntValue (ValueSourceId); string src = mesBlock.GetStringValue (ValueSource); string txt = mesBlock.GetStringValue (ValueText); From 7ffba859032afa9d3d12b7523728ec8d7fced929 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20V=C3=B6gele?= Date: Thu, 1 May 2014 18:10:01 +0200 Subject: [PATCH 10/12] Threads werden nicht mehr im Konstruktor gestartet, um race conditions zu vermeiden --- src/Backend.cs | 6 ++++++ src/Gui/Gui.cs | 9 +++++++-- src/Gui/IBackend.cs | 2 ++ src/Parser.cs | 8 +++++--- src/Receiver.cs | 8 ++++++-- src/Sender.cs | 6 +++++- 6 files changed, 31 insertions(+), 8 deletions(-) diff --git a/src/Backend.cs b/src/Backend.cs index d80c5e4..07ce862 100644 --- a/src/Backend.cs +++ b/src/Backend.cs @@ -112,6 +112,12 @@ namespace WorldOfPeacecraft Gui.PerformRefresh(); } + public void StartThreads() { + Parse.Start (); + Rec.Start (); + Send.Start (); + } + public void Stop() { Parse.Stop (); Send.Stop (); diff --git a/src/Gui/Gui.cs b/src/Gui/Gui.cs index 80c918d..bfc04a5 100644 --- a/src/Gui/Gui.cs +++ b/src/Gui/Gui.cs @@ -17,7 +17,6 @@ namespace WorldOfPeacecraft public Gui () { AllocConsole(); - InitializeComponents(); } public void SetBackend (IBackend backend) @@ -25,6 +24,13 @@ namespace WorldOfPeacecraft Backend = backend; } + protected override void OnLoad (EventArgs e) + { + base.OnLoad (e); + InitializeComponents (); + Backend.StartThreads (); + } + public void InitializeComponents () { this.SuspendLayout(); @@ -40,7 +46,6 @@ namespace WorldOfPeacecraft this.Controls.Add(Board); this.ResumeLayout(); - this.PerformLayout(); } protected override void OnClosing (System.ComponentModel.CancelEventArgs e) diff --git a/src/Gui/IBackend.cs b/src/Gui/IBackend.cs index 81c818f..0a583af 100644 --- a/src/Gui/IBackend.cs +++ b/src/Gui/IBackend.cs @@ -10,6 +10,8 @@ namespace WorldOfPeacecraft IEnumerable GetDragons(); + void StartThreads(); + void Stop(); } } diff --git a/src/Parser.cs b/src/Parser.cs index 1fc5fbb..01d9d09 100644 --- a/src/Parser.cs +++ b/src/Parser.cs @@ -62,7 +62,6 @@ namespace WorldOfPeacecraft Message = new LinkedList (); LastLineRegex = new Regex ("^end:[0-9]+$"); ParserThread = new Thread (new ThreadStart (this.RunParser)); - ParserThread.Start(); } private void RunParser () @@ -454,12 +453,15 @@ namespace WorldOfPeacecraft return LastLineRegex.IsMatch (lastLine); } + public void Start () + { + ParserThread.Start(); + } + public void Stop () { ParserThread.Abort (); } - - private class Block { diff --git a/src/Receiver.cs b/src/Receiver.cs index a66e957..82a9851 100644 --- a/src/Receiver.cs +++ b/src/Receiver.cs @@ -17,7 +17,6 @@ namespace WorldOfPeacecraft this.Client = client; this.ReceiverBuffer = buffer; ReceiverThread = new Thread(new ThreadStart(this.doReceive)); - ReceiverThread.Start(); } public string Receive () @@ -33,9 +32,14 @@ namespace WorldOfPeacecraft } } + public void Start() + { + ReceiverThread.Start (); + } + public void Stop() { - ReceiverThread.Abort(); + ReceiverThread.Abort (); } } } diff --git a/src/Sender.cs b/src/Sender.cs index 72252e4..9453498 100644 --- a/src/Sender.cs +++ b/src/Sender.cs @@ -17,7 +17,6 @@ namespace WorldOfPeacecraft this.Client = client; this.Buffer = buffer; this.SenderThread = new Thread(new ThreadStart(this.threadStart)); - SenderThread.Start(); } public void Send (String message) @@ -34,6 +33,11 @@ namespace WorldOfPeacecraft } } + public void Start() + { + SenderThread.Start(); + } + public void Stop() { SenderThread.Abort(); From 8cada1d5cec1bcefad9abae0f8320bcad480383d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20V=C3=B6gele?= Date: Thu, 1 May 2014 19:06:58 +0200 Subject: [PATCH 11/12] =?UTF-8?q?Die=20Gui=20hat=20nun=20ein=20Chatfenster?= =?UTF-8?q?.=20Bisher=20k=C3=B6nnen=20lediglich=20nachrichten=20versandt,?= =?UTF-8?q?=20jedoch=20nicht=20empfangen=20werden.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- inf3.csproj | 13 ++++--- src/Backend.cs | 6 ++- src/Gui/ChatInputBox.cs | 82 +++++++++++++++++++++++++++++++++++++++++ src/Gui/ChatPanel.cs | 46 +++++++++++++++++++++++ src/Gui/Gui.cs | 37 ++++++++++++------- src/Gui/IBackend.cs | 4 ++ 6 files changed, 167 insertions(+), 21 deletions(-) create mode 100644 src/Gui/ChatInputBox.cs create mode 100644 src/Gui/ChatPanel.cs diff --git a/inf3.csproj b/inf3.csproj index 9f8ef15..d71f91a 100644 --- a/inf3.csproj +++ b/inf3.csproj @@ -9,26 +9,27 @@ Exe inf3 inf3 + v4.0 - true + True full - false + False bin\Debug DEBUG; prompt 4 x86 - false + False none - true + True bin\Release prompt 4 x86 - false + False @@ -75,6 +76,8 @@ + + diff --git a/src/Backend.cs b/src/Backend.cs index 07ce862..f42b9e8 100644 --- a/src/Backend.cs +++ b/src/Backend.cs @@ -99,12 +99,14 @@ namespace WorldOfPeacecraft return Map.GetTiles (); } - public void sendCommand (string command) + public void SendCommand (string command) { + SenderBuffer.AddLine (command); } - public void sendChat (string message) + public void SendChatMessage (string message) { + SenderBuffer.AddLine ("ask:say:" + message); } public void RefreshGui() diff --git a/src/Gui/ChatInputBox.cs b/src/Gui/ChatInputBox.cs new file mode 100644 index 0000000..2ff32f8 --- /dev/null +++ b/src/Gui/ChatInputBox.cs @@ -0,0 +1,82 @@ +using System; +using System.Collections.Generic; +using System.Windows.Forms; + +namespace WorldOfPeacecraft +{ + public class ChatInputBox : TextBox + { + private LinkedList InputHistory = new LinkedList(); + private LinkedListNode CurrentHistoryEntry; + + public delegate void ChatMessageSubmittedEventHandler (string message); + public event ChatMessageSubmittedEventHandler ChatMessageSubmitted; + + public ChatInputBox () + { + this.KeyDown += KeyDownEvent; + this.KeyPress += KeyPressEvent; + } + + private void KeyPressEvent (object o, KeyPressEventArgs args) + { + // Supress the "ding"-sound + if (args.KeyChar == (char)Keys.Return) { + args.Handled = true; + } + } + + private void KeyDownEvent (object o, KeyEventArgs args) + { + if (args.KeyCode == Keys.Return) { + if (this.Text != "") + { + string message = this.Text; + this.Text = ""; + if (CurrentHistoryEntry == null) { + InputHistory.AddLast (message); + } + else { + CurrentHistoryEntry.Value = message; + CurrentHistoryEntry = null; + } + if (ChatMessageSubmitted != null) { + this.ChatMessageSubmitted (message); + } + } + args.Handled = true; + } else if (args.KeyCode == Keys.Up) { + if (InputHistory.Count > 0) { + if (CurrentHistoryEntry == null) { + CurrentHistoryEntry = InputHistory.Last; + if (this.Text != "") + { + InputHistory.AddLast(this.Text); + } + this.Text = CurrentHistoryEntry.Value; + args.Handled = true; + } else { + if (CurrentHistoryEntry != InputHistory.First) { + CurrentHistoryEntry.Value = this.Text; + CurrentHistoryEntry = CurrentHistoryEntry.Previous; + this.Text = CurrentHistoryEntry.Value; + args.Handled = true; + } + } + } + } else if (args.KeyCode == Keys.Down) { + if (CurrentHistoryEntry != null) + { + CurrentHistoryEntry.Value = this.Text; + CurrentHistoryEntry = CurrentHistoryEntry.Next; + if (CurrentHistoryEntry == null) { + this.Text = ""; + } else { + this.Text = CurrentHistoryEntry.Value; + } + } + } + } + } + +} diff --git a/src/Gui/ChatPanel.cs b/src/Gui/ChatPanel.cs new file mode 100644 index 0000000..3a95af3 --- /dev/null +++ b/src/Gui/ChatPanel.cs @@ -0,0 +1,46 @@ +using System.Drawing; +using System.Windows.Forms; + +namespace WorldOfPeacecraft +{ + public class ChatPanel : Panel + { + private ChatInputBox ChatInput; + private TextBox ChatOutput; + private IBackend Backend; + + public ChatPanel (IBackend backend) + { + Backend = backend; + ChatInput = new ChatInputBox (); + ChatInput.ChatMessageSubmitted += OnChatMessageSent; + ChatOutput = new TextBox (); + ChatOutput.ReadOnly = true; + ChatOutput.Multiline = true; + + this.Controls.Add (ChatInput); + this.Controls.Add (ChatOutput); + } + + protected override void OnLayout (LayoutEventArgs levent) + { + int outputHeight = this.ClientSize.Height - ChatInput.Height; + ChatOutput.Location = new Point (0, 0); + ChatOutput.Size = new Size (this.ClientSize.Width, outputHeight); + ChatInput.Location = new Point (0, outputHeight); + ChatInput.Size = new Size (this.ClientSize.Width, ChatInput.ClientSize.Width); + base.OnLayout (levent); + } + + private void OnChatMessageSent (string message) + { + if (message.StartsWith ("/")) { + string command = message.Substring (1); + Backend.SendCommand(command); + } else { + Backend.SendChatMessage(message); + } + // TODO Move focus to board? + } + } +} diff --git a/src/Gui/Gui.cs b/src/Gui/Gui.cs index bfc04a5..5323578 100644 --- a/src/Gui/Gui.cs +++ b/src/Gui/Gui.cs @@ -8,11 +8,13 @@ namespace WorldOfPeacecraft { class Gui : Form, IGui { - private const int tileSize = 32; - private const int entitySize = 10; + private const int TileSize = 32; + private const int EntitySize = 10; + private const int ChatWidth = 300; private IBackend Backend; private Panel Board = new Panel(); + private ChatPanel ChatPanel; public Gui () { @@ -33,18 +35,23 @@ namespace WorldOfPeacecraft public void InitializeComponents () { + ChatPanel = new ChatPanel (Backend); this.SuspendLayout(); - this.Size = new Size(400, 400); + this.Size = new Size(400 + ChatWidth, 400); Board.Location = new Point(0,0); Board.Size = new Size(400, 400); Board.Paint += DoPaint; + ChatPanel.Location = new Point (400, 0); + ChatPanel.Size = new Size (300, 400); this.DoubleBuffered = true; this.MaximizeBox = false; this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; this.Name = "WorldOfPeacecraft"; this.ShowIcon = false; - this.Controls.Add(Board); + this.Controls.Add (Board); + this.Controls.Add (ChatPanel); + this.ResumeLayout(); } @@ -82,8 +89,8 @@ namespace WorldOfPeacecraft public void PaintTile (Graphics g, ITile tile, int x, int y) { - int posx = x * tileSize; - int posy = y * tileSize; + int posx = x * TileSize; + int posy = y * TileSize; Color color; if (tile.IsForest ()) { color = Color.Green; @@ -99,7 +106,7 @@ namespace WorldOfPeacecraft } else { color = Color.Black; } - g.FillRectangle(new SolidBrush(color), posx, posy, tileSize, tileSize); + g.FillRectangle(new SolidBrush(color), posx, posy, TileSize, TileSize); } public void PaintEntities (Graphics g) @@ -116,10 +123,10 @@ namespace WorldOfPeacecraft public void PaintEntity (Graphics g, IPositionable entity) { - int x = entity.GetX () * tileSize + tileSize / 2 - entitySize / 2; - int y = entity.GetY () * tileSize + tileSize / 2 - entitySize / 2; - g.FillRectangle (new SolidBrush (Color.Red), x, y, entitySize, entitySize); - g.DrawRectangle (new Pen( new SolidBrush (Color.Black)), x, y, entitySize, entitySize); + int x = entity.GetX () * TileSize + TileSize / 2 - EntitySize / 2; + int y = entity.GetY () * TileSize + TileSize / 2 - EntitySize / 2; + g.FillRectangle (new SolidBrush (Color.Red), x, y, EntitySize, EntitySize); + g.DrawRectangle (new Pen( new SolidBrush (Color.Black)), x, y, EntitySize, EntitySize); } public void PerformRefresh () @@ -130,11 +137,13 @@ namespace WorldOfPeacecraft if (map == null) { return; } - int mapWidth = (map.GetLength(0)) * tileSize; - int mapHeight = (map.GetLength(1)) * tileSize; + int mapWidth = (map.GetLength(0)) * TileSize; + int mapHeight = (map.GetLength(1)) * TileSize; this.SuspendLayout(); - this.SetClientSizeCore(mapWidth, mapHeight); + this.SetClientSizeCore(mapWidth + ChatWidth, mapHeight); Board.Size = new Size(mapWidth, mapHeight); + ChatPanel.Location = new Point (mapWidth, 0); + ChatPanel.Size = new Size (ChatWidth, mapHeight); this.ResumeLayout(); this.PerformLayout(); this.Refresh(); diff --git a/src/Gui/IBackend.cs b/src/Gui/IBackend.cs index 0a583af..1128290 100644 --- a/src/Gui/IBackend.cs +++ b/src/Gui/IBackend.cs @@ -10,6 +10,10 @@ namespace WorldOfPeacecraft IEnumerable GetDragons(); + void SendChatMessage (string message); + + void SendCommand (string command); + void StartThreads(); void Stop(); From 30579e148800aac65f27fd6e395080c72e7180a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20V=C3=B6gele?= Date: Thu, 1 May 2014 20:30:33 +0200 Subject: [PATCH 12/12] Chatnachrichten werden jetzt angezeigt --- inf3.csproj | 2 ++ src/Backend.cs | 12 ++++++++++ src/Gui/ChatOutputBox.cs | 52 ++++++++++++++++++++++++++++++++++++++++ src/Gui/ChatPanel.cs | 11 +++++---- src/Gui/Gui.cs | 1 + src/Gui/IBackend.cs | 2 ++ src/Gui/IChatMessage.cs | 11 +++++++++ src/Message.cs | 17 ++++++++++++- src/Parser.cs | 5 +++- 9 files changed, 107 insertions(+), 6 deletions(-) create mode 100644 src/Gui/ChatOutputBox.cs create mode 100644 src/Gui/IChatMessage.cs diff --git a/inf3.csproj b/inf3.csproj index d71f91a..eb5c186 100644 --- a/inf3.csproj +++ b/inf3.csproj @@ -78,6 +78,8 @@ + + diff --git a/src/Backend.cs b/src/Backend.cs index f42b9e8..433e674 100644 --- a/src/Backend.cs +++ b/src/Backend.cs @@ -12,6 +12,7 @@ namespace WorldOfPeacecraft private TcpClient Client; private Dictionary Dragons; private Dictionary Players; + private LinkedList ChatMessages; private Map Map; private Buffer SenderBuffer; private IGui Gui; @@ -21,6 +22,7 @@ namespace WorldOfPeacecraft Gui = gui; Dragons = new Dictionary (); Players = new Dictionary (); + ChatMessages = new LinkedList (); Client = new TcpClient ("localhost", 9999); Buffer receiverBuffer = new Buffer(10000); SenderBuffer = new Buffer(100); @@ -99,6 +101,16 @@ namespace WorldOfPeacecraft return Map.GetTiles (); } + public void AddChatMessage (Message message) + { + ChatMessages.AddLast (message); + } + + public IEnumerable GetChatMessages () + { + return ChatMessages; + } + public void SendCommand (string command) { SenderBuffer.AddLine (command); diff --git a/src/Gui/ChatOutputBox.cs b/src/Gui/ChatOutputBox.cs new file mode 100644 index 0000000..be05f88 --- /dev/null +++ b/src/Gui/ChatOutputBox.cs @@ -0,0 +1,52 @@ +using System.Collections.Generic; +using System.Drawing; +using System.Windows.Forms; + +namespace WorldOfPeacecraft +{ + public class ChatOutputBox : RichTextBox + { + private IBackend Backend; + private Font MessageFont; + private Font SenderFont; + private Font IregularSenderFont; + + public ChatOutputBox (IBackend backend) + { + Backend = backend; + this.ReadOnly = true; + this.Multiline = true; + MessageFont = this.SelectionFont; + SenderFont = new Font (MessageFont, FontStyle.Bold); + IregularSenderFont = new Font (MessageFont, FontStyle.Bold | FontStyle.Italic); + } + + public void UpdateData () + { + this.SuspendLayout (); + this.Clear (); + IEnumerable chatMessages = Backend.GetChatMessages (); + bool firstline = true; + lock (Backend) { + foreach (IChatMessage message in chatMessages) { + if (firstline) { + firstline = false; + } else { + this.AppendText ("\n"); + } + if (message.IsSenderPlayer ()) { + this.SelectionFont = SenderFont; + } else { + this.SelectionFont = IregularSenderFont; + } + this.AppendText (message.GetSender ()); + this.AppendText (": "); + this.SelectionFont = MessageFont; + this.AppendText (message.GetMessage ()); + } + } + this.ResumeLayout (); + } + } +} + diff --git a/src/Gui/ChatPanel.cs b/src/Gui/ChatPanel.cs index 3a95af3..bcc3e4e 100644 --- a/src/Gui/ChatPanel.cs +++ b/src/Gui/ChatPanel.cs @@ -6,7 +6,7 @@ namespace WorldOfPeacecraft public class ChatPanel : Panel { private ChatInputBox ChatInput; - private TextBox ChatOutput; + private ChatOutputBox ChatOutput; private IBackend Backend; public ChatPanel (IBackend backend) @@ -14,9 +14,7 @@ namespace WorldOfPeacecraft Backend = backend; ChatInput = new ChatInputBox (); ChatInput.ChatMessageSubmitted += OnChatMessageSent; - ChatOutput = new TextBox (); - ChatOutput.ReadOnly = true; - ChatOutput.Multiline = true; + ChatOutput = new ChatOutputBox (backend); this.Controls.Add (ChatInput); this.Controls.Add (ChatOutput); @@ -42,5 +40,10 @@ namespace WorldOfPeacecraft } // TODO Move focus to board? } + + public void UpdateData() + { + ChatOutput.UpdateData (); + } } } diff --git a/src/Gui/Gui.cs b/src/Gui/Gui.cs index 5323578..f8786da 100644 --- a/src/Gui/Gui.cs +++ b/src/Gui/Gui.cs @@ -146,6 +146,7 @@ namespace WorldOfPeacecraft ChatPanel.Size = new Size (ChatWidth, mapHeight); this.ResumeLayout(); this.PerformLayout(); + ChatPanel.UpdateData (); this.Refresh(); })); } diff --git a/src/Gui/IBackend.cs b/src/Gui/IBackend.cs index 1128290..7361313 100644 --- a/src/Gui/IBackend.cs +++ b/src/Gui/IBackend.cs @@ -10,6 +10,8 @@ namespace WorldOfPeacecraft IEnumerable GetDragons(); + IEnumerable GetChatMessages(); + void SendChatMessage (string message); void SendCommand (string command); diff --git a/src/Gui/IChatMessage.cs b/src/Gui/IChatMessage.cs new file mode 100644 index 0000000..69b40ba --- /dev/null +++ b/src/Gui/IChatMessage.cs @@ -0,0 +1,11 @@ +namespace WorldOfPeacecraft +{ + public interface IChatMessage + { + string GetMessage(); + + string GetSender(); + + bool IsSenderPlayer(); + } +} \ No newline at end of file diff --git a/src/Message.cs b/src/Message.cs index 794e6f1..1ee3d99 100644 --- a/src/Message.cs +++ b/src/Message.cs @@ -2,7 +2,7 @@ namespace WorldOfPeacecraft { - public class Message + public class Message : IChatMessage { int sourceID; string source; @@ -14,6 +14,21 @@ namespace WorldOfPeacecraft source = src; text = txt; } + + public string GetMessage() + { + return text; + } + + public string GetSender() + { + return source; + } + + public bool IsSenderPlayer () + { + return true; + } } } diff --git a/src/Parser.cs b/src/Parser.cs index 01d9d09..265ed56 100644 --- a/src/Parser.cs +++ b/src/Parser.cs @@ -216,7 +216,10 @@ namespace WorldOfPeacecraft int srcid = mesBlock.GetIntValue (ValueSourceId); string src = mesBlock.GetStringValue (ValueSource); string txt = mesBlock.GetStringValue (ValueText); - Message m = new Message (srcid, src, txt); + lock (Backend) { + Backend.AddChatMessage (new Message (srcid, src, txt)); + } + Backend.RefreshGui (); } private void ProcessAnswer (Block block)