Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
doawoo committed Aug 1, 2021
0 parents commit e5977c5
Show file tree
Hide file tree
Showing 14 changed files with 228 additions and 0 deletions.
4 changes: 4 additions & 0 deletions .formatter.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Used by "mix format"
[
inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"]
]
27 changes: 27 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# The directory Mix will write compiled artifacts to.
/_build/

# If you run "mix test --cover", coverage assets end up here.
/cover/

# The directory Mix downloads your dependencies sources to.
/deps/

# Where third-party dependencies like ExDoc output generated docs.
/doc/

# Ignore .fetch files in case you like to edit your project deps locally.
/.fetch

# If the VM crashes, it generates a dump, let's ignore it too.
erl_crash.dump

# Also ignore archive artifacts (built via "mix archive.build").
*.ez

# Ignore package tarball (built via "mix hex.build").
elixir_rpg-*.tar


# Temporary files for e.g. tests
/tmp
21 changes: 21 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# ElixirRpg

**TODO: Add description**

## Installation

If [available in Hex](https://hex.pm/docs/publish), the package can be installed
by adding `elixir_rpg` to your list of dependencies in `mix.exs`:

```elixir
def deps do
[
{:elixir_rpg, "~> 0.1.0"}
]
end
```

Documentation can be generated with [ExDoc](https://github.com/elixir-lang/ex_doc)
and published on [HexDocs](https://hexdocs.pm). Once published, the docs can
be found at [https://hexdocs.pm/elixir_rpg](https://hexdocs.pm/elixir_rpg).

3 changes: 3 additions & 0 deletions lib/DSL/entity.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
defmodule ElixirRPG.DSL.Entity do

end
47 changes: 47 additions & 0 deletions lib/DSL/system.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
defmodule ElixirRPG.DSL.System do
defmacro __using__(_options) do
quote do
import ElixirRPG.DSL.System
end
end

defmacro defsystem(name, do: block) do
quote do
defmodule ElixirRPG.RuntimeSystems.unquote(name) do
Module.register_attribute(__MODULE__, :wants, accumulate: true, persist: true)
Module.register_attribute(__MODULE__, :system_name, persist: true)

unquote(block)

def wants do
@wants
end

def name do
@system_name
end
end
end
end

defmacro name(name) do
quote do
@system_name unquote(name)
end
end

defmacro wants(component_name) do
quote do
@wants unquote(component_name)
end
end

defmacro on_tick(do: block) do
quote do
def __tick() do
unquote(block)
:tock
end
end
end
end
10 changes: 10 additions & 0 deletions lib/elixir_rpg.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
defmodule ElixirRPG do
alias ElixirRPG.World

require Logger

def test_harness do
{:ok, world_pid} = World.start_link("test_world", :the_world)
Logger.info("Started World at PID: #{inspect(world_pid)}")
end
end
3 changes: 3 additions & 0 deletions lib/system/system.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
defmodule ElixirRPG.System do
@callback wants() :: list(atom())
end
13 changes: 13 additions & 0 deletions lib/system/test_system.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
use ElixirRPG.DSL.System

defsystem TestSystem do

name "A Simple Testing System"

wants :player_stats
wants :input

on_tick do
IO.inspect("tick")
end
end
12 changes: 12 additions & 0 deletions lib/world/data.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
defmodule ElixirRPG.World.Data do
use TypedStruct

typedstruct do
field(:name, String.t(), default: "world")
field(:clock, pid(), default: nil)
field(:target_tick_rate, integer(), default: 0)

field(:systems, list(), default: [])
field(:entities, list(), default: [])
end
end
49 changes: 49 additions & 0 deletions lib/world/world.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
defmodule ElixirRPG.World do
use GenServer

alias ElixirRPG.World

@initial_state %World.Data{target_tick_rate: 60}

def start_link(name, proc_name) when is_binary(name) and is_atom(proc_name) do
GenServer.start_link(__MODULE__, [name: name], name: proc_name)
end

@impl GenServer
def init(name: world_name) do
state = @initial_state

clock_ref = World.Clock.start_tick(state.target_tick_rate, self())
{:ok, %World.Data{state | name: world_name, clock: clock_ref}}
end

@impl GenServer
def handle_cast(:pause, current_state) do
:timer.cancel(current_state.clock)
{:noreply, %{current_state | clock: nil}}
end

def handle_cast(:resume, current_state) do
:timer.cancel(current_state.clock)
clock_ref = World.Clock.start_tick(current_state.target_tick_rate, self())
{:ok, %{@initial_state | clock: clock_ref}}
end

def handle_cast({:broadcast, msg}, current_state) do
Enum.each(current_state.children, fn pid -> GenServer.cast(pid, msg) end)
{:noreply, current_state}
end

@impl GenServer
def handle_info(:tick, current_state) do
# Enum.each(current_state.children, fn pid -> GenServer.cast(pid, :tick) end)
{:noreply, current_state}
end

@impl GenServer
def handle_call({:add_child, child, args}, _from, current_state) do
{:ok, new_child_pid} = GenServer.start_link(child, args)
new_state = %{current_state | children: [new_child_pid | current_state.children]}
{:reply, new_child_pid, new_state}
end
end
8 changes: 8 additions & 0 deletions lib/world/world_clock.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
defmodule ElixirRPG.World.Clock do
def start_tick(target_ticks_per_sec, target_pid)
when is_pid(target_pid) and is_integer(target_ticks_per_sec) do
ms = trunc(1000 / target_ticks_per_sec)
{:ok, timer_ref} = :timer.send_interval(ms, target_pid, :tick)
timer_ref
end
end
27 changes: 27 additions & 0 deletions mix.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
defmodule ElixirRpg.MixProject do
use Mix.Project

def project do
[
app: :elixir_rpg,
version: "0.1.0",
elixir: "~> 1.11",
start_permanent: Mix.env() == :prod,
deps: deps()
]
end

# Run "mix help compile.app" to learn about applications.
def application do
[
extra_applications: [:logger]
]
end

# Run "mix help deps" to learn about dependencies.
defp deps do
[
{:typed_struct, "~> 0.2.1"}
]
end
end
3 changes: 3 additions & 0 deletions mix.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
%{
"typed_struct": {:hex, :typed_struct, "0.2.1", "e1993414c371f09ff25231393b6430bd89d780e2a499ae3b2d2b00852f593d97", [:mix], [], "hexpm", "8f5218c35ec38262f627b2c522542f1eae41f625f92649c0af701a6fab2e11b3"},
}
1 change: 1 addition & 0 deletions test/test_helper.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ExUnit.start()

0 comments on commit e5977c5

Please sign in to comment.