52 lines
2.9 KiB
Markdown
52 lines
2.9 KiB
Markdown
|
# Hints
|
||
|
|
||
|
## General
|
||
|
|
||
|
- Read about behaviours in the official [Getting Started guide][getting-started-behaviours].
|
||
|
- Read about behaviours on [elixirschool.com][elixir-school-behaviours].
|
||
|
- Read about behaviours in the [documentation][doc-behaviours].
|
||
|
- Read about `use` in the official [Getting Started guide][getting-started-use].
|
||
|
- Read about `use` in the [documentation][doc-use].
|
||
|
|
||
|
## 1. Define the animation behaviour
|
||
|
|
||
|
- Use the `@callback` module attribute to define the desired functions.
|
||
|
- Each callback must specify the function name, list of arguments (their types) and the return value (its type).
|
||
|
- Use the given custom types `dot`, `opts`, `error`, and `frame_number` in the callbacks' definitions.
|
||
|
- Refresh your knowledge of [typespecs][typespec] to help with defining callbacks.
|
||
|
|
||
|
## 2. Provide a default implementation of the `init/1` callback
|
||
|
|
||
|
- Define a `__using__/1` macro in the `DancingDots.Animation` module.
|
||
|
- The macros' argument can be ignored.
|
||
|
- The macro must return a [quoted expression][quote].
|
||
|
- In the quoted expression, use `@behaviour` so that calling `use DancingDots.Animation` sets `DancingDots.Animation` as the using module's behaviour.
|
||
|
- In the quoted expression, implement the `init/1` function.
|
||
|
- The default implementation of the `init/1` function should wrap the given `opts` argument in `:ok` tuple.
|
||
|
- There is [a macro][defoverridable] that can mark a function as overridable.
|
||
|
|
||
|
## 3. Implement the `Flicker` animation
|
||
|
|
||
|
- Make use of `DancingDots.Animation` `__using__/1` macro by calling [this one special macro][doc-use] in the `DancingDots.Flicker` module.
|
||
|
- You do not need to implement the `init/1` function. Its default implementation is enough.
|
||
|
- You need to implement the `handle_frame/3` function.
|
||
|
- To detect "every 4th frame", you can check if the [remainder][rem] when dividing it by 4 is equal to 0.
|
||
|
|
||
|
## 4. Implement the `Zoom` animation
|
||
|
|
||
|
- Make use of `DancingDots.Animation` `__using__/1` macro by calling [this one special macro][doc-use] in the `DancingDots.Zoom` module.
|
||
|
- You need to implement both the `init/1` function and the `handle_frame/3` function.
|
||
|
- Use the [`Keyword`][keyword] module to work with the options keyword list.
|
||
|
- There is [a built-in guard][is_number] for checking if a value is a number.
|
||
|
|
||
|
[getting-started-behaviours]: https://hexdocs.pm/elixir/typespecs.html#behaviours
|
||
|
[doc-behaviours]: https://hexdocs.pm/elixir/typespecs.html#behaviours
|
||
|
[elixir-school-behaviours]: https://elixirschool.com/en/lessons/advanced/behaviours
|
||
|
[doc-use]: https://hexdocs.pm/elixir/Kernel.html#use/2
|
||
|
[getting-started-use]: https://hexdocs.pm/elixir/alias-require-and-import.html#use
|
||
|
[typespec]: https://hexdocs.pm/elixir/typespecs.html
|
||
|
[defoverridable]: https://hexdocs.pm/elixir/Kernel.html#defoverridable/1
|
||
|
[quote]: https://hexdocs.pm/elixir/Kernel.SpecialForms.html#quote/2
|
||
|
[rem]: https://hexdocs.pm/elixir/Kernel.html#rem/2
|
||
|
[is_number]: https://hexdocs.pm/elixir/Kernel.html#is_number/1
|
||
|
[keyword]: https://hexdocs.pm/elixir/Keyword.html
|