Skip to content

Commit

Permalink
Replaced Add/RemovingEventAddress with one for Screen, Group, and Ent…
Browse files Browse the repository at this point in the history
…ity. *BREAKING CHANGE*

Made unit testing slightly more succinct with World.initAndMakeEmpty function.


Former-commit-id: 52b233b
  • Loading branch information
bryanedds committed Jan 4, 2015
1 parent b2b25c6 commit 187f3fe
Show file tree
Hide file tree
Showing 10 changed files with 59 additions and 58 deletions.
3 changes: 1 addition & 2 deletions Nu/Nu/Nu/DesyncTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@ module DesyncTests =
let [<Fact>] desyncWorks () =

// build everything
World.init ()
let world = World.makeEmpty 0
let world = World.initAndMakeEmpty 0
let desync =
desync {
let! e = next
Expand Down
4 changes: 2 additions & 2 deletions Nu/Nu/Nu/Entity.fs
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ module WorldEntityModule =
/// Remove an entity from the world immediately. Can be dangerous if existing in-flight
/// subscriptions depend on the entity's existence. Use with caution.
static member removeEntityImmediate (address : Entity Address) world =
let world = World.publish4 () (RemovingEventAddress ->>- address) address world
let world = World.publish4 () (EntityRemovingEventAddress ->>- address) address world
match World.getOptEntity address world with
| Some entity ->
let (entity, world) = World.unregisterEntity entity address world
Expand Down Expand Up @@ -402,7 +402,7 @@ module WorldEntityModule =
if not <| World.containsEntity address world then
let world = World.setEntityWithoutEvent entity address world
let (entity, world) = World.registerEntity entity address world
let world = World.publish4 () (AddEventAddress ->>- address) address world
let world = World.publish4 () (EntityAddEventAddress ->>- address) address world
(entity, world)
else failwith <| "Adding an entity that the world already contains at address '" + acstring address + "'."

Expand Down
4 changes: 2 additions & 2 deletions Nu/Nu/Nu/Group.fs
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ module WorldGroupModule =
/// Remove a group from the world immediately. Can be dangerous if existing in-flight
/// subscriptions depend on the group's existence. Use with caution.
static member removeGroupImmediate address world =
let world = World.publish4 () (RemovingEventAddress ->>- address) address world
let world = World.publish4 () (GroupRemovingEventAddress ->>- address) address world
match World.getOptGroup address world with
| Some group ->
let (group, world) = World.unregisterGroup group address world
Expand Down Expand Up @@ -301,7 +301,7 @@ module WorldGroupModule =
let world = World.setGroupWithoutEvent group address world
let world = snd <| World.addEntities entities address world
let (group, world) = World.registerGroup group address world
let world = World.publish4 () (AddEventAddress ->>- address) address world
let world = World.publish4 () (GroupAddEventAddress ->>- address) address world
(group, world)
else failwith <| "Adding a group that the world already contains at address '" + acstring address + "'."

Expand Down
6 changes: 4 additions & 2 deletions Nu/Nu/Nu/Observation.fs
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,8 @@ module Observation =

/// Terminate an observation when the observer is removed from the world.
let lifetime (observation : Observation<'a, 'o>) : Observation<'a, 'o> =
until (RemovingEventAddress ->>- observation.ObserverAddress) observation
let removingEventAddress = stoa<unit> (typeof<'o>.Name + "/" + "Removing") ->>- observation.ObserverAddress
until removingEventAddress observation

/// Subscribe to an observation until the observer is removed from the world,
/// returning both an unsubscription procedure as well as the world as augmented with said
Expand Down Expand Up @@ -428,7 +429,8 @@ module Observation =

/// Make an observation from an observer address and the observer's change events.
let observeSimulantValue (valueGetter : 'a -> 'b) (simulantAddress : 'a Address) (observerAddress : 'o Address) =
let changeEventAddress = Address.changeType<Simulant SimulantChangeData, 'a SimulantChangeData> SimulantChangeEventAddress ->>- simulantAddress
let simulantChangeEventAddress = stoa<'a SimulantChangeData> (typeof<'a>.Name + "/Change")
let changeEventAddress = simulantChangeEventAddress ->>- simulantAddress
observe changeEventAddress observerAddress |>
simulantValue valueGetter

Expand Down
27 changes: 9 additions & 18 deletions Nu/Nu/Nu/ObservationTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,13 @@ module ObservationTests =
let incUserStateAndResolve _ world = (Resolve, World.updateUserState inc world)

let [<Fact>] subscribeWorks () =
World.init ()
let world = World.makeEmpty 0
let world = World.initAndMakeEmpty 0
let world = observe UnitEventAddress GameAddress |> subscribe incUserStateAndCascade <| world
let world = World.publish4 () UnitEventAddress GameAddress world
Assert.Equal (1, World.getUserState world)

let [<Fact>] subscribeTwiceUnsubscribeOnceWorks () =
World.init ()
let world = World.makeEmpty 0
let world = World.initAndMakeEmpty 0
let observation = observe UnitEventAddress GameAddress
let world = subscribe incUserStateAndCascade observation world
let (unsubscribe, world) = subscribeWithUnsub incUserStateAndCascade observation world
Expand All @@ -35,17 +33,15 @@ module ObservationTests =
Assert.Equal (1, World.getUserState world)

let [<Fact>] unsubscribeWorks () =
World.init ()
let world = World.makeEmpty 0
let world = World.initAndMakeEmpty 0
let (unsubscribe, world) = observe UnitEventAddress GameAddress |> subscribeWithUnsub incUserStateAndCascade <| world
let world = unsubscribe world
let world = World.publish4 () UnitEventAddress GameAddress world
Assert.True <| Map.isEmpty world.Callbacks.Subscriptions
Assert.Equal (0, World.getUserState world)

let [<Fact>] filterWorks () =
World.init ()
let world = World.makeEmpty 0
let world = World.initAndMakeEmpty 0
let world =
observe UnitEventAddress GameAddress |>
filter (fun _ world -> World.getUserState world = 0) |>
Expand All @@ -56,8 +52,7 @@ module ObservationTests =
Assert.Equal (1, World.getUserState world)

let [<Fact>] mapWorks () =
World.init ()
let world = World.makeEmpty 0
let world = World.initAndMakeEmpty 0
let world =
observe IntEventAddress GameAddress |>
map (fun event _ -> event.Data * 2) |>
Expand All @@ -67,8 +62,7 @@ module ObservationTests =
Assert.Equal (2, World.getUserState world)

let [<Fact>] scanWorks () =
World.init ()
let world = World.makeEmpty 0
let world = World.initAndMakeEmpty 0
let world =
observe IntEventAddress GameAddress |>
scan (fun acc event _ -> acc + event.Data) 0 |>
Expand All @@ -79,8 +73,7 @@ module ObservationTests =
Assert.Equal (3, World.getUserState world)

let [<Fact>] scanDoesntLeaveGarbage () =
World.init ()
let world = World.makeEmpty 0
let world = World.initAndMakeEmpty 0
let (unsubscribe, world) =
observe IntEventAddress GameAddress |>
scan2 (fun a _ _ -> a) |>
Expand All @@ -91,8 +84,7 @@ module ObservationTests =
Assert.True <| Map.isEmpty world.Callbacks.CallbackStates

let [<Fact>] discreteFrpWorks () =
World.init ()
let world = World.makeEmpty 0
let world = World.initAndMakeEmpty 0
let jim = World.makeEntity typeof<EntityDispatcher>.Name (Some JimName) world
let bob = World.makeEntity typeof<EntityDispatcher>.Name (Some BobName) world
let group = World.makeGroup typeof<GroupDispatcher>.Name (Some DefaultGroupName) world
Expand All @@ -104,8 +96,7 @@ module ObservationTests =
Assert.True <| World.getEntityBy (not << Entity.getVisible) JimAddress world

let [<Fact>] discreteFrpCyclicWorks () =
World.init ()
let world = World.makeEmpty 0
let world = World.initAndMakeEmpty 0
let jim = World.makeEntity typeof<EntityDispatcher>.Name (Some JimName) world
let bob = World.makeEntity typeof<EntityDispatcher>.Name (Some BobName) world
let group = World.makeGroup typeof<GroupDispatcher>.Name (Some DefaultGroupName) world
Expand Down
4 changes: 2 additions & 2 deletions Nu/Nu/Nu/Screen.fs
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ module WorldScreenModule =
/// Remove a screen from the world immediately. Can be dangerous if existing in-flight
/// subscriptions depend on the screen's existence. Use with caution.
static member removeScreenImmediate address world =
let world = World.publish4 () (RemovingEventAddress ->>- address) address world
let world = World.publish4 () (ScreenRemovingEventAddress ->>- address) address world
match World.getOptScreen address world with
| Some screen ->
let (screen, world) = World.unregisterScreen screen address world
Expand All @@ -274,7 +274,7 @@ module WorldScreenModule =
let world = World.setScreenWithoutEvent screen address world
let world = snd <| World.addGroups groupHierarchies address world
let (screen, world) = World.registerScreen screen address world
let world = World.publish4 () (AddEventAddress ->>- address) address world
let world = World.publish4 () (ScreenAddEventAddress ->>- address) address world
(screen, world)
else failwith <| "Adding a screen that the world already contains at address '" + acstring address + "'."

Expand Down
17 changes: 14 additions & 3 deletions Nu/Nu/Nu/World.fs
Original file line number Diff line number Diff line change
Expand Up @@ -528,7 +528,7 @@ module WorldModule =
let tasksNotRun = List.rev tasksNotRun
World.restoreTasks tasksNotRun world

/// Process an input event from SDL and ultimately publish any related Nu engine events.
/// Process an input event from SDL and ultimately publish any related game events.
static member processInput (event : SDL.SDL_Event) world =
let world =
match event.``type`` with
Expand Down Expand Up @@ -575,7 +575,7 @@ module WorldModule =
(world.State.Liveness, world)

/// Update the Nu game engine once per frame, updating its subsystems and publishing the
/// global tick event.
/// game tick event.
static member processUpdate handleUpdate world =
let world = handleUpdate world
match world.State.Liveness with
Expand Down Expand Up @@ -844,4 +844,15 @@ module WorldModule =
Math.initTypeConverters ()

// assign this crazy function
World.getOptSimulantForPublishing <- World.getOptSimulantForPublishingDefinition
World.getOptSimulantForPublishing <- World.getOptSimulantForPublishingDefinition

/// Initialize the Nu game engine, and make an empty world. Useful for unit-testing.
static member initAndMakeEmpty (userState : 'u) =
World.init ()
World.makeEmpty userState

/// Initialize the Nu game engine and try to make the world, returning either a Right
//// World on success, or a Left string (with an error message) on failure.
static member initAndTryMake farseerCautionMode useLoadedGameDispatcher interactivity userState nuPlugin sdlDeps =
World.init ()
World.tryMake farseerCautionMode useLoadedGameDispatcher interactivity userState nuPlugin sdlDeps
26 changes: 16 additions & 10 deletions Nu/Nu/Nu/WorldConstants.fs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ module WorldConstants =
let DefaultEntityAddress = gatoea DefaultGroupAddress DefaultEntityName
let AnyEventAddress = ntoa<obj> "*"
let TickEventAddress = ntoa<unit> "Tick"
let AddEventAddress = ntoa<unit> "Add"
let RemovingEventAddress = ntoa<unit> "Removing"
let SelectEventAddress = ntoa<unit> "Select"
let DeselectEventAddress = ntoa<unit> "Deselect"
let DownEventAddress = ntoa<unit> "Down"
Expand Down Expand Up @@ -57,12 +55,20 @@ module WorldConstants =
let OutgoingEventAddress = ntoa<unit> "Outgoing"
let OutgoingStartEventAddress = OutgoingEventAddress -|- ntoa "Start"
let OutgoingFinishEventAddress = OutgoingEventAddress -|- ntoa "Finish"
let WorldStateEventAddress = ntoa<WorldStateChangeData> "WorldState"
let WorldStateChangeEventAddress = WorldStateEventAddress -|- ntoa "Change"
let SimulantEventAddress = ntoa<Simulant SimulantChangeData> "Simulant"
let SimulantChangeEventAddress = SimulantEventAddress -|- ntoa "Change"
let GameChangeEventAddress = Address.changeType<Simulant SimulantChangeData, Game SimulantChangeData> SimulantChangeEventAddress
let ScreenChangeEventAddress = Address.changeType<Simulant SimulantChangeData, Screen SimulantChangeData> SimulantChangeEventAddress
let GroupChangeEventAddress = Address.changeType<Simulant SimulantChangeData, Group SimulantChangeData> SimulantChangeEventAddress
let EntityChangeEventAddress = Address.changeType<Simulant SimulantChangeData, Entity SimulantChangeData> SimulantChangeEventAddress
let WorldStateEventAddress = ntoa<obj> "WorldState"
let WorldStateChangeEventAddress = WorldStateEventAddress -<- ntoa<WorldStateChangeData> "Change"
let GameEventAddress = ntoa<obj> "Game"
let GameChangeEventAddress = GameEventAddress -<- ntoa<Game SimulantChangeData> "Change"
let ScreenEventAddress = ntoa<obj> "Screen"
let ScreenAddEventAddress = ScreenEventAddress -<- ntoa<unit> "Add"
let ScreenRemovingEventAddress = ScreenEventAddress -<- ntoa<unit> "Removing"
let ScreenChangeEventAddress = ScreenEventAddress -<- ntoa<Screen SimulantChangeData> "Change"
let GroupEventAddress = ntoa<obj> "Group"
let GroupAddEventAddress = GroupEventAddress -<- ntoa<unit> "Add"
let GroupRemovingEventAddress = GroupEventAddress -<- ntoa<unit> "Removing"
let GroupChangeEventAddress = GroupEventAddress -<- ntoa<Group SimulantChangeData> "Change"
let EntityEventAddress = ntoa<obj> "Entity"
let EntityAddEventAddress = EntityEventAddress -<- ntoa<unit> "Add"
let EntityRemovingEventAddress = EntityEventAddress -<- ntoa<unit> "Removing"
let EntityChangeEventAddress = EntityEventAddress -<- ntoa<Entity SimulantChangeData> "Change"
let DefaultDissolveImage = { PackageName = DefaultPackageName; AssetName = "Image8" }
2 changes: 1 addition & 1 deletion Nu/Nu/Nu/WorldPrimitives.fs
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@ module World =
let world = unsubscribe removalKey world
let world = unsubscribe monitorKey world
(Cascade, world)
let removingEventAddress = RemovingEventAddress ->- atooa subscriberAddress
let removingEventAddress = stoa<unit> (typeof<'s>.Name + "/" + "Removing") ->>- subscriberAddress
subscribe<unit, 's> removalKey subscription' removingEventAddress subscriberAddress world
else failwith "Cannot monitor events with an anonymous subscriber."

Expand Down
24 changes: 8 additions & 16 deletions Nu/Nu/Nu/WorldTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@ module WorldTests =
let incUserStateAndResolve (_ : Event<unit, Game>) world = (Resolve, World.updateUserState inc world)

let [<Fact>] emptyWorldDoesntExplode () =
World.init ()
let world = World.makeEmpty ()
let world = World.initAndMakeEmpty ()
match World.processInput (SDL.SDL_Event ()) world with
| (Running, world) ->
match World.processUpdate id world with
Expand All @@ -29,48 +28,42 @@ module WorldTests =
| (Exiting, _) -> failwith "Test should not reach here."

let [<Fact>] subscribeWorks () =
World.init ()
let world = World.makeEmpty 0
let world = World.initAndMakeEmpty 0
let world = World.subscribe4 incUserStateAndCascade UnitEventAddress GameAddress world
let world = World.publish4 () UnitEventAddress GameAddress world
Assert.Equal (1, World.getUserState world)

let [<Fact>] subscribeAndPublishTwiceWorks () =
World.init ()
let world = World.makeEmpty 0
let world = World.initAndMakeEmpty 0
let world = World.subscribe4 incUserStateAndCascade UnitEventAddress GameAddress world
let world = World.publish4 () UnitEventAddress GameAddress world
let world = World.publish4 () UnitEventAddress GameAddress world
Assert.Equal (2, World.getUserState world)

let [<Fact>] subscribeTwiceAndPublishWorks () =
World.init ()
let world = World.makeEmpty 0
let world = World.initAndMakeEmpty 0
let world = World.subscribe4 incUserStateAndCascade UnitEventAddress GameAddress world
let world = World.subscribe4 incUserStateAndCascade UnitEventAddress GameAddress world
let world = World.publish4 () UnitEventAddress GameAddress world
Assert.Equal (2, World.getUserState world)

let [<Fact>] subscribeWithResolutionWorks () =
World.init ()
let world = World.makeEmpty 0
let world = World.initAndMakeEmpty 0
let world = World.subscribe4 incUserStateAndCascade UnitEventAddress GameAddress world
let world = World.subscribe4 incUserStateAndResolve UnitEventAddress GameAddress world
let world = World.publish4 () UnitEventAddress GameAddress world
Assert.Equal (1, World.getUserState world)

let [<Fact>] unsubscribeWorks () =
World.init ()
let world = World.initAndMakeEmpty 0
let key = World.makeSubscriptionKey ()
let world = World.makeEmpty 0
let world = World.subscribe key incUserStateAndResolve UnitEventAddress GameAddress world
let world = World.unsubscribe key world
let world = World.publish4 () UnitEventAddress GameAddress world
Assert.Equal (0, World.getUserState world)

let [<Fact>] entitySubscribeWorks () =
World.init ()
let world = World.makeEmpty 0
let world = World.initAndMakeEmpty 0
let entity = World.makeEntity typeof<EntityDispatcher>.Name (Some DefaultEntityName) world
let group = World.makeGroup typeof<GroupDispatcher>.Name (Some DefaultGroupName) world
let screen = World.makeScreen typeof<ScreenDispatcher>.Name (Some DefaultScreenName) world
Expand All @@ -84,8 +77,7 @@ module WorldTests =

let [<Fact>] gameSerializationWorks () =
// TODO: make stronger assertions in here!!!
World.init ()
let world = World.makeEmpty 0
let world = World.initAndMakeEmpty 0
let entity = World.makeEntity typeof<EntityDispatcher>.Name (Some DefaultEntityName) world
let group = World.makeGroup typeof<GroupDispatcher>.Name (Some DefaultGroupName) world
let screen = World.makeScreen typeof<ScreenDispatcher>.Name (Some DefaultScreenName) world
Expand Down

0 comments on commit 187f3fe

Please sign in to comment.