3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Elixirを変数(Map)管理をしてVR(Resonite)でも使える仕組みを作ってみた

Last updated at Posted at 2025-12-06

VRでMapみたいのを使いたいとNeosVRのときから思っていました
なので、ElixirとResoniteで簡易的に仕組みを考えました

Screenshot from 2025-12-06 19-10-26.png

  • httpのGetでやり取りをする
    • エンドポイント
      • /insert?キー1=値1&キー2=値2&キー3=値3 …
        • 返却値: 登録ID
      • /get?id=登録ID&key=キー
        • 返却値: insertで登録した登録IDとキーの組み合わせの結果
      • /delete?id=登録ID
        • 返却値:true
  • Elixr側でメモリ管理をする
    • Elixirを止めるとデータは消えます
    • つまりetsを使います

実行イメージ

Resoniteで値取得

ブラウザーで検証例

image.png

ブラウザーで出来ることはResoniteでも出来る想定です

通信例

// 追加 マップ(name: ymn, a: 99)
get /insert?name=ymn&a=99
2

// 取得 登録ID: 2 マップのキーはname
get /get?id=2&key=name
ymn

// 取得 登録ID: 2 マップのキーはa
get /get?id=2&key=a
99

// 削除 登録ID: 2
/delete?id=2
true

// 削除されたデータを取得する空白で返ってくる
get /get?id=2&key=nama
[空白]

プログラムを書く

ets(インメモリDB)

lib/web_map/ets_map.ex
defmodule WebMap.EtsMap do
  @ets_table :data_store

  def init() do
    :ets.new(@ets_table, [:set, :public, :named_table])
    :ets.insert(@ets_table, {:id, 0})
  end

  def get_next_id() do
    :ets.update_counter(@ets_table, :id, 1)
  end

  def insert(id, map) do
    :ets.insert(@ets_table, {id_from_name(id), map})
  end

  def insert(map) do
    id = get_next_id()
    :ets.insert(@ets_table, {id_from_name(id), map})
    id
  end

  def get(id) when is_integer(id) do
    :ets.lookup(@ets_table, id_from_name(id))
    |> get_map_from_no()
  end

  defp get_map_from_no([{_, data}]) do
    data
  end

  defp get_map_from_no([]) do
    %{}
  end

  def delte(id) do
    :ets.delete(@ets_table, id_from_name(id))
  end

  defp id_from_name(id) do
    "id_#{id}"
  end
end

ETSを使ったメモリ管理です
機能は関数名と同じ

参考

コントローラー

Web部分のプログラムです

lib/web_map_web/controllers/map_controller.ex
defmodule WebMapWeb.MapController do
  use WebMapWeb, :controller
  alias WebMap.EtsMap

  def insert(conn, params) do
    EtsMap.insert(params)
    |> Integer.to_string()
    |> plain(conn)
  end

  def get(conn, %{"id" => id, "key" => key}) do
    String.to_integer(id)
    |> EtsMap.get()
    |> Map.get(key, "")
    |> plain(conn)
  end

  def delete(conn, %{"id" => id}) do
    String.to_integer(id)
    |> EtsMap.delte()
    |> inspect()
    |> plain(conn)
  end

  defp plain(body, conn) do
    conn
    |> put_resp_content_type("text/plain")
    |> send_resp(200, body)
  end
end

機能は関数名と同じ
ポイントは defp plain(body, conn) の中で
put_resp_content_type("text/plain")を書いていること
これでhtmlでなくてテキストデータを送信できます

ルーター

lib/web_map_web/router.ex
defmodule WebMapWeb.Router do
  use WebMapWeb, :router
# 省略 #
  scope "/", WebMapWeb do
    pipe_through :browser

    get "/", PageController, :home

+   get "/insert", MapController, :insert
+   get "/get", MapController, :get
+   get "/delete", MapController, :delete
  end
# 省略 #
end

起動時にETSを初期化

lib/web_map/application.ex
defmodule WebMap.Application do
  # See https://hexdocs.pm/elixir/Application.html
  # for more information on OTP Applications
  @moduledoc false

  use Application

  @impl true
  def start(_type, _args) do
+   WebMap.EtsMap.init()

    children = [
      WebMapWeb.Telemetry,
      {DNSCluster, query: Application.get_env(:web_map, :dns_cluster_query) || :ignore},
      {Phoenix.PubSub, name: WebMap.PubSub},
      # Start a worker by calling: WebMap.Worker.start_link(arg)
      # {WebMap.Worker, arg},
      # Start to serve requests, typically the last entry
      WebMapWeb.Endpoint
    ]

    # See https://hexdocs.pm/elixir/Supervisor.html
    # for other strategies and supported options
    opts = [strategy: :one_for_one, name: WebMap.Supervisor]
    Supervisor.start_link(children, opts)
  end

  # Tell Phoenix to update the endpoint configuration
  # whenever the application is updated.
  @impl true
  def config_change(changed, _new, removed) do
    WebMapWeb.Endpoint.config_change(changed, removed)
    :ok
  end
end

これで実現できました

これを応用すればIoT連携で各ポートのデータをMapに入れたりとか
GetでGPIOを直接いじるとか技術的には可能です
AtomVMに実装できればWifiでダイレクトで操作できれば面白いかも

ソース

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?