func startUpdateTracker(g grid2d.Grid, numUpdates *int64) { ch := make(chan []grid2d.Update, 0) go func() { for updates := range ch { atomic.AddInt64(numUpdates, int64(len(updates))) } }() g.Subscribe(ch) }
func startAndMaintainOrgs(g grid2d.Grid) { // Obtain an initial count before we start anything executing. mCount := maintain.Count(g, isOrg) ch := make(chan []grid2d.Update, 0) g.Subscribe(ch) // Start all organisms currently existing in the Grid. We do this *after* // subscribing ch so that we don't end up with a wrong count if any organisms // divide or die. cpu1.StartAll(g) go maintain.Maintain(ch, isOrg, func() { startOrg(g) }, minOrgs, mCount) }
func startPrintLoop(g grid2d.Grid, cns *census.DirCensus, cond *sync.Cond, numUpdates *int64, clearScreen bool) { // We want to use chanbuf.Tick to ensure renders occur at specific intervals regardless // of the rate at which updates arrive. To prevent the notification channel from backing up // and causing deadlock, we buffer using a chanbuf.Trigger (since we don't care about the // update messages themselves). We could have used a time.Tick instead, but we'd need to // do something special to ensure this loop exits when the notifications stop. // grid notifier -> updateCh -> trigger -> tick -> print world // grid notifier first dispatches an update the moment it occurs // trigger consumes the event and flags that an update occurred // tick fires every freq, halting when trigger reports it's closed // printLoop renders the grid every time tick fires updateCh := make(chan []grid2d.Update, 0) trigger := chanbuf.Trigger() freq := time.Duration(1000000.0/printRate) * time.Microsecond go chanbuf.Feed(trigger, grid2d.NotifyToInterface(updateCh)) tickCh := chanbuf.Tick(trigger, freq, true) g.Subscribe(updateCh) go printLoop(grid2d.NotifyFromInterface(tickCh), g, cns, cond, numUpdates, clearScreen) }
func startCensus(g grid2d.Grid) *census.DirCensus { // Create a new Census that writes to /tmp/census when a population grows to 40. cns, err := census.NewDirCensus("/tmp/census", func(p census.Population) bool { return p.Count > 40 }) if err != nil { fmt.Printf("Error creating census: %v\n", err) os.Exit(1) } // Use human times. timeNow := func(interface{}) interface{} { return time.Now() } ch := make(chan []grid2d.Update, 0) g.Subscribe(ch) // Populate the Census with what's already in the world (perhaps restored from an autosave). // Assumes nothing in the world is changing yet. grid2d.ScanForCensus(cns, g, timeNow, orgHash) // Start monitoring for changes go grid2d.WatchForCensus(cns, ch, timeNow, orgHash) return cns }