Skip to content

Commit

Permalink
Ensure long lived service instances
Browse files Browse the repository at this point in the history
  • Loading branch information
davesmith00000 committed Nov 10, 2024
1 parent 6cd317d commit 0496851
Show file tree
Hide file tree
Showing 6 changed files with 33 additions and 56 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,20 +29,12 @@ final class ScenesFrameProcessor[StartUpData, Model, ViewModel](
with StandardFrameProcessorFunctions[StartUpData, Model, ViewModel]:

def run(
startUpData: => StartUpData,
model: => Model,
viewModel: => ViewModel,
gameTime: GameTime,
globalEvents: Batch[GlobalEvent],
inputState: InputState,
dice: Dice,
boundaryLocator: BoundaryLocator,
renderer: => Renderer
context: => Context[StartUpData]
): Outcome[(Model, ViewModel, SceneUpdateFragment)] = {

val context =
Context[StartUpData](gameTime, dice, inputState, boundaryLocator, startUpData, renderer.captureScreen)

val processSceneViewModel: (Model, ViewModel) => Outcome[ViewModel] = (m, vm) =>
globalEvents
.map(sceneManager.eventFilters.viewModelFilter)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,25 +25,17 @@ final class StandardFrameProcessor[StartUpData, Model, ViewModel](
with StandardFrameProcessorFunctions[StartUpData, Model, ViewModel]:

def run(
startUpData: => StartUpData,
model: => Model,
viewModel: => ViewModel,
gameTime: GameTime,
globalEvents: Batch[GlobalEvent],
inputState: InputState,
dice: Dice,
boundaryLocator: BoundaryLocator,
renderer: => Renderer
context: => Context[StartUpData]
): Outcome[(Model, ViewModel, SceneUpdateFragment)] =
val frameContext =
Context[StartUpData](gameTime, dice, inputState, boundaryLocator, startUpData, renderer.captureScreen)

Outcome.join(
for {
m <- processModel(frameContext, model, globalEvents)
vm <- processViewModel(frameContext, m, viewModel, globalEvents)
e <- subSystemsRegister.update(frameContext.forSubSystems, m, globalEvents.toJSArray).eventsAsOutcome
v <- processView(frameContext, m, vm)
m <- processModel(context, model, globalEvents)
vm <- processViewModel(context, m, viewModel, globalEvents)
e <- subSystemsRegister.update(context.forSubSystems, m, globalEvents.toJSArray).eventsAsOutcome
v <- processView(context, m, vm)
} yield Outcome((m, vm, v), e)
)

Expand All @@ -55,7 +47,7 @@ trait StandardFrameProcessorFunctions[StartUpData, Model, ViewModel]:
def viewUpdate: (Context[StartUpData], Model, ViewModel) => Outcome[SceneUpdateFragment]

def processModel(
frameContext: Context[StartUpData],
context: Context[StartUpData],
model: Model,
globalEvents: Batch[GlobalEvent]
): Outcome[Model] =
Expand All @@ -64,12 +56,12 @@ trait StandardFrameProcessorFunctions[StartUpData, Model, ViewModel]:
.collect { case Some(e) => e }
.foldLeft(Outcome(model)) { (acc, e) =>
acc.flatMap { next =>
modelUpdate(frameContext, next)(e)
modelUpdate(context, next)(e)
}
}

def processViewModel(
frameContext: Context[StartUpData],
context: Context[StartUpData],
model: Model,
viewModel: ViewModel,
globalEvents: Batch[GlobalEvent]
Expand All @@ -79,16 +71,16 @@ trait StandardFrameProcessorFunctions[StartUpData, Model, ViewModel]:
.collect { case Some(e) => e }
.foldLeft(Outcome(viewModel)) { (acc, e) =>
acc.flatMap { next =>
viewModelUpdate(frameContext, model, next)(e)
viewModelUpdate(context, model, next)(e)
}
}

def processView(
frameContext: Context[StartUpData],
context: Context[StartUpData],
model: Model,
viewModel: ViewModel
): Outcome[SceneUpdateFragment] =
Outcome.merge(
viewUpdate(frameContext, model, viewModel),
subSystemsRegister.present(frameContext.forSubSystems, model)
viewUpdate(context, model, viewModel),
subSystemsRegister.present(context.forSubSystems, model)
)(_ |+| _)
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package indigo.gameengine

import indigo.platform.renderer.Renderer
import indigo.shared.BoundaryLocator
import indigo.shared.Context
import indigo.shared.Outcome
import indigo.shared.collections.Batch
import indigo.shared.dice.Dice
Expand All @@ -12,13 +13,8 @@ import indigo.shared.time.GameTime

trait FrameProcessor[StartUpData, Model, ViewModel]:
def run(
startUpData: => StartUpData,
model: => Model,
viewModel: => ViewModel,
gameTime: GameTime,
globalEvents: Batch[GlobalEvent],
inputState: InputState,
dice: Dice,
boundaryLocator: BoundaryLocator,
renderer: => Renderer
context: => Context[StartUpData]
): Outcome[(Model, ViewModel, SceneUpdateFragment)]
10 changes: 3 additions & 7 deletions indigo/indigo/src/main/scala/indigo/gameengine/GameEngine.scala
Original file line number Diff line number Diff line change
Expand Up @@ -178,15 +178,11 @@ final class GameEngine[StartUpData, GameModel, ViewModel](

audioPlayer.addAudioAssets(accumulatedAssetCollection.sounds)

val randomSeed =
if (firstRun) 0
else
gameLoopInstance.runningTimeReference // + gameLoopInstance.initialSeed // TODO: Bug here. Black screen of no-render death.
val dice = Dice.fromSeed((if firstRun then 0 else gameLoopInstance.runningTimeReference).toLong)

if (firstRun)
platform = new Platform(parentElement, gameConfig, globalEventStream, dynamicText)
if firstRun then platform = new Platform(parentElement, gameConfig, globalEventStream, dynamicText)

initialise(accumulatedAssetCollection)(Dice.fromSeed(randomSeed.toLong)) match {
initialise(accumulatedAssetCollection)(dice) match {
case oe @ Outcome.Error(error, _) =>
IndigoLogger.error(
if (firstRun) "Error during first initialisation - Halting."
Expand Down
22 changes: 14 additions & 8 deletions indigo/indigo/src/main/scala/indigo/gameengine/GameLoop.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package indigo.gameengine
import indigo.platform.assets.AssetCollection
import indigo.platform.renderer.Renderer
import indigo.shared.BoundaryLocator
import indigo.shared.Context
import indigo.shared.IndigoLogger
import indigo.shared.Outcome
import indigo.shared.collections.Batch
Expand Down Expand Up @@ -37,8 +38,6 @@ final class GameLoop[StartUpData, GameModel, ViewModel](
renderer: => Renderer
):

val initialSeed = new Date().valueOf()

@SuppressWarnings(Array("scalafix:DisableSyntax.var"))
private var _gameModelState: GameModel = initialModel
@SuppressWarnings(Array("scalafix:DisableSyntax.var"))
Expand All @@ -57,6 +56,11 @@ final class GameLoop[StartUpData, GameModel, ViewModel](

private val frameDeltaRecord: scala.scalajs.js.Array[Double] = scala.scalajs.js.Array(0.0d, 0.0d, 0.0d, 0.0d, 0.0d)

private val _randomInstance: scala.util.Random = new scala.util.Random()

private lazy val _services: Context.Services =
Context.Services(boundaryLocator, _randomInstance, renderer.captureScreen)

def gameModelState: GameModel = _gameModelState
def viewModelState: ViewModel = _viewModelState
def runningTimeReference: Double = _runningTimeReference
Expand Down Expand Up @@ -125,18 +129,20 @@ final class GameLoop[StartUpData, GameModel, ViewModel](
gameEngine.gamepadInputCapture.giveGamepadState
)

val context =
new Context[StartUpData](
gameEngine.startUpData,
Context.Frame(Dice.fromSeconds(gameTime.running), gameTime, _inputState),
_services
)

// Run the frame processor
val processedFrame: Outcome[(GameModel, ViewModel, SceneUpdateFragment)] =
frameProcessor.run(
gameEngine.startUpData,
_gameModelState,
_viewModelState,
gameTime,
events,
_inputState,
Dice.fromSeconds(gameTime.running + initialSeed),
boundaryLocator,
renderer
context
)

// Persist frame state
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,10 @@ class StandardFrameProcessorTests extends munit.FunSuite {
test("standard frame processor") {

val outcome = standardFrameProcessor.run(
(),
model,
viewModel,
GameTime.zero,
Batch(EventsOnlyEvent.Increment),
InputState.default,
Dice.loaded(0),
boundaryLocator,
Renderer.blackHole
Context.initial
)

val outModel = outcome.unsafeGet._1
Expand Down

0 comments on commit 0496851

Please sign in to comment.