|  | 
|  | 1 | +# Hints | 
|  | 2 | + | 
|  | 3 | +## General | 
|  | 4 | + | 
|  | 5 | +- Read about behaviours in the official [Getting Started guide][getting-started-behaviours]. | 
|  | 6 | +- Read about behaviours on [elixirschool.com][elixir-school-behaviours]. | 
|  | 7 | +- Read about behaviours in the [documentation][doc-behaviours]. | 
|  | 8 | +- Read about `use` in the official [Getting Started guide][getting-started-use]. | 
|  | 9 | +- Read about `use` in the [documentation][doc-use]. | 
|  | 10 | + | 
|  | 11 | +## 1. Define the animation behaviour | 
|  | 12 | + | 
|  | 13 | +- Use the `@callback` module attribute to define the desired functions. | 
|  | 14 | +- Each callback must specify the function name, list of arguments (their types) and the return value (its type). | 
|  | 15 | +- Use the given custom types `dot`, `opts`, `error`, and `frame_number` in the callbacks' definitions. | 
|  | 16 | +- Refresh your knowledge of [typespecs][typespec] to help with defining callbacks. | 
|  | 17 | + | 
|  | 18 | +## 2. Provide a default implementation of the `init/1` callback | 
|  | 19 | + | 
|  | 20 | +- Define a `__using__/1` macro in the `DacingDots.Animation` module. | 
|  | 21 | +- The macros' argument can be ignored. | 
|  | 22 | +- The macro must return a [quoted expression][quote]. | 
|  | 23 | +- In the quoted expression, use `@behaviour` so that calling `use DacingDots.Animation` sets `DacingDots.Animation` as the using module's behaviour. | 
|  | 24 | +- In the quoted expression, implement the `init/1` function. | 
|  | 25 | +- The default implementation of the `init/1` function should wrap the given `opts` argument in `:ok` tuple. | 
|  | 26 | +- There is [a macro][defoverridable] that can mark a function as overridable. | 
|  | 27 | + | 
|  | 28 | +## 3. Implement the `Flicker` animation | 
|  | 29 | + | 
|  | 30 | +- Make use of `DancingDots.Animation` `__using__/1` macro by calling [this one special macro][doc-use] in the `DancingDots.Flicker` module. | 
|  | 31 | +- You do not need to implement the `init/1` function. Its default implementation is enough. | 
|  | 32 | +- You need to implement the `handle_frame/3` function. | 
|  | 33 | +- To detect "every 4th frame", you can check if the [remainder][rem] when dividing it by 4 is equal to 0. | 
|  | 34 | + | 
|  | 35 | +## 4. Implement the `Zoom` animation | 
|  | 36 | + | 
|  | 37 | +- Make use of `DancingDots.Animation` `__using__/1` macro by calling [this one special macro][doc-use] in the `DancingDots.Zoom` module. | 
|  | 38 | +- You need to implement both the `init/1` function and the `handle_frame/3` function. | 
|  | 39 | +- Use the [`Keyword`][keyword] module to work with the options keyword list. | 
|  | 40 | +- There is [a built-in guard][is_number] for checking if a value is a number. | 
|  | 41 | + | 
|  | 42 | +[getting-started-behaviours]: https://elixir-lang.org/getting-started/typespecs-and-behaviours.html#behaviours | 
|  | 43 | +[doc-behaviours]: https://hexdocs.pm/elixir/typespecs.html#behaviours | 
|  | 44 | +[elixir-school-behaviours]: https://elixirschool.com/en/lessons/advanced/behaviours | 
|  | 45 | +[doc-use]: https://hexdocs.pm/elixir/Kernel.html#use/2 | 
|  | 46 | +[getting-started-use]: https://elixir-lang.org/getting-started/alias-require-and-import.html#use | 
|  | 47 | +[typespec]: https://hexdocs.pm/elixir/typespecs.html | 
|  | 48 | +[defoverridable]: https://hexdocs.pm/elixir/Kernel.html#defoverridable/1 | 
|  | 49 | +[quote]: https://hexdocs.pm/elixir/Kernel.SpecialForms.html#quote/2 | 
|  | 50 | +[rem]: https://hexdocs.pm/elixir/Kernel.html#rem/2 | 
|  | 51 | +[is_number]: https://hexdocs.pm/elixir/Kernel.html#is_number/1 | 
|  | 52 | +[keyword]: https://hexdocs.pm/elixir/Keyword.html | 
0 commit comments