Skip to content

Commit

Permalink
documentation setup
Browse files Browse the repository at this point in the history
  • Loading branch information
louisponet committed Apr 15, 2023
1 parent adcd6de commit e9b3f51
Show file tree
Hide file tree
Showing 13 changed files with 251 additions and 34 deletions.
11 changes: 11 additions & 0 deletions .github/workflows/TagBot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,18 @@ on:
lookback:
default: 3
permissions:
actions: read
checks: read
contents: write
deployments: read
issues: read
discussions: read
packages: read
pages: read
pull-requests: read
repository-projects: read
security-events: read
statuses: read
jobs:
TagBot:
if: github.event_name == 'workflow_dispatch' || github.actor == 'JuliaTagBot'
Expand Down
38 changes: 21 additions & 17 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,20 +48,24 @@ jobs:
- uses: julia-actions/julia-uploadcodecov@latest
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
# docs:
# name: Documentation
# runs-on: ubuntu-latest
# steps:
# - uses: actions/checkout@v1
# - uses: julia-actions/setup-julia@latest
# with:
# version: '1.4'
# - run: julia --project=docs -e '
# using Pkg;
# Pkg.develop(PackageSpec(; path=pwd()));
# Pkg.instantiate();'
# - run: julia --project=docs docs/make.jl
# env:
# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# # Needed due to https://github.com/JuliaDocs/Documenter.jl/issues/1177
# DOCUMENTER_KEY: ${{ secrets.DOCUMENTER_KEY }}
docs:
name: Documentation
runs-on: ubuntu-latest
permissions:
contents: write
statuses: write
steps:
- uses: actions/checkout@v3
- uses: julia-actions/setup-julia@v1
with:
version: '1'
- uses: julia-actions/julia-buildpkg@v1
- uses: julia-actions/julia-docdeploy@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- run: |
julia --project=docs -e '
using Documenter: DocMeta, doctest
using Trading
DocMeta.setdocmeta!(Trading, :DocTestSetup, :(using Trading); recursive=true)
doctest(Trading)'
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@

Manifest\.toml

docs/build/
4 changes: 4 additions & 0 deletions docs/Project.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[deps]
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
Literate = "98b081ad-f1c9-55d3-8b20-4c87d4299306"
Overseer = "1ada24be-c16d-4464-9f61-27c2e0f16645"
91 changes: 91 additions & 0 deletions docs/make.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# Based on documentation of DFControl and DFTK
using LibGit2: LibGit2
using Pkg: Pkg

# To manually generate the docs:
# Run "julia make.jl" to generate the docs

# Set to true to disable some checks and cleanup
DEBUG = false

# Where to get files from and where to build them
SRCPATH = joinpath(@__DIR__, "src")
BUILDPATH = joinpath(@__DIR__, "build")
ROOTPATH = joinpath(@__DIR__, "..")
CONTINUOUS_INTEGRATION = get(ENV, "CI", nothing) == "true"

JLDEPS = [Pkg.PackageSpec(;
url = "https://github.com/louisponet/Overseer.jl.git",
rev = LibGit2.head(ROOTPATH))]

# Setup julia dependencies for docs generation if not yet done
Pkg.activate(@__DIR__)
Pkg.develop(Pkg.PackageSpec(; path = ROOTPATH))
Pkg.instantiate()

# Setup environment for making plots
ENV["GKS_ENCODING"] = "utf8"
ENV["GKSwstype"] = "100"
ENV["PLOTS_TEST"] = "true"

# Import packages for docs generation
using Overseer
using Documenter
using Literate

usings = quote
using Overseer
end

DocMeta.setdocmeta!(Overseer, :DocTestSetup, usings; recursive=true)

EXAMPLES = [String(m[1])
for m in match.(r"\"(examples/[^\"]+.md)\"", readlines(joinpath(SRCPATH, "index.md"))) if !isnothing(m)]

literate_files = NamedTuple[(src = joinpath(ROOTPATH, splitext(file)[1] * ".jl"),
dest = joinpath(SRCPATH, "examples"),
example = true) for file in EXAMPLES]

for (dir, directories, files) in walkdir(SRCPATH)
for file in files
if endswith(file, ".jl")
push!(literate_files, (src = joinpath(dir, file), dest = dir, example = false))
end
end
end

for file in literate_files
# preprocess = file.example ? add_badges : identity
# Literate.markdown(file.src, file.dest; documenter=true, credit=false,
# preprocess=preprocess)
# Literate.notebook(file.src, file.dest; credit=false,
# execute=CONTINUOUS_INTEGRATION || DEBUG)
Literate.markdown(file.src, file.dest; documenter = true, credit = false)
Literate.notebook(file.src, file.dest; credit = false,
execute = CONTINUOUS_INTEGRATION || DEBUG)
end

# Generate the docs in BUILDPATH
makedocs(; modules = [Overseer],
format = Documenter.HTML(; prettyurls = CONTINUOUS_INTEGRATION,
canonical = "https://louisponet.github.io/Overseer.jl/stable/",
assets = ["assets/favicon.ico"]),
sitename = "Overseer.jl", authors = "Louis Ponet",
linkcheck_ignore = [
# Ignore links that point to GitHub's edit pages, as they redirect to the
# login screen and cause a warning:
r"https://github.com/([A-Za-z0-9_.-]+)/([A-Za-z0-9_.-]+)/edit(.*)"],
pages = ["Home" => "index.md",
# "Getting Started" => "installation.md",
"Topics" => ["Ledger" => "ledger.md",
"Components" => "components.md",
"Systems" => "systems.md",
"Entities" => "entities.md",
"Iteration" => "iteration.md"]])

# Deploy docs to gh-pages branch
deploydocs(; repo = "github.com/louisponet/Overseer.jl.git", devbranch = "master")

if !CONTINUOUS_INTEGRATION
println("\nDocs generated, try $(joinpath(BUILDPATH, "index.html"))")
end
9 changes: 9 additions & 0 deletions docs/src/components.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Components
```@meta
CurrentModule = Overseer
```

```@docs
Component
PooledComponent
```
10 changes: 10 additions & 0 deletions docs/src/entities.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Entities

```@meta
CurrentModule = Overseer
```

```@docs
Entity
EntityState
```
1 change: 1 addition & 0 deletions docs/src/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Overseer
11 changes: 11 additions & 0 deletions docs/src/iteration.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Iteration
```@meta
CurrentModule = Overseer
```

```@docs
@entities_in
@safe_entities_in
pools
entity_pool
```
7 changes: 7 additions & 0 deletions docs/src/ledger.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Ledger
```@meta
CurrentModule = Overseer
```
```@docs
Ledger
```
7 changes: 7 additions & 0 deletions docs/src/systems.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Systems
```@meta
CurrentModule = Overseer
```
```@docs
System
```
56 changes: 46 additions & 10 deletions src/iteration.jl
Original file line number Diff line number Diff line change
Expand Up @@ -283,29 +283,36 @@ for (m, it_short, it) in zip((:entities_in, :safe_entities_in), (:indices_iterat
end

"""
@entities_in
@entities_in(comp_expr)
@entities_in(l, comp_expr)
This macro creates an iterator that iterates over all entities that are present
in the components according to the expression passed to it. Each iteration an
[`EntityState`](@ref) is returned that refers to the entity and the associated data
inside the [`Components`](@ref).
`comp_expr` is a boolean expression that is used to decide which entities to return.
# Examples
```jldoctest
```julia
for e in @entities_in(comp1 && (comp2 || comp3) && !comp4)
# do something with e
end
for e in @entities_in(ledger, CompType1 && (CompType2 || CompType3) && !CompType4)
# do something with e
end
```
Assuming that `comp1 = ledger[CompType1]` and similar for the others, these expressions will
loop over the [`Entities`](@ref EntityState) that are in `comp1`, in `comp2` or `comp3`, and not in
`comp4`.
"""
:(@entities_in)

"""
@safe_entities_in
@safe_entities_in(comp_expr)
@safe_entities_in(ledger, comp_expr)
Similar to [`@entities_in`](@ref) but safe to [`pop!`](@ref) entities during iteration.
# Examples
```jldoctest
```
"""
:(@safe_entities_in)

Expand All @@ -324,6 +331,21 @@ end
indices_iterator(g::EntityPoolIterator) = g
indices(g::EntityPoolIterator) = g

"""
entity_pool(c::PooledComponent, pool_id::Int)
entity_pool(c::PooledComponent, e::AbstractEntity)
Returns an iterator that iterates over all the [`Entities`](@ref EntityState) in the pool
with `id == pool_id` or the pool to which `e` belongs.
# Example
```julia
for e in entity_pool(c, 1)
# do something with e belonging to the first pool of c
end
```
"""
function entity_pool(c::PooledComponent, pool_id::Int)
@boundscheck if length(c.data) < pool_id
throw(BoundsError(c, pool_id))
Expand All @@ -339,7 +361,7 @@ entity_pool(c::PooledComponent, e::AbstractEntity) = entity_pool(c, pool(c, e))
state[2] > i.c.pool_size[i.pool_id] && return nothing
n = findnext(isequal(i.pool_id), i.c.pool, state[1])
n === nothing && return n
return Entity(i.c.indices.packed[n]), (n + 1, state[2] + 1)
return EntityState(Entity(i.c.indices.packed[n]), i.c), (n + 1, state[2] + 1)
end

Base.getindex(iterator::EntityPoolIterator, i::Int) = iterate(iterator, (i, 1))[1]
Expand Down Expand Up @@ -378,8 +400,22 @@ struct PoolsIterator{T}
c::PooledComponent{T}
end

pools(c::PooledComponent) = PoolsIterator(c)
"""
pools(c::PooledComponent)
Returns an iterator that loops over the pools in `c`, returning a `Tuple`
with the data and an iterator like the one gotten from [`entity_pool`](@ref).
# Example
```julia
for (data, entities) in pools(c)
for e in entities
# do something with e
end
end
```
"""
pools(c::PooledComponent) = PoolsIterator(c)

function Base.iterate(i::PoolsIterator, p = 1)
p > length(i.c.data) && return nothing
Expand Down
37 changes: 31 additions & 6 deletions src/ledger.jl
Original file line number Diff line number Diff line change
@@ -1,8 +1,33 @@
"""
Ledger
A `Ledger` holds all the [`Entities`](@ref Entity), [`Components`](@ref) and [`Systems`](@ref). It has interfaces to create new [`Entities`](@ref Entity) and access the [`Components`](ref). Calling [`update(ledger)`](@ref Overseer.update) will call
A `Ledger` holds all the [`Entities`](@ref Entity), [Components](@ref) and [Systems](@ref).
It has interfaces to create new [`Entities`](@ref Entity) and access the [Components](ref).
Calling [`update(ledger)`](@ref Overseer.update) will call
all the [`update`](@ref) functions of the systems in the `Ledger`.
# Example
```julia
l = Ledger()
e1 = Entity(l, CompType1(1, 2))
e2 = Entity(l, CompType1(1, 2), CompType2("comptype2"))
```
this has created a new [`Ledger`](@ref) with two [`Entities`](@ref Entity), the first having 1 component of type `CompType1`,
the second has 2 components.
```julia
l[e1]
```
Will return an [`EntityState`](@ref), essentially a bag of [`Components`](@ref AbstractComponent) `e1` belongs to.
```julia
l[CompType1]
```
returns the [`AbstractComponent`](@ref) holding the data of type `CompType1`.
For further info on interactions with a [`Ledger`](@ref), see:
- [`in`](@ref)
- [`delete!`](@ref)
- [`setindex!`](@ref)
"""
mutable struct Ledger <: AbstractLedger
entities ::Vector{Entity}
Expand Down Expand Up @@ -71,9 +96,14 @@ function Base.show(io::IO, ::MIME"text/plain", l::AbstractLedger)
end
println(io, "Total entities: $(length(entities(l)) - length(free_entities(l)))")
end

function Base.in(::Type{R}, m::AbstractLedger) where {R}
return R keys(components(m))
end
function Base.in(e::AbstractEntity, m::AbstractLedger)
es = entities(m)
return length(es) >= Entity(e).id && es[Entity(e).id] != EMPTY_ENTITY
end

function Base.empty!(m::AbstractLedger)
empty!(entities(m))
Expand Down Expand Up @@ -225,11 +255,6 @@ function components(ledger::AbstractLedger, ::Type{T}) where {T}
return comps
end

function Base.in(e::AbstractEntity, m::AbstractLedger)
es = entities(m)
return length(es) >= Entity(e).id && es[Entity(e).id] != EMPTY_ENTITY
end

function entity_assert(m::AbstractLedger, e::AbstractEntity)
@assert e in m "$(Entity(e)) does not exist, either never initiated or removed previously."
end
Expand Down

0 comments on commit e9b3f51

Please sign in to comment.