Skip to content

Commit 46d9bbc

Browse files
committed
Warns missing handle_input/3 on request_input/2
With all the different handlers for events, inputs, and messages, it can be simple to pick the wrong one when implementing. This leads to bugs that are difficult to find. I didn’t want development workflows or older projects to break, so I thought a warning would be an excellent solution to reduce the time spent debugging but still allow current projects to continue to work with this enhancement. This means that it is still possible to implement the wrong callback, but hopefully, the warning will point the developer in the right direction and save minutes, if not hours, of debugging.
1 parent a6e35e1 commit 46d9bbc

File tree

3 files changed

+41
-1
lines changed

3 files changed

+41
-1
lines changed

lib/scenic/scene.ex

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -722,7 +722,10 @@ defmodule Scenic.Scene do
722722
def request_input(scene, input_class)
723723
def request_input(scene, input) when is_atom(input), do: request_input(scene, [input])
724724

725-
def request_input(%Scene{viewport: vp, pid: pid}, inputs) when is_list(inputs) do
725+
def request_input(%Scene{viewport: vp, pid: pid, module: module}, inputs) when is_list(inputs) do
726+
unless Kernel.function_exported?(module, :handle_input, 3) do
727+
Logger.warn("Requesting input for #{inspect inputs} - #{module}.handle_input/3 not implemented")
728+
end
726729
ViewPort.Input.request(vp, inputs, pid: pid)
727730
end
728731

test/scenic/scene_test.exs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ defmodule Scenic.SceneTest do
1313
alias Scenic.Script
1414
import Scenic.Components
1515

16+
import ExUnit.CaptureLog
17+
1618
@root_id ViewPort.root_id()
1719

1820
# import IEx
@@ -68,6 +70,23 @@ defmodule Scenic.SceneTest do
6870
scene = assign(scene, pid: pid)
6971
{:ok, scene}
7072
end
73+
74+
@impl Scenic.Scene
75+
def handle_input(input, id, %{assigns: %{pid: pid}} = scene) do
76+
send(pid, {:input_test, input, id})
77+
{:noreply, scene}
78+
end
79+
end
80+
81+
defmodule TestSceneNoInputHandler do
82+
use Scenic.Scene
83+
84+
@impl Scenic.Scene
85+
def init(scene, pid, _opts) do
86+
Process.send(pid, {:up, scene}, [])
87+
scene = assign(scene, pid: pid)
88+
{:ok, scene}
89+
end
7190
end
7291

7392
@codepoint {:codepoint, {"k", []}}
@@ -403,6 +422,20 @@ defmodule Scenic.SceneTest do
403422
{:ok, [:cursor_pos, :cursor_button, :codepoint]}
404423
end
405424

425+
test "request_input warns when handle_input is not implements" do
426+
Scenic.Test.ViewPort.start({TestSceneNoInputHandler, self()})
427+
428+
scene =
429+
receive do
430+
{:up, scene} -> scene
431+
end
432+
433+
assert capture_log(fn ->
434+
Scenic.Scene.request_input(scene, [:key])
435+
end)
436+
=~ "handle_input/3 not implemented"
437+
end
438+
406439
test "unrequest_input works", %{scene: scene} do
407440
Scenic.Scene.request_input(scene, :cursor_button)
408441

test/scenic/view_port/input_test.exs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ defmodule Scenic.ViewPort.InputTest do
2727
# def handle_input( input, %{assigns: %{pid: pid}} = scene ) do
2828
# Process.send( pid, {:test_input, input}, [] )
2929
# end
30+
31+
def handle_input(_, _, scene) do
32+
{:noreply, scene}
33+
end
3034
end
3135

3236
setup do

0 commit comments

Comments
 (0)