do i even need this pqueue?

pull/5/head
Jordan Orelli 10 years ago
parent 8a5bbcd658
commit 4f45c203f7

@ -13,13 +13,6 @@ type Command struct {
handler func(*Connection, ...string)
}
// var scanCommand = &Command{
// name: "scan",
// help: "scans for resources",
// handler: func(conn *Connection, args ...string) {
// },
// }
var infoCommand = &Command{
name: "info",
help: "gives you some info about your current position",
@ -80,18 +73,24 @@ var commandsCommand = &Command{
},
}
// var superscanCommand = &Command{
// name: "super-scan",
// help: "super duper scan",
// handler: func(conn *Connection, args ...string) {
// for id, _ := range index {
// if id == conn.System().id {
// continue
// }
//
// }
// },
// }
var scanCommand = &Command{
name: "scan",
help: "super duper scan",
handler: func(conn *Connection, args ...string) {
system := conn.System()
log_info("scan sent from %s", system.name)
for id, _ := range index {
if id == system.id {
continue
}
delay := system.TimeTo(index[id])
id2 := id
After(delay, func() {
scanSystem(id2, system.id)
})
}
},
}
func isCommand(name string) bool {
_, ok := commandRegistry[name]
@ -117,4 +116,5 @@ func init() {
registerCommand(helpCommand)
registerCommand(infoCommand)
registerCommand(nearbyCommand)
registerCommand(scanCommand)
}

@ -7,7 +7,6 @@ import (
"net"
"os"
"strings"
"sync"
"time"
)
@ -35,8 +34,6 @@ func bail(status int, template string, args ...interface{}) {
}
func handleConnection(conn *Connection) {
var mu sync.Mutex
defer conn.Close()
conn.Login()
@ -69,20 +66,6 @@ func handleConnection(conn *Connection) {
}
switch parts[0] {
case "scan":
for _, otherSystem := range index {
if otherSystem.name == system.name {
continue
}
go func(p *System) {
dist := system.DistanceTo(p)
delay := time.Duration(int64(dist * 100000000))
time.Sleep(delay)
mu.Lock()
fmt.Fprintf(conn, "PONG from system %s (%v)\n", p.name, delay)
mu.Unlock()
}(otherSystem)
}
case "broadcast":
msg := strings.Join(parts[1:], " ")
log_info("player %s is broadcasting message %s", conn.PlayerName(), msg)
@ -101,18 +84,6 @@ func handleConnection(conn *Connection) {
})
}(otherSystem)
}
// case "nearby":
// neighbors, err := system.Nearby(25)
// fmt.Fprintf(conn, "fetching nearby star systems\n")
// if err != nil {
// log_error("%v", err)
// break
// }
// fmt.Fprintf(conn, "found %d nearby systems\n", len(neighbors))
// for _, neighbor := range neighbors {
// other := index[neighbor.id]
// fmt.Fprintf(conn, "%s: %v\n", other.name, neighbor.distance)
// }
case "quit":
return
default:
@ -130,6 +101,7 @@ func main() {
if err != nil {
bail(E_No_Port, "unable to start server: %v", err)
}
go RunQueue()
for {
conn, err := listener.Accept()
if err != nil {

@ -5,6 +5,7 @@ import (
"fmt"
"math"
"math/rand"
"time"
)
var (
@ -65,6 +66,10 @@ func (s *System) DistanceTo(other *System) float64 {
return dist3d(s.x, s.y, s.z, other.x, other.y, other.z)
}
func (s *System) TimeTo(other *System) time.Duration {
return time.Duration(int64(s.DistanceTo(other) * 100000000))
}
func (e System) String() string {
return fmt.Sprintf("<name: %s x: %v y: %v z: %v planets: %v>", e.name, e.x, e.y, e.z, e.planets)
}
@ -144,3 +149,20 @@ func randomSystem() (*System, error) {
planet := index[pick]
return planet, nil
}
func scanSystem(id int, reply int) {
system := index[id]
source := index[reply]
delay := system.TimeTo(source)
log_info("scan hit %s from %s after traveling for %v", system.name, source.name, delay)
After(delay, func() {
deliverReply(source.id, system.id)
})
}
func deliverReply(id int, echo int) {
system := index[id]
source := index[echo]
delay := system.TimeTo(source)
log_info("echo received at %s reflected from %s after traveling for %v", system.name, source.name, delay)
}

@ -0,0 +1,74 @@
package main
import (
"container/heap"
"time"
)
var queue = make(Queue, 0, 32)
type Future struct {
ts time.Time
index int
work func()
}
type Queue []*Future
func (q Queue) Len() int { return len(q) }
func (q Queue) Less(i, j int) bool {
return q[i].ts.Before(q[j].ts)
}
func (q Queue) Swap(i, j int) {
q[i], q[j] = q[j], q[i]
q[i].index = j
q[j].index = i
}
func (q *Queue) Push(v interface{}) {
n := len(*q)
future := v.(*Future)
future.index = n
*q = append(*q, future)
}
func (q *Queue) Pop() interface{} {
old := *q
n := len(old)
future := old[n-1]
future.index = -1
*q = old[0 : n-1]
return future
}
func At(ts time.Time, work func()) {
heap.Push(&queue, &Future{ts: ts, work: work})
}
func After(delay time.Duration, work func()) {
heap.Push(&queue, &Future{ts: time.Now().Add(delay), work: work})
}
func RunQueue() {
defer log_info("Queue runner done.")
heap.Init(&queue)
for {
if len(queue) == 0 {
time.Sleep(100 * time.Microsecond)
continue
}
future, ok := heap.Pop(&queue).(*Future)
if !ok {
log_error("there's shit on the work heap")
continue
}
log_info("we have a work item with delay %v", time.Since(future.ts))
if future.ts.After(time.Now()) {
time.Sleep(future.ts.Sub(time.Now()))
}
log_info("performing work")
future.work()
}
}
Loading…
Cancel
Save