39d48991a79b

Make some data structures. Everything is broken right now.
[view raw] [browse files]
author Steve Losh <steve@stevelosh.com>
date Thu, 21 Jul 2011 20:14:53 -0400
parents 2e6076224d34
children c4629568f91a
branches/tags (none)
files src/clojurecraft/core.clj src/clojurecraft/data.clj todo.org

Changes

--- a/src/clojurecraft/core.clj	Thu Jul 21 18:59:53 2011 -0400
+++ b/src/clojurecraft/core.clj	Thu Jul 21 20:14:53 2011 -0400
@@ -3,6 +3,7 @@
   (:use [clojurecraft.in])
   (:use [clojurecraft.out])
   (:use [clojurecraft.util])
+  (:use [clojurecraft.data])
   (:use [clojure.contrib.pprint :only (pprint)])
   (:require [clojurecraft.actions :as act])
   (:import (java.net Socket)
@@ -14,6 +15,19 @@
 (declare conn-handler)
 (declare login)
 
+; Connections ----------------------------------------------------------------------
+(def *worlds* (ref {}))
+(defn get-world [server]
+  (dosync
+    (ensure *worlds*)
+    (let [world (@*worlds* server)]
+      (if world
+        world
+        (do
+          (alter *worlds* assoc server (World. server (ref {}) (ref {}) (ref 0)))
+          (@*worlds* server))))))
+
+
 (defn login [bot username]
   ; Send handshake
   (write-packet bot :handshake {:username username})
@@ -57,9 +71,10 @@
         out (DataOutputStream. (.getOutputStream socket))
         conn (ref {:in in :out out})
         outqueue (LinkedBlockingQueue.)
+
+        world (get-world server)
         player (ref {:location {:onground false, :pitch 0.0, :yaw 0.0, :z 240.0,
                                 :y 85.0, :stance 60.0, :x -120.0}})
-        world (ref {})
         bot {:connection conn, :outqueue outqueue, :player player, :world world,
              :packet-counts-in (atom {}), :packet-counts-out (atom {})}]
 
@@ -86,10 +101,11 @@
   (dosync (alter (:connection bot) merge {:exit true})))
 
 
+; Utility functions ----------------------------------------------------------------
 
 ; Scratch --------------------------------------------------------------------------
-(def bot (connect minecraft-local "Honeydew"))
-(act/move bot 0 -1 0)
+;(def bot (connect minecraft-local "Honeydew"))
+;(act/move bot 0 -1 0)
 ;(pprint @(:packet-counts-in bot))
 ;(pprint @(:packet-counts-out bot))
 ;(pprint (:player bot))
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/clojurecraft/data.clj	Thu Jul 21 20:14:53 2011 -0400
@@ -0,0 +1,92 @@
+(ns clojurecraft.data)
+
+; Location
+;
+; The location of an entity in the world.
+;
+; x        -> double
+; y        -> double
+; z        -> double
+; pitch    -> double
+; yaw      -> double
+; stance   -> double
+; onground -> boolean
+(defrecord Location [x y z pitch yaw stance onground])
+
+; Entity
+;
+; A single entity in the world.
+;
+; eid -> integer
+; loc -> Location
+;
+; despawned -> boolean
+;   True if the entity has been despawned.
+;
+;   This exists to notify transactions coordinating on this ref that
+;   something has changed, since otherwise there would be no way to tell
+;   (despawning would simply remove the object from the entity list
+;   without modifying it).
+(defrecord Entity [eid loc despawned])
+
+; Chunk
+;
+; A single chunk in the world.
+(defrecord Chunk [])
+
+; Block
+;
+; A representation of a single block.
+; This may be removed in the future if the overhead is too great.
+;
+; loc  -> [x y z]
+;   A simple vector of three coordinates, NOT a Location (for performance).
+;
+; kind -> TODO
+(defrecord Block [loc kind])
+
+; Bot
+;
+; A single bot, connected to a server.
+;
+; connection -> (ref {:in DataInputStream :out :DataOutputStream})
+;   The input and output streams.
+;
+;   Don't ever touch this -- the writing thread will handle it.
+;
+; outqueue -> LinkedBlockingQueue
+;   A queue of packets to write, so we can coordinate the writes
+;   to avoid mixing packets together.
+;
+;   Don't ever touch this.  Use out/-write-packet-* instead.
+;
+; player -> (ref Entity)
+;   A ref to the Entity representing the bot's player in the world.
+;
+; world -> World
+;   The world the bot is connected to.
+;
+;   NOT a ref.  Coordinating the entire world would be too much of a performance
+;   hit.  Instead the individual pieces of the world are refs.
+;
+;   Worlds themselves should never need to be updated after creation -- instead the
+;   various refs inside them are updated.
+;
+; packet-counts-in  -> integer
+; packet-counts-out -> integer
+(defrecord Bot [connection outqueue player world
+                packet-counts-in packet-counts-out])
+
+; World
+;
+; A representation of a single world/server, shared by all bots connected to it.
+;
+; server   -> {:name hostname :port port}
+; entities -> (ref {eid (ref Entity) ...})
+;             A map of all the entities in the world.
+; chunks   -> (ref {[x y z] [(ref Chunk) ...] ...})
+;             A map of all the chunks in the world.
+; time     -> (ref integer)
+;             The current world time.
+(defrecord World [server entities chunks time])
+
--- a/todo.org	Thu Jul 21 18:59:53 2011 -0400
+++ b/todo.org	Thu Jul 21 20:14:53 2011 -0400
@@ -1,5 +1,3 @@
-* DONE Wrap all IO in io!.
-* TODO Wrap class mutations in io!?
 * TODO Use Clojure's ugly keyword arguments.
 
   (defn dothreads! [f & {thread-count :threads exec-count :times
@@ -7,60 +5,3 @@
   ...)
 
 * TODO Use some pre/post conditions.
-* TODO Make records for common pieces of data.
-** TODO Locations
-** TODO Entities
-** TODO Chunks
-* TODO Relayout the data structures.
-** TODO Servers
-
-   { 'localhost' world1,
-     '222.222.111.232' world2,
-     ... }
-
-** TODO World
-
-   { :entities {},
-     :chunks {}, }
-
-** TODO Entities
-
-   { 123 {},
-     234 {},
-     ... }
-
-** TODO Entity (ref)
-
-   { :eid 123,
-     :location location,
-     ...? }
-
-** TODO Location
-
-   { :x 100.0,
-     :y 100.1,
-     :z 80.3,
-     :stance 101.0,
-     :yaw 11.0,
-     :pitch 81.0,
-     :onground true }
-
-** TODO Chunks
-
-   { [1,23,12] (ref? chunk),
-     ... }
-
-** TODO Chunk (ref?)
-
-   { ? }
-
-** TODO Bot
-
-   { :world world,
-     :eid 123,
-     :connections { :in in-conn,
-                    :out out-conn },
-     :packet-counts { :in (atom 123),
-                      :out (atom 234) },
-     ...? }
-