{-# OPTIONS_GHC -Wno-unused-imports #-}

-- |
-- [Previous Chapter: Introduction to Assets]("Mischief.Assets.Tutorial.Introduction")
--
-- [Next Chapter: Asset Control Flow]("Mischief.Assets.Tutorial.Control")
--
-- [Main Page]("Mischief.Assets")
module Mischief.Assets.Tutorial.Refs
  ( -- * Chapter 2: Asset Refs
    -- $intro

    -- * Asset Querying
    -- $querying

    -- * Kdl Refs
    -- $kdlrefs

    -- * [Next Chapter: Asset Control Flow]("Mischief.Assets.Tutorial.Control")
  )
where

import Mischief.Assets
import Mischief.ECS

-- $intro
-- When you want to point to an asset, you use an @'AssetRef'@. This is a refernece specifying how to get to the asset you're looking for. It
-- could be a simple loaded asset, an asset referenced in another asset, or even a subasset (a part of a larger asset).

-- $querying
-- An @AssetRef a@ can be used with functions such as @'asset'@ and @'qasset'@ to attempt to grab the @a@ the ref is pointing to.
--
-- Assume you have these two .kdl assets:
--
-- assets\/foo.kdl
--
-- @
-- foo {
--   f 10
--   bar \"bars\/bar.kdl\"
-- }
-- @
--
-- assets\/bars\/bar.kdl
--
-- @
-- bar {
--   b 15
-- }
-- @
--
-- And their represenatations in Haskell:
--
-- @
-- data Foo = Foo {
--   f :: 'Int',
--   bar :: 'AssetRef' Bar
-- }
--
-- data Bar = Bar {
--   b :: 'Int'
-- }
-- @
--
-- To query for the Foo asset, you need to provide an @AssetRef Foo@, which can be the path to the asset:
--
-- @
-- foo :: Foo <- 'asset' \"foo.kdl\"
-- @
--
-- You can also query directly for the @f@ field of a Foo:
--
-- @
-- f \<- 'asset' $ do
--   foo :: Foo <- \"foo.kdl"
--   pure foo.f
-- @
--
-- And you can query for the Bar asset referenced by a certain Foo:
--
-- @
-- bar \<- 'asset' $ do
--   foo :: Foo \<- \"foo.kdl\"
--   foo.bar
-- @
--
-- Note that this is equivalent to referencing Bar's file directly, assuming you know the path to it:
--
-- @
-- bar \<- 'asset' $ \"bars\/bar.kdl\"
-- @

-- $kdlrefs
-- For kdl files in particular, there is an utility called a @KdlRef@.
--
-- Let's rewrite the earlier types, this time with KdlRefs instead of AssetRefs:
--
-- @
-- data Foo = Foo {
--   f :: 'Int'
--   bar :: 'KdlRef' Bar
-- }
--
-- data Bar = Bar {
--   b :: 'Int'
-- }
-- @
--
-- A @KdlRef@ can have two possible values: either a reference to another file, or directly the value of the other asset:
--
-- So both of these are valid:
--
-- @
-- -- foo.kdl
-- foo {
--   f 10
--   bar link=\"bar.kdl\"
-- }
--
-- -- bar.kdl
-- bar {
--   b 15
-- }
-- @
--
-- @
-- -- foo.kdl
-- foo {
--   f 10
--   bar {
--     b 15 s
--   }
-- }
-- @
--
-- You can convert a @KdlRef@ to an @AssetRef@ using @toRef@. For instance, this is how we'd get the value of @b@ from a Foo file:
--
-- @
-- b \<- 'asset' $ do
--   foo :: Foo <- \"foo.kdl\"
--   bar <- 'toRef' foo.bar
--   pure bar.b
-- @