Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 19 additions & 3 deletions lib/mix/tasks/ecsx.gen.component.ex
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,13 @@ defmodule Mix.Tasks.Ecsx.Gen.Component do

def run([component_type_name, value_type | opts]) do
value_type = validate(value_type)
{opts, _, _} = OptionParser.parse(opts, strict: [index: :boolean])
Helpers.inject_component_module_into_manager(component_type_name)
{opts, _, _} = OptionParser.parse(opts, strict: [index: :boolean, namespace: :string])

case namespace = Keyword.get(opts, :namespace, nil) do
nil -> Helpers.inject_component_module_into_manager(component_type_name)
_ -> Helpers.inject_component_module_into_manager({component_type_name, namespace})
end

create_component_file(component_type_name, value_type, opts)
end

Expand All @@ -68,17 +73,28 @@ defmodule Mix.Tasks.Ecsx.Gen.Component do
do: Mix.raise("Invalid value type. Possible types are: #{inspect(@valid_value_types)}")

defp create_component_file(component_type_name, value_type, opts) do
{namespace, namespace_file_name} = format_namespace(Keyword.get(opts, :namespace, nil))
filename = Macro.underscore(component_type_name)
target = "lib/#{Helpers.otp_app()}/components/#{filename}.ex"

target =
case namespace do
nil -> "lib/#{Helpers.otp_app()}/components/#{filename}.ex"
_ -> "lib/#{Helpers.otp_app()}/components/#{namespace_file_name}/#{filename}.ex"
end

source = Application.app_dir(:ecsx, "/priv/templates/component.ex")

binding = [
app_name: Helpers.root_module(),
index: Keyword.get(opts, :index, false),
namespace: namespace,
component_type: component_type_name,
value: value_type
]

Mix.Generator.create_file(target, EEx.eval_file(source, binding))
end

defp format_namespace(nil), do: {nil, nil}
defp format_namespace(namespace), do: {Macro.camelize(namespace), Macro.underscore(namespace)}
end
53 changes: 49 additions & 4 deletions lib/mix/tasks/ecsx.gen.system.ex
Original file line number Diff line number Diff line change
Expand Up @@ -27,20 +27,58 @@ defmodule Mix.Tasks.Ecsx.Gen.System do
""")
end

def run([system_name | _] = _args) do
inject_system_module_into_manager(system_name)
create_system_file(system_name)
def run([system_name | opts] = _args) do
{opts, _, _} = OptionParser.parse(opts, strict: [namespace: :string])

case namespace = Keyword.get(opts, :namespace, nil) do
nil ->
inject_system_module_into_manager(system_name)
create_system_file(system_name)

_ ->
inject_system_module_into_manager({system_name, namespace})
create_system_file(system_name, namespace)
end
end

defp create_system_file(system_name) do
filename = Macro.underscore(system_name)
target = "lib/#{Helpers.otp_app()}/systems/#{filename}.ex"
source = Application.app_dir(:ecsx, "/priv/templates/system.ex")
binding = [app_name: Helpers.root_module(), system_name: system_name]
binding = [app_name: Helpers.root_module(), system_name: system_name, namespace: nil]

Mix.Generator.create_file(target, EEx.eval_file(source, binding))
end

defp create_system_file(system_name, namespace) do
{namespace, namespace_file_name} = format_namespace(namespace)

filename = Macro.underscore(system_name)
target = "lib/#{Helpers.otp_app()}/systems/#{namespace_file_name}/#{filename}.ex"
source = Application.app_dir(:ecsx, "/priv/templates/system.ex")
binding = [app_name: Helpers.root_module(), namespace: namespace, system_name: system_name]

Mix.Generator.create_file(target, EEx.eval_file(source, binding))
end

defp inject_system_module_into_manager({system_name, namespace}) do
manager_path = ECSx.manager_path()
{before_systems, after_systems, list} = parse_manager(manager_path)

new_list =
{system_name, namespace}
|> add_system_to_list(list)
|> ensure_list_format()

new_contents =
[before_systems, "def systems do\n ", new_list, "\n end\n", after_systems]
|> IO.iodata_to_binary()
|> Code.format_string!()

Mix.shell().info([:green, "* injecting ", :reset, manager_path])
File.write!(manager_path, [new_contents, "\n"])
end

defp inject_system_module_into_manager(system_name) do
manager_path = ECSx.manager_path()
{before_systems, after_systems, list} = parse_manager(manager_path)
Expand Down Expand Up @@ -76,6 +114,10 @@ defmodule Mix.Tasks.Ecsx.Gen.System do
|> inspect()
end

defp full_system_module({system_name, namespace}) do
Module.concat([Helpers.root_module(), "Systems", namespace, system_name])
end

defp full_system_module(system_name) do
Module.concat([Helpers.root_module(), "Systems", system_name])
end
Expand All @@ -86,4 +128,7 @@ defmodule Mix.Tasks.Ecsx.Gen.System do

["[\n" | rest]
end

defp format_namespace(nil), do: {nil, nil}
defp format_namespace(namespace), do: {Macro.camelize(namespace), Macro.underscore(namespace)}
end
22 changes: 22 additions & 0 deletions lib/mix/tasks/ecsx/helpers.ex
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,24 @@ defmodule Mix.Tasks.ECSx.Helpers do

def write_file(contents, path), do: File.write!(path, contents)

def inject_component_module_into_manager({component_type, namespace}) do
manager_path = ECSx.manager_path()
{before_components, after_components, list} = parse_manager_components(manager_path)

new_list =
{component_type, namespace}
|> add_component_to_list(list)
|> ensure_list_format()

new_contents =
[before_components, "def components do\n ", new_list, "\n end\n", after_components]
|> IO.iodata_to_binary()
|> Code.format_string!()

Mix.shell().info([:green, "* injecting ", :reset, manager_path])
File.write!(manager_path, [new_contents, "\n"])
end

def inject_component_module_into_manager(component_type) do
manager_path = ECSx.manager_path()
{before_components, after_components, list} = parse_manager_components(manager_path)
Expand Down Expand Up @@ -61,6 +79,10 @@ defmodule Mix.Tasks.ECSx.Helpers do
|> inspect()
end

defp full_component_module({component_type, namespace}) do
Module.concat([root_module(), "Components", namespace, component_type])
end

defp full_component_module(component_type) do
Module.concat([root_module(), "Components", component_type])
end
Expand Down
2 changes: 1 addition & 1 deletion mix.lock
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
"mix_test_watch": {:hex, :mix_test_watch, "1.1.0", "330bb91c8ed271fe408c42d07e0773340a7938d8a0d281d57a14243eae9dc8c3", [:mix], [{:file_system, "~> 0.2.1 or ~> 0.3", [hex: :file_system, repo: "hexpm", optional: false]}], "hexpm", "52b6b1c476cbb70fd899ca5394506482f12e5f6b0d6acff9df95c7f1e0812ec3"},
"nimble_parsec": {:hex, :nimble_parsec, "1.2.3", "244836e6e3f1200c7f30cb56733fd808744eca61fd182f731eac4af635cc6d0b", [:mix], [], "hexpm", "c8d789e39b9131acf7b99291e93dae60ab48ef14a7ee9d58c6964f59efb570b0"},
"parse_trans": {:hex, :parse_trans, "3.3.1", "16328ab840cc09919bd10dab29e431da3af9e9e7e7e6f0089dd5a2d2820011d8", [:rebar3], [], "hexpm", "07cd9577885f56362d414e8c4c4e6bdf10d43a8767abb92d24cbe8b24c54888b"},
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.6", "cf344f5692c82d2cd7554f5ec8fd961548d4fd09e7d22f5b62482e5aeaebd4b0", [:make, :mix, :rebar3], [], "hexpm", "bdb0d2471f453c88ff3908e7686f86f9be327d065cc1ec16fa4540197ea04680"},
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.7", "354c321cf377240c7b8716899e182ce4890c5938111a1296add3ec74cf1715df", [:make, :mix, :rebar3], [], "hexpm", "fe4c190e8f37401d30167c8c405eda19469f34577987c76dde613e838bbc67f8"},
"statistex": {:hex, :statistex, "1.0.0", "f3dc93f3c0c6c92e5f291704cf62b99b553253d7969e9a5fa713e5481cd858a5", [:mix], [], "hexpm", "ff9d8bee7035028ab4742ff52fc80a2aa35cece833cf5319009b52f1b5a86c27"},
"telemetry": {:hex, :telemetry, "1.2.1", "68fdfe8d8f05a8428483a97d7aab2f268aaff24b49e0f599faa091f1d4e7f61c", [:rebar3], [], "hexpm", "dad9ce9d8effc621708f99eac538ef1cbe05d6a874dd741de2e689c47feafed5"},
"unicode_util_compat": {:hex, :unicode_util_compat, "0.7.0", "bc84380c9ab48177092f43ac89e4dfa2c6d62b40b8bd132b1059ecc7232f9a78", [:rebar3], [], "hexpm", "25eee6d67df61960cf6a794239566599b09e17e668d3700247bc498638152521"},
Expand Down
2 changes: 1 addition & 1 deletion priv/templates/component.ex
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
defmodule <%= app_name %>.Components.<%= component_type %> do
defmodule <%= app_name %>.Components.<%= if namespace do %><%= namespace %>.<%= component_type %><% else %><%= component_type %><% end %> do
@moduledoc """
Documentation for <%= component_type %> components.
"""
Expand Down
2 changes: 1 addition & 1 deletion priv/templates/system.ex
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
defmodule <%= app_name %>.Systems.<%= system_name %> do
defmodule <%= app_name %>.Systems.<%= if namespace do %><%= namespace %>.<%= system_name %><% else %><%= system_name %><% end %> do
@moduledoc """
Documentation for <%= system_name %> system.
"""
Expand Down
34 changes: 34 additions & 0 deletions test/mix/tasks/ecsx.gen.component_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,14 @@ defmodule Mix.Tasks.Ecsx.Gen.ComponentTest do
Mix.Tasks.Ecsx.Gen.Component.run(["FooComponent", "binary"])
Mix.Tasks.Ecsx.Gen.Component.run(["BarComponent", "integer"])
Mix.Tasks.Ecsx.Gen.Component.run(["BazComponent", "float"])
Mix.Tasks.Ecsx.Gen.Component.run(["NamespacedComponent1", "float", "--namespace", "Sample"])

Mix.Tasks.Ecsx.Gen.Component.run([
"NamespacedComponent2",
"integer",
"--namespace",
"SampleNamespace"
])

manager_file = File.read!("lib/my_app/manager.ex")

Expand All @@ -105,6 +113,8 @@ defmodule Mix.Tasks.Ecsx.Gen.ComponentTest do
# Declare all valid Component types
def components do
[
MyApp.Components.SampleNamespace.NamespacedComponent2,
MyApp.Components.Sample.NamespacedComponent1,
MyApp.Components.BazComponent,
MyApp.Components.BarComponent,
MyApp.Components.FooComponent
Expand Down Expand Up @@ -206,4 +216,28 @@ defmodule Mix.Tasks.Ecsx.Gen.ComponentTest do
"""
end)
end

test "generates a component with a namespace flag" do
Mix.Project.in_project(:my_app, ".", fn _module ->
Mix.Tasks.Ecsx.Gen.Component.run([
"FooComponent",
"binary",
"--namespace",
"EntityNamespace"
])

component_file = File.read!("lib/my_app/components/entity_namespace/foo_component.ex")

assert component_file ==
"""
defmodule MyApp.Components.EntityNamespace.FooComponent do
@moduledoc \"\"\"
Documentation for FooComponent components.
\"\"\"
use ECSx.Component,
value: :binary
end
"""
end)
end
end
26 changes: 26 additions & 0 deletions test/mix/tasks/ecsx.gen.system_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ defmodule Mix.Tasks.Ecsx.Gen.SystemTest do
Mix.Project.in_project(:my_app, ".", fn _module ->
Mix.Tasks.Ecsx.Gen.System.run(["FooSystem"])
Mix.Tasks.Ecsx.Gen.System.run(["BarSystem"])
Mix.Tasks.Ecsx.Gen.System.run(["BazSystem", "--namespace", "NewNamespace"])

manager_file = File.read!("lib/my_app/manager.ex")

Expand Down Expand Up @@ -116,6 +117,7 @@ defmodule Mix.Tasks.Ecsx.Gen.SystemTest do
# Declare all Systems to run
def systems do
[
MyApp.Systems.NewNamespace.BazSystem,
MyApp.Systems.BarSystem,
MyApp.Systems.FooSystem
]
Expand Down Expand Up @@ -178,4 +180,28 @@ defmodule Mix.Tasks.Ecsx.Gen.SystemTest do
"""
end)
end

test "Generates a name spaced system" do
Mix.Project.in_project(:my_app, ".", fn _module ->
Mix.Tasks.Ecsx.Gen.System.run(["FooSystem", "--namespace", "EntityNamespace"])

system_file = File.read!("lib/my_app/systems/entity_namespace/foo_system.ex")

assert system_file ==
"""
defmodule MyApp.Systems.EntityNamespace.FooSystem do
@moduledoc \"\"\"
Documentation for FooSystem system.
\"\"\"
@behaviour ECSx.System

@impl ECSx.System
def run do
# System logic
:ok
end
end
"""
end)
end
end