Added ecs
This commit is contained in:
parent
62cee9bd63
commit
8819e10d9e
10
ecs/.gitignore
vendored
Normal file
10
ecs/.gitignore
vendored
Normal file
|
@ -0,0 +1,10 @@
|
|||
/bower_components/
|
||||
/node_modules/
|
||||
/.pulp-cache/
|
||||
/output/
|
||||
/generated-docs/
|
||||
/.psc-package/
|
||||
/.psc*
|
||||
/.purs*
|
||||
/.psa*
|
||||
/.spago
|
8
ecs/package.json
Normal file
8
ecs/package.json
Normal file
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"dependencies": {
|
||||
"@thi.ng/ecs": "^0.7.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"typescript": "^4.5.2"
|
||||
}
|
||||
}
|
104
ecs/packages.dhall
Normal file
104
ecs/packages.dhall
Normal file
|
@ -0,0 +1,104 @@
|
|||
{-
|
||||
Welcome to your new Dhall package-set!
|
||||
|
||||
Below are instructions for how to edit this file for most use
|
||||
cases, so that you don't need to know Dhall to use it.
|
||||
|
||||
## Use Cases
|
||||
|
||||
Most will want to do one or both of these options:
|
||||
1. Override/Patch a package's dependency
|
||||
2. Add a package not already in the default package set
|
||||
|
||||
This file will continue to work whether you use one or both options.
|
||||
Instructions for each option are explained below.
|
||||
|
||||
### Overriding/Patching a package
|
||||
|
||||
Purpose:
|
||||
- Change a package's dependency to a newer/older release than the
|
||||
default package set's release
|
||||
- Use your own modified version of some dependency that may
|
||||
include new API, changed API, removed API by
|
||||
using your custom git repo of the library rather than
|
||||
the package set's repo
|
||||
|
||||
Syntax:
|
||||
where `entityName` is one of the following:
|
||||
- dependencies
|
||||
- repo
|
||||
- version
|
||||
-------------------------------
|
||||
let upstream = --
|
||||
in upstream
|
||||
with packageName.entityName = "new value"
|
||||
-------------------------------
|
||||
|
||||
Example:
|
||||
-------------------------------
|
||||
let upstream = --
|
||||
in upstream
|
||||
with halogen.version = "master"
|
||||
with halogen.repo = "https://example.com/path/to/git/repo.git"
|
||||
|
||||
with halogen-vdom.version = "v4.0.0"
|
||||
with halogen-vdom.dependencies = [ "extra-dependency" ] # halogen-vdom.dependencies
|
||||
-------------------------------
|
||||
|
||||
### Additions
|
||||
|
||||
Purpose:
|
||||
- Add packages that aren't already included in the default package set
|
||||
|
||||
Syntax:
|
||||
where `<version>` is:
|
||||
- a tag (i.e. "v4.0.0")
|
||||
- a branch (i.e. "master")
|
||||
- commit hash (i.e. "701f3e44aafb1a6459281714858fadf2c4c2a977")
|
||||
-------------------------------
|
||||
let upstream = --
|
||||
in upstream
|
||||
with new-package-name =
|
||||
{ dependencies =
|
||||
[ "dependency1"
|
||||
, "dependency2"
|
||||
]
|
||||
, repo =
|
||||
"https://example.com/path/to/git/repo.git"
|
||||
, version =
|
||||
"<version>"
|
||||
}
|
||||
-------------------------------
|
||||
|
||||
Example:
|
||||
-------------------------------
|
||||
let upstream = --
|
||||
in upstream
|
||||
with benchotron =
|
||||
{ dependencies =
|
||||
[ "arrays"
|
||||
, "exists"
|
||||
, "profunctor"
|
||||
, "strings"
|
||||
, "quickcheck"
|
||||
, "lcg"
|
||||
, "transformers"
|
||||
, "foldable-traversable"
|
||||
, "exceptions"
|
||||
, "node-fs"
|
||||
, "node-buffer"
|
||||
, "node-readline"
|
||||
, "datetime"
|
||||
, "now"
|
||||
]
|
||||
, repo =
|
||||
"https://github.com/hdgarrood/purescript-benchotron.git"
|
||||
, version =
|
||||
"v7.0.0"
|
||||
}
|
||||
-------------------------------
|
||||
-}
|
||||
let upstream =
|
||||
https://github.com/purescript/package-sets/releases/download/psc-0.14.5-20211116/packages.dhall sha256:7ba810597a275e43c83411d2ab0d4b3c54d0b551436f4b1632e9ff3eb62e327a
|
||||
|
||||
in upstream
|
185
ecs/pnpm-lock.yaml
Normal file
185
ecs/pnpm-lock.yaml
Normal file
|
@ -0,0 +1,185 @@
|
|||
lockfileVersion: 5.3
|
||||
|
||||
specifiers:
|
||||
'@thi.ng/ecs': ^0.7.2
|
||||
typescript: ^4.5.2
|
||||
|
||||
dependencies:
|
||||
'@thi.ng/ecs': 0.7.2
|
||||
|
||||
devDependencies:
|
||||
typescript: 4.5.2
|
||||
|
||||
packages:
|
||||
|
||||
/@thi.ng/api/8.3.2:
|
||||
resolution: {integrity: sha512-sZBbrBtSzXQlCcyxkFwOysvvU9bqcsEQJCqSpxtSmju16c1RjDGLQ/hdv755QRBkNywKykypNBwutUtpaejUfA==}
|
||||
engines: {node: '>=12.7'}
|
||||
dev: false
|
||||
|
||||
/@thi.ng/arrays/2.1.2:
|
||||
resolution: {integrity: sha512-QS0uJFln7xeCyJcDtqjXdov1ta7PMSYjrb17AjjUvSfvPUkLArCJMVTJBl4k9QrFirp8N3Blc1e8xZJgeK9lrg==}
|
||||
engines: {node: '>=12.7'}
|
||||
dependencies:
|
||||
'@thi.ng/api': 8.3.2
|
||||
'@thi.ng/checks': 3.1.2
|
||||
'@thi.ng/compare': 2.1.2
|
||||
'@thi.ng/equiv': 2.1.2
|
||||
'@thi.ng/errors': 2.1.2
|
||||
'@thi.ng/random': 3.2.2
|
||||
dev: false
|
||||
|
||||
/@thi.ng/associative/6.1.2:
|
||||
resolution: {integrity: sha512-Bf1gncNPmAxe6j4cRMhi0nj+2qLUVQznA2VA5U+pqMoI42mOf8zvC28U0GpUzJ+9h53Sv6+P11oDHEQs6qsleA==}
|
||||
engines: {node: '>=12.7'}
|
||||
dependencies:
|
||||
'@thi.ng/api': 8.3.2
|
||||
'@thi.ng/arrays': 2.1.2
|
||||
'@thi.ng/binary': 3.1.2
|
||||
'@thi.ng/checks': 3.1.2
|
||||
'@thi.ng/compare': 2.1.2
|
||||
'@thi.ng/dcons': 3.1.2
|
||||
'@thi.ng/equiv': 2.1.2
|
||||
'@thi.ng/errors': 2.1.2
|
||||
'@thi.ng/transducers': 8.1.2
|
||||
tslib: 2.3.1
|
||||
dev: false
|
||||
|
||||
/@thi.ng/binary/3.1.2:
|
||||
resolution: {integrity: sha512-7PajvPvxT8iG0c4xPg9v/x7tiTWESz/VQMIHvX3pT9mO0wqKJoc4jWUFXCnWqHItnBwNsuEvRPI6I8KjqPnXIg==}
|
||||
engines: {node: '>=12.7'}
|
||||
dependencies:
|
||||
'@thi.ng/api': 8.3.2
|
||||
dev: false
|
||||
|
||||
/@thi.ng/checks/3.1.2:
|
||||
resolution: {integrity: sha512-DyypenoE0bh7hpeBDihHaPqxJmUe2AtQI9dcyGwkizjmaanBSHzJlfckkz46CYoDcq51DnJWn23+GLVJ3qFYhA==}
|
||||
engines: {node: '>=12.7'}
|
||||
dependencies:
|
||||
tslib: 2.3.1
|
||||
dev: false
|
||||
|
||||
/@thi.ng/compare/2.1.2:
|
||||
resolution: {integrity: sha512-0BmxdiG9ybDlzA03dCt6fisjhx9eyP81ODD9JNHT+rNuizt6SApzywjvr+J2GT5HG76SzaSQE8WpvGbScwAS8Q==}
|
||||
engines: {node: '>=12.7'}
|
||||
dependencies:
|
||||
'@thi.ng/api': 8.3.2
|
||||
dev: false
|
||||
|
||||
/@thi.ng/compose/2.1.2:
|
||||
resolution: {integrity: sha512-z0d6G2y3vYlR5IJRn0ehTSyk+2bLhQwnQXxr7EBADq7qlARu0Wco0WIkO2y6FmLDF2M4NKvho8F9K1iqt1jXyQ==}
|
||||
engines: {node: '>=12.7'}
|
||||
dependencies:
|
||||
'@thi.ng/api': 8.3.2
|
||||
'@thi.ng/errors': 2.1.2
|
||||
dev: false
|
||||
|
||||
/@thi.ng/dcons/3.1.2:
|
||||
resolution: {integrity: sha512-RPxxa0DCbmZ4Y9+ffP6WRv6zbwcH14gthxhDycAnpplryu4vgIjNeOV2XW80S2qAINN2RDkC52jO7iA30HzDIw==}
|
||||
engines: {node: '>=12.7'}
|
||||
dependencies:
|
||||
'@thi.ng/api': 8.3.2
|
||||
'@thi.ng/checks': 3.1.2
|
||||
'@thi.ng/compare': 2.1.2
|
||||
'@thi.ng/equiv': 2.1.2
|
||||
'@thi.ng/errors': 2.1.2
|
||||
'@thi.ng/random': 3.2.2
|
||||
'@thi.ng/transducers': 8.1.2
|
||||
dev: false
|
||||
|
||||
/@thi.ng/ecs/0.7.2:
|
||||
resolution: {integrity: sha512-HeEIif+gJm57sdlnWURUrUi/kKWUfc1P/dGk6CNuo4Sg1fo8XPCWR5y2dSLN+dsUyMlw9LAJWR/rvhDOwK//6w==}
|
||||
engines: {node: '>=12.7'}
|
||||
dependencies:
|
||||
'@thi.ng/api': 8.3.2
|
||||
'@thi.ng/associative': 6.1.2
|
||||
'@thi.ng/binary': 3.1.2
|
||||
'@thi.ng/checks': 3.1.2
|
||||
'@thi.ng/dcons': 3.1.2
|
||||
'@thi.ng/errors': 2.1.2
|
||||
'@thi.ng/idgen': 2.1.2
|
||||
'@thi.ng/logger': 1.1.2
|
||||
'@thi.ng/malloc': 6.1.2
|
||||
'@thi.ng/transducers': 8.1.2
|
||||
tslib: 2.3.1
|
||||
dev: false
|
||||
|
||||
/@thi.ng/equiv/2.1.2:
|
||||
resolution: {integrity: sha512-S0QZmWXIO5d/TQSLsyFLYT3/j9nKRuJMUEJYz8seFnQQ9ydrAjV4o5pIHbXiWnjllHAWYa/iN6LJ8xuV8nXxag==}
|
||||
engines: {node: '>=12.7'}
|
||||
dev: false
|
||||
|
||||
/@thi.ng/errors/2.1.2:
|
||||
resolution: {integrity: sha512-3XdabkDNqrL76HVlt3q01zqMRLnSB8FFjJchiYWT/RVkAI2OBogE+eBy4KhYc0mvssYPfdnP9ikjDrV1CC2rVg==}
|
||||
engines: {node: '>=12.7'}
|
||||
dev: false
|
||||
|
||||
/@thi.ng/hex/2.1.2:
|
||||
resolution: {integrity: sha512-JFUApXIn7HWFYEZMQLtf9rZ1aeXFFI8ggdJrA45PzVC0kl73J8yeRHlXn3kjV7spd7jk7oatdEm4JnvadbT4EQ==}
|
||||
engines: {node: '>=12.7'}
|
||||
dev: false
|
||||
|
||||
/@thi.ng/idgen/2.1.2:
|
||||
resolution: {integrity: sha512-15jngVT0kdlrWeTfeXnLBTN8RZW7nCrs2r8c2dj3OGm8cbQDwnd9LxwlYMhu37flMTG55cFiVbiftTK6TEvGWA==}
|
||||
engines: {node: '>=12.7'}
|
||||
dependencies:
|
||||
'@thi.ng/api': 8.3.2
|
||||
'@thi.ng/errors': 2.1.2
|
||||
tslib: 2.3.1
|
||||
dev: false
|
||||
|
||||
/@thi.ng/logger/1.1.2:
|
||||
resolution: {integrity: sha512-zMUAkz7TJ6maTxerWiimGdoCsKR+v1kCyTkRxT1ii0dtTkvhtjhSPpnFAIMM/S4+7PdKxpiTqAl3oFNTt+EN7A==}
|
||||
engines: {node: '>=12.7'}
|
||||
dev: false
|
||||
|
||||
/@thi.ng/malloc/6.1.2:
|
||||
resolution: {integrity: sha512-PPAJmN17CS+HhmKCwFrgXYNXsSSs5zRZJdE5CsCqvvKHnKg+YsAoHFudkmmpIilLdCzFkyZK6gHBT+63jD/xbw==}
|
||||
engines: {node: '>=12.7'}
|
||||
dependencies:
|
||||
'@thi.ng/api': 8.3.2
|
||||
'@thi.ng/binary': 3.1.2
|
||||
'@thi.ng/checks': 3.1.2
|
||||
'@thi.ng/errors': 2.1.2
|
||||
dev: false
|
||||
|
||||
/@thi.ng/math/5.1.2:
|
||||
resolution: {integrity: sha512-iOzs+cy19sxlOxk6OW5xDx5+rsvbXahqOf9Y323zs14VPS/I7rJl9SMY2F5MDbxZf65m3si6nolzOVW0a52C4Q==}
|
||||
engines: {node: '>=12.7'}
|
||||
dependencies:
|
||||
'@thi.ng/api': 8.3.2
|
||||
dev: false
|
||||
|
||||
/@thi.ng/random/3.2.2:
|
||||
resolution: {integrity: sha512-QJD+F2kXfFyTI//EEVnVHP4XdeBhm9tlxavaAZizfIRKwWWxhrAHdk8BDPnN3nQe74Ana6UZy2NMrb3nb0A/gQ==}
|
||||
engines: {node: '>=12.7'}
|
||||
dependencies:
|
||||
'@thi.ng/api': 8.3.2
|
||||
'@thi.ng/checks': 3.1.2
|
||||
'@thi.ng/errors': 2.1.2
|
||||
'@thi.ng/hex': 2.1.2
|
||||
dev: false
|
||||
|
||||
/@thi.ng/transducers/8.1.2:
|
||||
resolution: {integrity: sha512-nMZNrMA8yJfvFpVtIYF31bBHsGJGadci+I3/VqUBneBfWM2aFbJcOjYAyLq7Xe15RBTx9eGfBikPGTcvz5ILfA==}
|
||||
engines: {node: '>=12.7'}
|
||||
dependencies:
|
||||
'@thi.ng/api': 8.3.2
|
||||
'@thi.ng/arrays': 2.1.2
|
||||
'@thi.ng/checks': 3.1.2
|
||||
'@thi.ng/compare': 2.1.2
|
||||
'@thi.ng/compose': 2.1.2
|
||||
'@thi.ng/errors': 2.1.2
|
||||
'@thi.ng/math': 5.1.2
|
||||
'@thi.ng/random': 3.2.2
|
||||
dev: false
|
||||
|
||||
/tslib/2.3.1:
|
||||
resolution: {integrity: sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==}
|
||||
dev: false
|
||||
|
||||
/typescript/4.5.2:
|
||||
resolution: {integrity: sha512-5BlMof9H1yGt0P8/WF+wPNw6GfctgGjXp5hkblpyT+8rkASSmkUKMXrxR0Xg8ThVCi/JnHQiKXeBaEwCeQwMFw==}
|
||||
engines: {node: '>=4.2.0'}
|
||||
hasBin: true
|
||||
dev: true
|
26
ecs/spago.dhall
Normal file
26
ecs/spago.dhall
Normal file
|
@ -0,0 +1,26 @@
|
|||
{-
|
||||
Welcome to a Spago project!
|
||||
You can edit this file as you like.
|
||||
|
||||
Need help? See the following resources:
|
||||
- Spago documentation: https://github.com/purescript/spago
|
||||
- Dhall language tour: https://docs.dhall-lang.org/tutorials/Language-Tour.html
|
||||
|
||||
When creating a new Spago project, you can use
|
||||
`spago init --no-comments` or `spago init -C`
|
||||
to generate this file without the comments in this block.
|
||||
-}
|
||||
{ name = "my-project"
|
||||
, dependencies =
|
||||
[ "arraybuffer-types"
|
||||
, "console"
|
||||
, "effect"
|
||||
, "heterogeneous"
|
||||
, "lazy"
|
||||
, "prelude"
|
||||
, "psci-support"
|
||||
, "undefined-is-not-a-problem"
|
||||
]
|
||||
, packages = ./packages.dhall
|
||||
, sources = [ "src/**/*.purs", "test/**/*.purs" ]
|
||||
}
|
10
ecs/src/Main.purs
Normal file
10
ecs/src/Main.purs
Normal file
|
@ -0,0 +1,10 @@
|
|||
module Main where
|
||||
|
||||
import Prelude
|
||||
|
||||
import Effect (Effect)
|
||||
import Effect.Console (log)
|
||||
|
||||
main :: Effect Unit
|
||||
main = do
|
||||
log "🍝"
|
43
ecs/src/Types.js
Normal file
43
ecs/src/Types.js
Normal file
|
@ -0,0 +1,43 @@
|
|||
// @ts-check
|
||||
const ecs = require("@thi.ng/ecs");
|
||||
|
||||
exports.makeEcs =
|
||||
({ size, components }) =>
|
||||
() => {
|
||||
const thisEcs = new ecs.ECS({
|
||||
capacity: size,
|
||||
});
|
||||
|
||||
for (const key in components) {
|
||||
const component = { id: key };
|
||||
Object.assign(component, components[key]);
|
||||
thisEcs.defComponent(component);
|
||||
}
|
||||
|
||||
return ecs;
|
||||
};
|
||||
|
||||
exports.unsafeCreateEntity = (components, /** @type {ecs.ECS} */ ecs) => {
|
||||
return ecs.defEntity(components);
|
||||
};
|
||||
|
||||
exports.deleteEntity =
|
||||
(/** @type {number} */ id) => (/** @type {ecs.ECS} */ ecs) => () => {
|
||||
return ecs.deleteID(id);
|
||||
};
|
||||
|
||||
exports.unsafeCreateGroup = (
|
||||
components,
|
||||
owned,
|
||||
opts,
|
||||
/** @type {ecs.ECS} */ ecs
|
||||
) => {
|
||||
return ecs.defGroup(components, owned, opts);
|
||||
};
|
||||
|
||||
exports.unsafeGetComponentManager = (
|
||||
/** @type {string} */ name,
|
||||
/** @type {ecs.ECS} */ ecs
|
||||
) => {
|
||||
return ecs.components.get(name);
|
||||
};
|
227
ecs/src/Types.purs
Normal file
227
ecs/src/Types.purs
Normal file
|
@ -0,0 +1,227 @@
|
|||
module Thing.Ecs.Types
|
||||
( Cache
|
||||
, ComponentManager
|
||||
, ComponentSet
|
||||
, ComponentSpec
|
||||
, Ecs
|
||||
, EcsSpec
|
||||
, EntityId
|
||||
, Group
|
||||
, GroupSpec
|
||||
, MakeComponentSet
|
||||
, MemMappedComponent
|
||||
, MemPool
|
||||
, OpaqueComponentManager
|
||||
, SelectGroupComponents
|
||||
, createEntity
|
||||
, createGroup
|
||||
, deleteEntity
|
||||
, makeComponentSet
|
||||
, makeEcs
|
||||
, unsafeCreateEntity
|
||||
, unsafeCreateGroup
|
||||
) where
|
||||
|
||||
import Prelude
|
||||
|
||||
import Data.ArrayBuffer.Types (ArrayBuffer)
|
||||
import Data.List (List)
|
||||
import Data.List as List
|
||||
import Data.Symbol (class IsSymbol, reflectSymbol)
|
||||
import Data.Undefined.NoProblem (Opt)
|
||||
import Effect (Effect)
|
||||
import Effect.Uncurried (EffectFn2, EffectFn4, runEffectFn2, runEffectFn4)
|
||||
import Heterogeneous.Folding (class FoldingWithIndex, class HFoldlWithIndex, hfoldlWithIndex)
|
||||
import Heterogeneous.Mapping (class HMap, class Mapping)
|
||||
import Prim.Row as Row
|
||||
import Prim.RowList as RL
|
||||
import Type.Data.RowList (RLProxy(..))
|
||||
import Type.Proxy (Proxy)
|
||||
import Unsafe.Coerce (unsafeCoerce)
|
||||
|
||||
-- | The entity component system is the core of the library.
|
||||
-- | This is an opaque type, used by the different helpers provided by this library.
|
||||
data Ecs :: Row Type -> Type
|
||||
data Ecs components
|
||||
|
||||
-- | A group is what keeps track of the intersection of multiple component managers
|
||||
data Group :: Row Type -> Type
|
||||
data Group components
|
||||
|
||||
-- | A component manager is the class which manages the lifetime of a particular component
|
||||
data ComponentManager :: Symbol -> Type -> Type
|
||||
data ComponentManager name component
|
||||
|
||||
data OpaqueComponentManager
|
||||
|
||||
-- | Unique id identifying an entity
|
||||
newtype EntityId :: Type
|
||||
newtype EntityId = EntityId Int
|
||||
|
||||
---------- Configuration options
|
||||
-- | Opaque type which represents instances of classes which implement [ICache](https://docs.thi.ng/umbrella/ecs/interfaces/ICache.html)
|
||||
data Cache
|
||||
|
||||
-- | A memory mapped component should lead to more efficient iteration speed (?)
|
||||
-- | and somewhat easy interop with the gpu
|
||||
type MemMappedComponent =
|
||||
{ buffer :: Opt ArrayBuffer
|
||||
, byteOffset :: Opt Int
|
||||
, size :: Opt Int
|
||||
, stride :: Opt Int
|
||||
, cache :: Opt Cache
|
||||
, type :: String -- TODO: fix this
|
||||
}
|
||||
|
||||
-- | An individual component spec specifies how a manager stores it's components
|
||||
data ComponentSpec :: forall k. k -> Type
|
||||
data ComponentSpec a
|
||||
-- | An object component manager can store any javascript value. Useful when the size of the data is not constant
|
||||
= ObjectComponent
|
||||
|
||||
| MemMappedComponent MemMappedComponent
|
||||
|
||||
-- | A component set is just a set of configurations
|
||||
-- | for the components specified by the given row type.
|
||||
data ComponentSet :: Row Type -> Type
|
||||
data ComponentSet components
|
||||
|
||||
-- | Opaque type which represents classes implementing [IMemPoolArray](https://docs.thi.ng/umbrella/malloc/interfaces/imempoolarray.html)
|
||||
data MemPool
|
||||
|
||||
-- TODO: add custom object pool setting
|
||||
-- | The config required to build an ecs
|
||||
type EcsSpec components =
|
||||
{
|
||||
-- | The maximum amount of entities in the system at one point in time
|
||||
size :: Int
|
||||
|
||||
-- | Optional custom implementation of entity allocation / deallocation
|
||||
, pool :: Opt MemPool
|
||||
|
||||
-- | Configuration for all components in the entity component system
|
||||
, components :: ComponentSet components
|
||||
}
|
||||
|
||||
-- | Options for creating a group
|
||||
type GroupSpec =
|
||||
{ id :: Opt String
|
||||
, cache :: Opt Cache
|
||||
}
|
||||
|
||||
---------- Component set creation
|
||||
-- | Typelevel tag for the operation of creating component specs.
|
||||
-- | Internal to this module. Exporting can lead to unsafe code.
|
||||
data MakeComponentSet
|
||||
|
||||
-- | Instance used to compute the record of component specs at the typelevel
|
||||
instance Mapping MakeComponentSet n (ComponentSpec n) where
|
||||
mapping = unsafeCoerce
|
||||
|
||||
-- | Dummy function to remove typeclass constrains from a set of component specs
|
||||
makeComponentSet
|
||||
:: forall components specs
|
||||
. HMap MakeComponentSet (Record components) (Record specs)
|
||||
=> Record specs
|
||||
-> ComponentSet components
|
||||
makeComponentSet = unsafeCoerce
|
||||
|
||||
---------- Helpers
|
||||
createEntity
|
||||
:: forall components provided remaining
|
||||
. Row.Union provided remaining components
|
||||
=> Record provided
|
||||
-> Ecs components
|
||||
-> Effect EntityId
|
||||
createEntity = runEffectFn2 unsafeCreateEntity
|
||||
|
||||
---------- Gruop creation
|
||||
createGroup
|
||||
:: forall components group remaining owned remaining' grl orl
|
||||
. Row.Union group remaining components
|
||||
=> Row.Union owned remaining' components
|
||||
=> RL.RowToList owned orl
|
||||
=> RL.RowToList group grl
|
||||
=> HFoldlWithIndex SelectGroupComponents
|
||||
(Ecs components -> List OpaqueComponentManager)
|
||||
(RLProxy grl)
|
||||
(Ecs components -> List OpaqueComponentManager)
|
||||
=> HFoldlWithIndex SelectGroupComponents
|
||||
(Ecs components -> List OpaqueComponentManager)
|
||||
(RLProxy orl)
|
||||
(Ecs components -> List OpaqueComponentManager)
|
||||
=> Proxy group
|
||||
-> Proxy owned
|
||||
-> GroupSpec
|
||||
-> Ecs components
|
||||
-> Effect (Group remaining)
|
||||
createGroup _ _ options ecs = runEffectFn4 unsafeCreateGroup
|
||||
( List.toUnfoldable $ hfoldlWithIndex
|
||||
SelectGroupComponents
|
||||
(const List.Nil :: Ecs components -> List OpaqueComponentManager)
|
||||
_selected
|
||||
ecs
|
||||
)
|
||||
|
||||
( List.toUnfoldable $ hfoldlWithIndex
|
||||
SelectGroupComponents
|
||||
(const List.Nil :: Ecs components -> List OpaqueComponentManager)
|
||||
_owned
|
||||
ecs
|
||||
)
|
||||
options
|
||||
ecs
|
||||
where
|
||||
_owned :: RLProxy orl
|
||||
_owned = RLProxy
|
||||
|
||||
_selected :: RLProxy grl
|
||||
_selected = RLProxy
|
||||
|
||||
data SelectGroupComponents = SelectGroupComponents
|
||||
|
||||
instance
|
||||
( IsSymbol key
|
||||
) =>
|
||||
FoldingWithIndex SelectGroupComponents
|
||||
(Proxy key)
|
||||
(Ecs components -> List OpaqueComponentManager)
|
||||
(Proxy ty)
|
||||
(Ecs components -> List OpaqueComponentManager)
|
||||
where
|
||||
foldingWithIndex _ key previous _ ecs = List.Cons
|
||||
(unsafeGetComponentManager name ecs)
|
||||
(previous ecs)
|
||||
where
|
||||
name = reflectSymbol key
|
||||
|
||||
---------- Foreign imports
|
||||
-- | Unsafe version of makeEcs
|
||||
foreign import makeEcs
|
||||
:: forall result components
|
||||
. EcsSpec components
|
||||
-> (Ecs components -> result)
|
||||
-> Effect result
|
||||
|
||||
-- | Foreign, unsafe way of adding an entity to an ecs
|
||||
foreign import unsafeCreateEntity
|
||||
:: forall a b
|
||||
. EffectFn2
|
||||
(Record a)
|
||||
(Ecs b)
|
||||
EntityId
|
||||
|
||||
-- | Unsafe version of createGroup
|
||||
foreign import unsafeCreateGroup
|
||||
:: forall a b
|
||||
. EffectFn4
|
||||
(Array OpaqueComponentManager)
|
||||
(Array OpaqueComponentManager)
|
||||
GroupSpec
|
||||
(Ecs a)
|
||||
(Group b)
|
||||
|
||||
-- | Deletes an entity from the system
|
||||
foreign import deleteEntity :: forall components. EntityId -> Ecs components -> Effect Boolean
|
||||
|
||||
foreign import unsafeGetComponentManager :: forall components. String -> Ecs components -> OpaqueComponentManager
|
40
ecs/src/Utils/Keys.purs
Normal file
40
ecs/src/Utils/Keys.purs
Normal file
|
@ -0,0 +1,40 @@
|
|||
-- | Modified version of the code from [record-extra](https://github.com/justinwoo/purescript-record-extra/blob/v4.0.0/src/Record/Extra.purs#L123-L127)
|
||||
-- | I did not like how that lib used lists, so I modified it to output to an (initially) mutable array
|
||||
module Thing.Ecs.Utils.Keys (keys, class Keys, keysImpl) where
|
||||
|
||||
import Prelude
|
||||
|
||||
import Control.Monad.ST (ST)
|
||||
import Data.Array.ST (STArray)
|
||||
import Data.Array.ST as STArray
|
||||
import Data.Symbol (class IsSymbol, reflectSymbol)
|
||||
import Prim.RowList as RL
|
||||
import Type.Proxy (Proxy(..))
|
||||
|
||||
-- | Typeclass jk
|
||||
class Keys (xs :: RL.RowList Type) where
|
||||
keysImpl :: forall r. Proxy xs -> ST r (STArray r String)
|
||||
|
||||
instance Keys RL.Nil where
|
||||
keysImpl _ = STArray.empty
|
||||
|
||||
instance
|
||||
( IsSymbol name
|
||||
, Keys tail
|
||||
) =>
|
||||
Keys (RL.Cons name ty tail) where
|
||||
keysImpl _ = do
|
||||
rest <- keysImpl (Proxy :: _ tail)
|
||||
_ <- STArray.push first rest
|
||||
pure rest
|
||||
where
|
||||
first = reflectSymbol (Proxy :: _ name)
|
||||
|
||||
-- | Extract a value level array of the keys of a row
|
||||
keys
|
||||
:: forall g row rl
|
||||
. RL.RowToList row rl
|
||||
=> Keys rl
|
||||
=> g row -- this will work for any type with the row as a param!
|
||||
-> Array String
|
||||
keys _ = STArray.run (keysImpl (Proxy :: _ rl))
|
11
ecs/test/Main.purs
Normal file
11
ecs/test/Main.purs
Normal file
|
@ -0,0 +1,11 @@
|
|||
module Test.Main where
|
||||
|
||||
import Prelude
|
||||
|
||||
import Effect (Effect)
|
||||
import Effect.Class.Console (log)
|
||||
|
||||
main :: Effect Unit
|
||||
main = do
|
||||
log "🍝"
|
||||
log "You should add some tests."
|
101
ecs/tsconfig.json
Normal file
101
ecs/tsconfig.json
Normal file
|
@ -0,0 +1,101 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
/* Visit https://aka.ms/tsconfig.json to read more about this file */
|
||||
|
||||
/* Projects */
|
||||
// "incremental": true, /* Enable incremental compilation */
|
||||
// "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
|
||||
// "tsBuildInfoFile": "./", /* Specify the folder for .tsbuildinfo incremental compilation files. */
|
||||
// "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects */
|
||||
// "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
|
||||
// "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
|
||||
|
||||
/* Language and Environment */
|
||||
"target": "es2016" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */,
|
||||
// "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
|
||||
// "jsx": "preserve", /* Specify what JSX code is generated. */
|
||||
// "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */
|
||||
// "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
|
||||
// "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h' */
|
||||
// "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
|
||||
// "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using `jsx: react-jsx*`.` */
|
||||
// "reactNamespace": "", /* Specify the object invoked for `createElement`. This only applies when targeting `react` JSX emit. */
|
||||
// "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
|
||||
// "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
|
||||
|
||||
/* Modules */
|
||||
"module": "commonjs" /* Specify what module code is generated. */,
|
||||
// "rootDir": "./", /* Specify the root folder within your source files. */
|
||||
"moduleResolution": "node" /* Specify how TypeScript looks up a file from a given module specifier. */,
|
||||
// "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
|
||||
// "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
|
||||
// "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
|
||||
// "typeRoots": [], /* Specify multiple folders that act like `./node_modules/@types`. */
|
||||
// "types": [], /* Specify type package names to be included without being referenced in a source file. */
|
||||
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
|
||||
// "resolveJsonModule": true, /* Enable importing .json files */
|
||||
// "noResolve": true, /* Disallow `import`s, `require`s or `<reference>`s from expanding the number of files TypeScript should add to a project. */
|
||||
|
||||
/* JavaScript Support */
|
||||
// "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the `checkJS` option to get errors from these files. */
|
||||
// "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
|
||||
// "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from `node_modules`. Only applicable with `allowJs`. */
|
||||
|
||||
/* Emit */
|
||||
// "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
|
||||
// "declarationMap": true, /* Create sourcemaps for d.ts files. */
|
||||
// "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
|
||||
// "sourceMap": true, /* Create source map files for emitted JavaScript files. */
|
||||
// "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If `declaration` is true, also designates a file that bundles all .d.ts output. */
|
||||
// "outDir": "./", /* Specify an output folder for all emitted files. */
|
||||
// "removeComments": true, /* Disable emitting comments. */
|
||||
// "noEmit": true, /* Disable emitting files from a compilation. */
|
||||
// "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
|
||||
// "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types */
|
||||
// "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
|
||||
// "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */
|
||||
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
|
||||
// "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
|
||||
// "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */
|
||||
// "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
|
||||
// "newLine": "crlf", /* Set the newline character for emitting files. */
|
||||
// "stripInternal": true, /* Disable emitting declarations that have `@internal` in their JSDoc comments. */
|
||||
// "noEmitHelpers": true, /* Disable generating custom helper functions like `__extends` in compiled output. */
|
||||
// "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
|
||||
// "preserveConstEnums": true, /* Disable erasing `const enum` declarations in generated code. */
|
||||
// "declarationDir": "./", /* Specify the output directory for generated declaration files. */
|
||||
// "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */
|
||||
|
||||
/* Interop Constraints */
|
||||
"isolatedModules": true /* Ensure that each file can be safely transpiled without relying on other imports. */,
|
||||
"allowSyntheticDefaultImports": true /* Allow 'import x from y' when a module doesn't have a default export. */,
|
||||
"esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */,
|
||||
// "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
|
||||
"forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */,
|
||||
|
||||
/* Type Checking */
|
||||
"strict": true /* Enable all strict type-checking options. */,
|
||||
// "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied `any` type.. */
|
||||
// "strictNullChecks": true, /* When type checking, take into account `null` and `undefined`. */
|
||||
// "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
|
||||
// "strictBindCallApply": true, /* Check that the arguments for `bind`, `call`, and `apply` methods match the original function. */
|
||||
// "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
|
||||
// "noImplicitThis": true, /* Enable error reporting when `this` is given the type `any`. */
|
||||
// "useUnknownInCatchVariables": true, /* Type catch clause variables as 'unknown' instead of 'any'. */
|
||||
// "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */
|
||||
// "noUnusedLocals": true, /* Enable error reporting when a local variables aren't read. */
|
||||
// "noUnusedParameters": true, /* Raise an error when a function parameter isn't read */
|
||||
// "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
|
||||
// "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
|
||||
// "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
|
||||
// "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */
|
||||
// "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
|
||||
// "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type */
|
||||
// "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
|
||||
// "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */
|
||||
|
||||
/* Completeness */
|
||||
// "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
|
||||
"skipLibCheck": true /* Skip type checking all .d.ts files. */
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue