Example #1
0
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)
}
Example #2
0
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)
}
Example #3
0
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)
}
Example #4
0
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
}