Initial Grengine

parents
# 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 3rd-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
# Grengine
**TODO: Add description**
## Installation
If [available in Hex](https://hex.pm/docs/publish), the package can be installed
by adding `grengine` to your list of dependencies in `mix.exs`:
```elixir
def deps do
[{:grengine, "~> 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/grengine](https://hexdocs.pm/grengine).
# This file is responsible for configuring your application
# and its dependencies with the aid of the Mix.Config module.
use Mix.Config
# This configuration is loaded before any dependency and is restricted
# to this project. If another project depends on this project, this
# file won't be loaded nor affect the parent project. For this reason,
# if you want to provide default values for your application for
# 3rd-party users, it should be done in your "mix.exs" file.
# You can configure for your application as:
#
# config :grengine, key: :value
#
# And access this configuration in your application as:
#
# Application.get_env(:grengine, :key)
#
# Or configure a 3rd-party app:
#
# config :logger, level: :info
#
# It is also possible to import configuration files, relative to this
# directory. For example, you can emulate configuration per environment
# by uncommenting the line below and defining dev.exs, test.exs and such.
# Configuration from the imported file will override the ones defined
# here (which is why it is important to import them last).
#
# import_config "#{Mix.env}.exs"
defmodule Grengine.Grain do
alias Grengine.{Grain, Parameter}
def start_link() do
Agent.start_link(fn -> %{} end)
end
def get(grain, key) do
Agent.get(grain, fn map -> map[key] end)
end
def set(grain, key, value) do
Agent.update(grain, &Map.put(&1, key, value))
end
def get_values(grain) do
Agent.get(grain, &(&1))
end
def to_string(grain) do
"{}"
end
end
defmodule Grengine do
@moduledoc """
Documentation for Grengine.
"""
@doc """
Hello world.
## Examples
iex> Grengine.hello
:world
"""
def hello do
:world
end
end
defmodule Grengine.Application do
# See http://elixir-lang.org/docs/stable/elixir/Application.html
# for more information on OTP Applications
@moduledoc false
use Application
def start(_type, _args) do
import Supervisor.Spec, warn: false
# Define workers and child supervisors to be supervised
children = [
# Starts a worker by calling: Grengine.Worker.start_link(arg1, arg2, arg3)
# worker(Grengine.Worker, [arg1, arg2, arg3]),
supervisor(Grengine.PerformanceSupervisor, [])
]
# See http://elixir-lang.org/docs/stable/elixir/Supervisor.html
# for other strategies and supported options
opts = [strategy: :one_for_one, name: Grengine.Supervisor]
Supervisor.start_link(children, opts)
end
end
defmodule Grengine.PerformanceSupervisor do
use Supervisor
require Logger
def start_link do
Logger.info "Starting PerformanceSupervisor"
Supervisor.start_link(__MODULE__, [], name: :performance_supervisor)
end
def start_performance(name) do
Supervisor.start_child(:performance_supervisor, [name])
end
def init(_) do
children = [
worker(Grengine.Performance, [])
]
supervise(children, strategy: :simple_one_for_one)
end
end
defmodule Grengine.Parameter do
defstruct name: :none, value: :none
alias Grengine.Parameter
def start_link(name \\ :none) do
Agent.start_link(fn -> %Parameter{name: name, value: :none} end)
end
def name(parameter) do
Agent.get(parameter, fn state -> state.name end)
end
def value(parameter) do
Agent.get(parameter, fn state -> state.value end)
end
def set?(parameter) do
case Agent.get(parameter, fn state -> state.name end) do
:none -> false
_ -> true
end
end
def set_value(parameter, value) when is_number value do
Agent.update(parameter, fn state -> Map.put(state, :value, value) end)
end
def set_name(parameter, name) do
Agent.update(parameter, fn state -> Map.put(state, :name, name) end)
end
def to_string(parameter) do
"(name:#{name(parameter)}: #{value(parameter)})"
end
end
defmodule Grengine.Performance do
use GenServer
alias Grengine.Performance
alias Grengine.Grain
def start_link(name) do
GenServer.start_link(__MODULE__, [], name: via_tuple(name))
end
defp via_tuple(performance_name) do
{:via, :gproc, {:n, :l, {:performance, performance_name}}}
end
def set_values(performance_name, params) do
GenServer.cast(via_tuple(performance_name), {:set_values, params})
end
def get_values(performance_name) do
GenServer.call(via_tuple(performance_name), :get_values)
end
def send_values(performance_name) do
GenServer.cast(via_tuple(performance_name), {:send_values, performance_name})
end
# SERVER
def init(params) do
{:ok, grain} = Grain.start_link()
{:ok, grain}
end
def handle_cast({:set_values, params}, grain) do
Enum.each(params, fn {k, v} ->
Grain.set(grain, k, v)
end)
{:noreply, grain}
end
def handle_cast({:send_values, name}, grain) do
IO.puts("sending: #{name} #{inspect grain}")
# GrainsEngine.OscSender.send_grain(name, grain)
{:noreply, grain}
end
def handle_call(:get_values, _from, grain) do
{:reply, Grain.get_values(grain), grain}
end
end
defmodule Grengine.Mixfile do
use Mix.Project
def project do
[app: :grengine,
version: "0.1.0",
elixir: "~> 1.4",
build_embedded: Mix.env == :prod,
start_permanent: Mix.env == :prod,
deps: deps()]
end
# Configuration for the OTP application
#
# Type "mix help compile.app" for more information
def application do
# Specify extra applications you'll use from Erlang/Elixir
[extra_applications: [:logger, :gproc],
mod: {Grengine.Application, []}]
end
# Dependencies can be Hex packages:
#
# {:my_dep, "~> 0.3.0"}
#
# Or git/path repositories:
#
# {:my_dep, git: "https://github.com/elixir-lang/my_dep.git", tag: "0.1.0"}
#
# Type "mix help deps" for more examples and options
defp deps do
[
{:gproc, "0.3.1"},
{:mix_test_watch, "~> 0.3", only: :dev, runtime: false}
]
end
end
%{"fs": {:hex, :fs, "2.12.0", "ad631efacc9a5683c8eaa1b274e24fa64a1b8eb30747e9595b93bec7e492e25e", [:rebar3], []},
"gproc": {:hex, :gproc, "0.3.1", "ec14f40cb941bde3f940de59c11e59beb2977e90dbae72fab3ddf77743fd4ea9", [:rebar], []},
"mix_test_watch": {:hex, :mix_test_watch, "0.4.0", "7e44b681b0238999d4c39b5beed77b4ac45aef1c112a763aae414bdb5bc34523", [:mix], [{:fs, "~> 2.12", [hex: :fs, optional: false]}]}}
defmodule GrainTest do
use ExUnit.Case, async: true
doctest Grengine.Grain
alias Grengine.Grain
describe "empty Grain" do
setup do
{:ok, grain} = Grain.start_link()
{:ok, grain: grain}
end
test "represents string", %{grain: grain} do
assert Grain.to_string(grain) == "{}"
end
test "get nonexistent parameter", %{grain: grain} do
assert Grain.get(grain, :bar) == nil
end
test "set a value", %{grain: grain} do
Grain.set(grain, :foo, 88)
assert Grain.get(grain, :foo) == 88
end
test "get all values", %{grain: grain} do
Grain.set(grain, :foo, 88)
Grain.set(grain, :bar, 42)
assert Grain.get_values(grain) == %{foo: 88, bar: 42}
end
end
end
defmodule GrengineTest do
use ExUnit.Case
doctest Grengine
test "the truth" do
assert 1 + 1 == 2
end
end
defmodule ParameterTest do
use ExUnit.Case, async: true
alias Grengine.Parameter
describe "populated Parameter" do
setup do
{:ok, parameter} = Parameter.start_link("foo")
{:ok, parameter: parameter}
end
test "represents string", %{parameter: parameter} do
assert Parameter.to_string(parameter) == "(name:foo: none)"
end
test "set a value", %{parameter: parameter} do
Parameter.set_value(parameter, 42)
assert Parameter.value(parameter) == 42
end
# test "set all values for the player", %{player: player} do
# values = %{foo: 1, bar: 2}
# Player.update_parameters(player, values)
# assert Player.get_values(player) == %{bar: 2, foo: 1}
# end
end
end
defmodule PerformanceTest do
use ExUnit.Case, async: true
doctest Grengine.Performance
alias Grengine.Performance
describe "empty Performance" do
setup do
{:ok, perf} = Performance.start_link("foo")
{:ok, perf: perf}
end
test "represents string", %{perf: perf} do
assert Performance.to_string(perf) == "{}"
end
end
end
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment