Guest User

Untitled

a guest
Nov 18th, 2017
182
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.20 KB | None | 0 0
  1. defmodule Thumbex do
  2. @moduledoc """
  3. Thumbex keeps the contexts that define your domain
  4. and business logic.
  5.  
  6. Contexts are also responsible for managing your data, regardless
  7. if it comes from the database, an external API or others.
  8. """
  9.  
  10. end
  11.  
  12. defmodule ElectronicLock do
  13. use GenStateMachine
  14. # Client
  15. def start_link(code),
  16. do: GenStateMachine.start_link(__MODULE__, code)
  17. def button(lock, digit),
  18. do: GenStateMachine.cast(lock, {:button, digit})
  19. def code_length(lock),
  20. do: GenStateMachine.call(lock, :code_length)
  21. def lock(lock),
  22. do: GenStateMachine.call(lock, :lock)
  23. def status(lock),
  24. do: GenStateMachine.call(lock, :status)
  25.  
  26. # Server
  27. def init(code) do
  28. {:ok, :locked, %{code: code}, [{:next_event, :internal, :enter}]}
  29. end
  30.  
  31. def handle_event(:internal, :enter, :locked, %{code: code} = data),
  32. do: IO.puts("Locked!") && {:keep_state, Map.put(data, :remaining, code)}
  33.  
  34. def handle_event(:cast, {:button, digit}, :locked, data) do
  35. case data.remaining do
  36. [^digit] ->
  37. {:next_state, :open, data, [{:next_event, :internal, :enter}]}
  38. [^digit | rest] ->
  39. {:keep_state, %{data | remaining: rest}}
  40. [_ | _] ->
  41. {:keep_state, %{data | remaining: data.code}}
  42. end
  43. end
  44.  
  45. def handle_event(:internal, :enter, :open, data) do
  46. #timer = :erlang.start_timer(10_000, self(), :lock)
  47. IO.puts("Unlocked!")
  48. #{:keep_state, Map.put(data, :timer, timer)}
  49.  
  50. {:next_state, :open, data, [
  51. {:state_timeout,4_000,:lock}
  52. ]}
  53.  
  54. end
  55.  
  56.  
  57. # [:state_timeout, :lock, :open, %{code: [1, 2, 3, 4], remaining: [4]}],
  58. # [file: 'lib/thumbex.ex', line: 31]},
  59.  
  60.  
  61. def handle_event(
  62. :state_timeout,
  63. :lock,
  64. :open,
  65. data
  66. ),
  67. do: {:next_state, :locked, data, [{:next_event, :internal, :enter}]}
  68.  
  69. def handle_event(
  70. :state_timeout,
  71. :lock,
  72. :locked,
  73. data
  74. ),
  75. do: {:next_state, :locked, data, [{:next_event, :internal, :enter}]}
  76.  
  77. # def handle_event(
  78. # :info,
  79. # {:timeout, timer, :lock},
  80. # :open,
  81. # %{timer: timer} = data
  82. # ),
  83. # do: {:next_state, :locked, data, [{:next_event, :internal, :enter}]}
  84. #
  85. # def handle_event(
  86. # :info,
  87. # {:timeout, timer, :lock},
  88. # :locked,
  89. # %{timer: timer} = data
  90. # )
  91. # do
  92. # IO.puts("Ignoring timeout event, already locked.")
  93. # {:next_state, :locked, data, [{:next_event, :internal, :enter}]}
  94. # end
  95.  
  96. def handle_event(:cast, {:button, _digit}, :open, _data),
  97. do: {:keep_state_and_data, [:postpone]}
  98.  
  99. def handle_event({:call, from}, :code_length, _state, %{code: code}),
  100. do: {:keep_state_and_data, [{:reply, from, length(code)}]}
  101.  
  102. def handle_event({:call, from}, :status, state, %{code: code}),
  103. do: {:keep_state_and_data, [{:reply, from, state}]}
  104.  
  105. def handle_event({:call, from}, :lock, :open, data) do
  106. {
  107. :next_state,
  108. :locked,
  109. data,
  110. [
  111. {:next_event, :internal, :enter},
  112. {:reply, from, :ok}
  113. ]
  114. }
  115. end
  116.  
  117. def handle_event({:call, from}, :lock, :locked, data) do
  118. {
  119. :next_state,
  120. :locked,
  121. data,
  122. [
  123. {:next_event, :internal, :enter},
  124. {:reply, from, :ok}
  125. ]
  126. }
  127. end
  128.  
  129. end
Add Comment
Please, Sign In to add comment