Example #1
0
func UpdaterSpec(c gospec.Context) {
	c.Specify("Basic Updater functionality.", func() {
		var params core.EngineParams
		params.Id = 1234
		params.Delay = 2
		params.Frame_ms = 5
		params.Max_frames = 25
		var updater core.Updater
		updater.Params = params
		local_bundles := make(chan core.FrameBundle)
		broadcast_bundles := make(chan core.FrameBundle)
		remote_bundles := make(chan core.FrameBundle)
		updater.Local_bundles = local_bundles
		updater.Broadcast_bundles = broadcast_bundles
		updater.Remote_bundles = remote_bundles
		data := core.FrameData{
			Bundle: nil,
			Game:   &TestGame{},
			Info: core.EngineInfo{
				Engines: map[core.EngineId]bool{
					params.Id:     true,
					params.Id + 1: true,
				},
			},
		}
		var start_frame core.StateFrame = 10
		updater.Start(start_frame, data)
		go func() {
			for _ = range broadcast_bundles {
			}
		}()
		defer close(broadcast_bundles)
		cur_frame := start_frame + 1
		c.Specify("Local game Events are applied properly.", func() {
			for cur_frame = start_frame + 1; cur_frame <= start_frame+5; cur_frame++ {
				local_bundles <- core.FrameBundle{
					Frame: cur_frame,
					Bundle: core.EventBundle{
						params.Id: core.AllEvents{
							Game: []core.Event{
								EventA{2},
								EventB{fmt.Sprintf("%d", cur_frame)},
							},
						},
						params.Id + 1: core.AllEvents{
							Game: []core.Event{
								EventA{1},
								EventB{fmt.Sprintf("%d", cur_frame)},
							},
						},
					},
				}
			}
			state, _ := updater.RequestFinalGameState(cur_frame - 1)
			c.Expect(state, Not(Equals), nil)
			tg := state.(*TestGame)
			c.Expect(tg.Thinks, Equals, 5)
			c.Expect(tg.A, Equals, 15)
			c.Expect(tg.B, Equals, fmt.Sprintf("%d", cur_frame-1))
		})

		// Same test as above, but one of the engine's events come through the
		// remote_bundles channel.
		c.Specify("Remote game Events are applied properly.", func() {
			for cur_frame = start_frame + 1; cur_frame <= start_frame+5; cur_frame++ {
				local_bundles <- core.FrameBundle{
					Frame: cur_frame,
					Bundle: core.EventBundle{
						params.Id: core.AllEvents{
							Game: []core.Event{
								EventA{2},
								EventB{fmt.Sprintf("%d", cur_frame)},
							},
						},
					},
				}
				remote_bundles <- core.FrameBundle{
					Frame: cur_frame,
					Bundle: core.EventBundle{
						params.Id + 1: core.AllEvents{
							Game: []core.Event{
								EventA{1},
								EventB{fmt.Sprintf("%d", cur_frame)},
							},
						},
					},
				}
			}
			state, _ := updater.RequestFinalGameState(cur_frame - 1)
			c.Expect(state, Not(Equals), nil)
			tg := state.(*TestGame)
			c.Expect(tg.Thinks, Equals, 5)
			c.Expect(tg.A, Equals, 15)
			c.Expect(tg.B, Equals, fmt.Sprintf("%d", cur_frame-1))
		})

		// Similar test as above but we drop and rejoin one of the engines.
		c.Specify("Engine Events are applied properly.", func() {
			local_bundles <- core.FrameBundle{
				Frame: cur_frame,
				Bundle: core.EventBundle{
					params.Id: core.AllEvents{
						Engine: []core.EngineEvent{
							core.EngineDropped{params.Id + 1},
						},
						Game: []core.Event{
							EventA{1},
						},
					},
					params.Id + 1: core.AllEvents{
						Game: []core.Event{
							EventA{1},
						},
					},
				},
			}

			local_bundles <- core.FrameBundle{
				Frame: cur_frame + 1,
				Bundle: core.EventBundle{
					params.Id: core.AllEvents{
						Engine: []core.EngineEvent{
							core.EngineJoined{params.Id + 1},
						},
						Game: []core.Event{
							EventA{1},
						},
					},
					params.Id + 1: core.AllEvents{ // These events should not get applied
						Game: []core.Event{
							EventA{1},
						},
					},
				},
			}

			local_bundles <- core.FrameBundle{
				Frame: cur_frame + 2,
				Bundle: core.EventBundle{
					params.Id: core.AllEvents{
						Game: []core.Event{
							EventA{1},
						},
					},
					params.Id + 1: core.AllEvents{ // These events should get applied
						Game: []core.Event{
							EventA{1},
						},
					},
				},
			}

			state, _ := updater.RequestFinalGameState(-1)
			c.Expect(state, Not(Equals), nil)
			tg := state.(*TestGame)
			c.Expect(tg.Thinks, Equals, 3)
			c.Expect(tg.A, Equals, 5)
		})
	})
}
Example #2
0
func BundlerSpec(c gospec.Context) {
	c.Specify("Basic Bundler functionality.", func() {
		var params core.EngineParams
		params.Id = 1234
		params.Delay = 2
		params.Frame_ms = 5
		params.Max_frames = 25
		bundles := make(chan core.FrameBundle)
		local_event := make(chan core.Event)
		var bundler core.Bundler
		bundler.Params = params
		bundler.Local_bundles = bundles
		bundler.Local_event = local_event
		bundler.Time_delta = nil
		ticker := &core.FakeTicker{}
		bundler.Ticker = ticker
		bundler.Start()
		c.Expect(1, Equals, 1)
		go func() {
			for i := 0; i < 10; i++ {
				if i%2 == 0 {
					local_event <- &EventA{i}
					local_event <- &EventB{fmt.Sprintf("%d", i)}
				} else {
					local_event <- &EventB{fmt.Sprintf("%d", i)}
					local_event <- &EventA{i}
				}
				// Advance two frames, so we will have two events per every other
				// frame.
				ticker.Inc(10)
			}
			bundler.Shutdown()
		}()
		var frame core.StateFrame = 0
		for bundle := range bundles {
			c.Expect(bundle.Frame, Equals, frame)
			events, ok := bundle.Bundle[params.Id]
			c.Assume(ok, Equals, true)
			c.Expect(len(events.Engine), Equals, 0)
			if ok {
				if frame%2 == 0 {
					c.Expect(len(events.Game), Equals, 2)
				} else {
					c.Expect(len(events.Game), Equals, 0)
				}
			}
			if frame%2 == 0 {
				c.Expect(len(bundle.Bundle), Equals, 1)
				c.Specify("checking bundle values", func() {
					index_a := 0
					if frame%4 != 0 {
						index_a = 1
					}
					ea, aok := events.Game[index_a].(*EventA)
					eb, bok := events.Game[(index_a+1)%2].(*EventB)
					c.Assume(aok, Equals, true)
					c.Assume(bok, Equals, true)
					c.Specify("checking event data", func() {
						c.Expect(ea.Data, Equals, int(frame/2))
						c.Expect(eb.Data, Equals, fmt.Sprintf("%d", frame/2))
					})
				})
			}
			frame++
		}
	})
}