diff --git a/Nu/Nu/Nu/DesyncTests.fs b/Nu/Nu/Nu/DesyncTests.fs index c9e74893d6..3d8528d94e 100644 --- a/Nu/Nu/Nu/DesyncTests.fs +++ b/Nu/Nu/Nu/DesyncTests.fs @@ -19,8 +19,7 @@ module DesyncTests = let [] desyncWorks () = // build everything - World.init () - let world = World.makeEmpty 0 + let world = World.initAndMakeEmpty 0 let desync = desync { let! e = next diff --git a/Nu/Nu/Nu/Entity.fs b/Nu/Nu/Nu/Entity.fs index 5a1870eb47..f335f03dae 100644 --- a/Nu/Nu/Nu/Entity.fs +++ b/Nu/Nu/Nu/Entity.fs @@ -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 @@ -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 + "'." diff --git a/Nu/Nu/Nu/Group.fs b/Nu/Nu/Nu/Group.fs index a97d319107..8b623be45e 100644 --- a/Nu/Nu/Nu/Group.fs +++ b/Nu/Nu/Nu/Group.fs @@ -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 @@ -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 + "'." diff --git a/Nu/Nu/Nu/Observation.fs b/Nu/Nu/Nu/Observation.fs index 62c2b83721..db564f4547 100644 --- a/Nu/Nu/Nu/Observation.fs +++ b/Nu/Nu/Nu/Observation.fs @@ -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 (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 @@ -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 SimulantChangeEventAddress ->>- simulantAddress + let simulantChangeEventAddress = stoa<'a SimulantChangeData> (typeof<'a>.Name + "/Change") + let changeEventAddress = simulantChangeEventAddress ->>- simulantAddress observe changeEventAddress observerAddress |> simulantValue valueGetter diff --git a/Nu/Nu/Nu/ObservationTests.fs b/Nu/Nu/Nu/ObservationTests.fs index 64c59e65bf..3c6c5f9a1f 100644 --- a/Nu/Nu/Nu/ObservationTests.fs +++ b/Nu/Nu/Nu/ObservationTests.fs @@ -18,15 +18,13 @@ module ObservationTests = let incUserStateAndResolve _ world = (Resolve, World.updateUserState inc world) let [] 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 [] 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 @@ -35,8 +33,7 @@ module ObservationTests = Assert.Equal (1, World.getUserState world) let [] 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 @@ -44,8 +41,7 @@ module ObservationTests = Assert.Equal (0, World.getUserState world) let [] 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) |> @@ -56,8 +52,7 @@ module ObservationTests = Assert.Equal (1, World.getUserState world) let [] mapWorks () = - World.init () - let world = World.makeEmpty 0 + let world = World.initAndMakeEmpty 0 let world = observe IntEventAddress GameAddress |> map (fun event _ -> event.Data * 2) |> @@ -67,8 +62,7 @@ module ObservationTests = Assert.Equal (2, World.getUserState world) let [] 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 |> @@ -79,8 +73,7 @@ module ObservationTests = Assert.Equal (3, World.getUserState world) let [] scanDoesntLeaveGarbage () = - World.init () - let world = World.makeEmpty 0 + let world = World.initAndMakeEmpty 0 let (unsubscribe, world) = observe IntEventAddress GameAddress |> scan2 (fun a _ _ -> a) |> @@ -91,8 +84,7 @@ module ObservationTests = Assert.True <| Map.isEmpty world.Callbacks.CallbackStates let [] discreteFrpWorks () = - World.init () - let world = World.makeEmpty 0 + let world = World.initAndMakeEmpty 0 let jim = World.makeEntity typeof.Name (Some JimName) world let bob = World.makeEntity typeof.Name (Some BobName) world let group = World.makeGroup typeof.Name (Some DefaultGroupName) world @@ -104,8 +96,7 @@ module ObservationTests = Assert.True <| World.getEntityBy (not << Entity.getVisible) JimAddress world let [] discreteFrpCyclicWorks () = - World.init () - let world = World.makeEmpty 0 + let world = World.initAndMakeEmpty 0 let jim = World.makeEntity typeof.Name (Some JimName) world let bob = World.makeEntity typeof.Name (Some BobName) world let group = World.makeGroup typeof.Name (Some DefaultGroupName) world diff --git a/Nu/Nu/Nu/Screen.fs b/Nu/Nu/Nu/Screen.fs index c183e5eda9..044468c6c5 100644 --- a/Nu/Nu/Nu/Screen.fs +++ b/Nu/Nu/Nu/Screen.fs @@ -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 @@ -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 + "'." diff --git a/Nu/Nu/Nu/World.fs b/Nu/Nu/Nu/World.fs index 4cb68c13c7..506c6b2a83 100644 --- a/Nu/Nu/Nu/World.fs +++ b/Nu/Nu/Nu/World.fs @@ -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 @@ -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 @@ -844,4 +844,15 @@ module WorldModule = Math.initTypeConverters () // assign this crazy function - World.getOptSimulantForPublishing <- World.getOptSimulantForPublishingDefinition \ No newline at end of file + 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 \ No newline at end of file diff --git a/Nu/Nu/Nu/WorldConstants.fs b/Nu/Nu/Nu/WorldConstants.fs index c86523fd89..26ec4fdb4b 100644 --- a/Nu/Nu/Nu/WorldConstants.fs +++ b/Nu/Nu/Nu/WorldConstants.fs @@ -12,8 +12,6 @@ module WorldConstants = let DefaultEntityAddress = gatoea DefaultGroupAddress DefaultEntityName let AnyEventAddress = ntoa "*" let TickEventAddress = ntoa "Tick" - let AddEventAddress = ntoa "Add" - let RemovingEventAddress = ntoa "Removing" let SelectEventAddress = ntoa "Select" let DeselectEventAddress = ntoa "Deselect" let DownEventAddress = ntoa "Down" @@ -57,12 +55,20 @@ module WorldConstants = let OutgoingEventAddress = ntoa "Outgoing" let OutgoingStartEventAddress = OutgoingEventAddress -|- ntoa "Start" let OutgoingFinishEventAddress = OutgoingEventAddress -|- ntoa "Finish" - let WorldStateEventAddress = ntoa "WorldState" - let WorldStateChangeEventAddress = WorldStateEventAddress -|- ntoa "Change" - let SimulantEventAddress = ntoa "Simulant" - let SimulantChangeEventAddress = SimulantEventAddress -|- ntoa "Change" - let GameChangeEventAddress = Address.changeType SimulantChangeEventAddress - let ScreenChangeEventAddress = Address.changeType SimulantChangeEventAddress - let GroupChangeEventAddress = Address.changeType SimulantChangeEventAddress - let EntityChangeEventAddress = Address.changeType SimulantChangeEventAddress + let WorldStateEventAddress = ntoa "WorldState" + let WorldStateChangeEventAddress = WorldStateEventAddress -<- ntoa "Change" + let GameEventAddress = ntoa "Game" + let GameChangeEventAddress = GameEventAddress -<- ntoa "Change" + let ScreenEventAddress = ntoa "Screen" + let ScreenAddEventAddress = ScreenEventAddress -<- ntoa "Add" + let ScreenRemovingEventAddress = ScreenEventAddress -<- ntoa "Removing" + let ScreenChangeEventAddress = ScreenEventAddress -<- ntoa "Change" + let GroupEventAddress = ntoa "Group" + let GroupAddEventAddress = GroupEventAddress -<- ntoa "Add" + let GroupRemovingEventAddress = GroupEventAddress -<- ntoa "Removing" + let GroupChangeEventAddress = GroupEventAddress -<- ntoa "Change" + let EntityEventAddress = ntoa "Entity" + let EntityAddEventAddress = EntityEventAddress -<- ntoa "Add" + let EntityRemovingEventAddress = EntityEventAddress -<- ntoa "Removing" + let EntityChangeEventAddress = EntityEventAddress -<- ntoa "Change" let DefaultDissolveImage = { PackageName = DefaultPackageName; AssetName = "Image8" } \ No newline at end of file diff --git a/Nu/Nu/Nu/WorldPrimitives.fs b/Nu/Nu/Nu/WorldPrimitives.fs index 951c5ebaf7..3bb1b56342 100644 --- a/Nu/Nu/Nu/WorldPrimitives.fs +++ b/Nu/Nu/Nu/WorldPrimitives.fs @@ -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 (typeof<'s>.Name + "/" + "Removing") ->>- subscriberAddress subscribe removalKey subscription' removingEventAddress subscriberAddress world else failwith "Cannot monitor events with an anonymous subscriber." diff --git a/Nu/Nu/Nu/WorldTests.fs b/Nu/Nu/Nu/WorldTests.fs index fd8615829d..803cb9d082 100644 --- a/Nu/Nu/Nu/WorldTests.fs +++ b/Nu/Nu/Nu/WorldTests.fs @@ -17,8 +17,7 @@ module WorldTests = let incUserStateAndResolve (_ : Event) world = (Resolve, World.updateUserState inc world) let [] 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 @@ -29,48 +28,42 @@ module WorldTests = | (Exiting, _) -> failwith "Test should not reach here." let [] 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 [] 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 [] 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 [] 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 [] 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 [] entitySubscribeWorks () = - World.init () - let world = World.makeEmpty 0 + let world = World.initAndMakeEmpty 0 let entity = World.makeEntity typeof.Name (Some DefaultEntityName) world let group = World.makeGroup typeof.Name (Some DefaultGroupName) world let screen = World.makeScreen typeof.Name (Some DefaultScreenName) world @@ -84,8 +77,7 @@ module WorldTests = let [] gameSerializationWorks () = // TODO: make stronger assertions in here!!! - World.init () - let world = World.makeEmpty 0 + let world = World.initAndMakeEmpty 0 let entity = World.makeEntity typeof.Name (Some DefaultEntityName) world let group = World.makeGroup typeof.Name (Some DefaultGroupName) world let screen = World.makeScreen typeof.Name (Some DefaultScreenName) world