| Safe Haskell | None |
|---|---|
| Language | GHC2024 |
Mischief.Assets.Tutorial.Control
Synopsis
Chapter 3: Asset Control Flow
Some pointers on controlling the logic control flow when working with assets.
Active vs. Passive Querying
Attempting to query for an asset will, by default, prompt the asset to load. This is called active querying.
For instance, running this every frame:
foo <- asset @Foo "foo.kdl"
Will prompt Foo to start loading if it hasn't yet.
Assuming that it takes it less than a frame to load, this should be returning a Just Foo starting with the second frame.
This mechanism is extremely powerful when used in conjunction with queries, via qasset, since
queries are designed to stop executing when something you're trying to grab isn't available:
query_$ do foo <-qasset@Foo getBqlift$info[i|Reading asset: #{foo}|]
You can choose to use passive querying, through the equivalent functions ending in '. Such as
and asset'. These functions will attempt to grab the asset, but they will not prompt it to load.qasset'
Recursive Loading
By default, each asset is loaded lazily. Meaning the least possible amount of I/O operations will be performed in order to get the data you need.
If asset A contains a reference to asset B, neither nor load of assetA will attempt to load B.
You can alternatively use the dedicated and loadRec which will trigger a recursive loading sequence.assetRec
For all assets you define, you are responsible for specifying the references that will be loaded in such a case. For instance:
data Foo = Foo
{
i :: Int,
ref1 :: AssetRef Bar
ref2 :: KdlRef Baz
}
instance Asset Foo where
rec foo = do
addRec foo.ref1
addRec $ toRef foo.ref2
Events
You can spawn observers that listen to the OnLoad events, which is triggered each time an asset is loaded.
onFoo ::OnLoadFoo ->SystemonFoo event = ...
Since assets are components, you can also listen to , OnAdd, and so on.OnSet
One-Shot Observers
You can use and similar functions to run a system when a specific asset (or group of assets) has been loaded, like so:runWhen
runWhenOne( foo <-qasset@Foo "foo.kdl" bar <-qasset@Bar "bar.kdl"pure(foo, bar) ) (\(foo, bar) -> do ... )
Note however, that each time this function is ran, an instance of your query will be scheduled to run at every sync point until it returns a result. In order to not waste a large amount of resources, this should only be used in one-time logic such as on Startup or in an Observer, rather than in logic that runs at a fixed interval.