-module(smut). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/smut.gleam"). -export([init/0, new/2, with_timeout/2, get/1, set/2, update/2, update_and_get/2, get_and_update/2]). -if(?OTP_RELEASE >= 27). -define(MODULEDOC(Str), -moduledoc(Str)). -define(DOC(Str), -doc(Str)). -else. -define(MODULEDOC(Str), -compile([])). -define(DOC(Str), -compile([])). -endif. -file("src/smut.gleam", 11). ?DOC( " Create a table to hold shared, mutable state values and return a\n" " handle to it.\n" "\n" " You should call this function as early in your program as possible,\n" " preferably in your main function, and pass this handle around.\n" ). -spec init() -> smut@types:table_handle(). init() -> internal@erl_impl:init(). -file("src/smut.gleam", 21). ?DOC( " Insert a new `initial_val` of type `a` into the global state table,\n" " returning a handle for reads, writes, and updates.\n" ). -spec new(smut@types:table_handle(), FRP) -> {ok, internal@erl_impl:state(FRP)} | {error, smut@types:smut_error()}. new(Table, Initial_val) -> internal@erl_impl:new(Table, Initial_val). -file("src/smut.gleam", 30). ?DOC( " Change the default retrieval timeout (for retrievals that require a\n" " timeout) for this particular value to `ms` milliseconds.\n" "\n" " The default timeout is otherwise 5000 ms.\n" ). -spec with_timeout(internal@erl_impl:state(FRT), integer()) -> internal@erl_impl:state(FRT). with_timeout(State, Ms) -> internal@erl_impl:with_timeout(State, Ms). -file("src/smut.gleam", 45). ?DOC( " Retrieve the current value of `state`.\n" "\n" " Global state, in general, is problematic. I have done my (admittedly\n" " non-expert) best to ensure this library runs smoothly, but if anything\n" " goes wrong, this function will return `Error(Nil)`. It does not return\n" " a more informative error message, because if something _has_ gone wrong,\n" " your program, which relies on this state, is probably hosed.\n" "\n" " (In future versions, I may attempt to provide some facilities for\n" " attempting to recover from certain kinds of errors, but that's all\n" " very contingent.)\n" ). -spec get(internal@erl_impl:state(FRW)) -> {ok, FRW} | {error, nil}. get(State) -> internal@erl_impl:get(State). -file("src/smut.gleam", 68). ?DOC( " Replace the current value of `state` with the given `new_val`.\n" "\n" " The majority of the time, you will probably want to use one of\n" "\n" " * `update()`\n" " * `update_and_get()`\n" " * `get_and_update()`\n" "\n" " instead. An operation like\n" "\n" " ```gleam\n" " let assert Ok(cur_val) = smut.get(state)\n" " let new_val = update_state(cur_val)\n" " smut.set(state, new_val)\n" " ```\n" " is not guaranteed to be atomic; another process could futz with the\n" " value of `state` between the call to `smut.get()` and `smut.set()`.\n" " The `update` family of functions ensure \"atomic\" updates.\n" ). -spec set(FSA, internal@erl_impl:state(FSA)) -> nil. set(New_val, State) -> internal@erl_impl:set(New_val, State). -file("src/smut.gleam", 78). ?DOC( " Update the current value of `state` `with` the given update function.\n" "\n" " This operation is guaranteed to be \"atomic\"; that is, no other process\n" " can affect the value of `state` between its retrieval and replacement;\n" " its value immediately after the function call will be the value returned\n" " by `with`.\n" ). -spec update(fun((FSC) -> FSC), internal@erl_impl:state(FSC)) -> nil. update(With, State) -> internal@erl_impl:update(With, State). -file("src/smut.gleam", 98). ?DOC( " Update the value of `state` `with` the given function, then return the\n" " new value.\n" "\n" " ```gleam\n" " // Our updater function, which we define ahead of time to make the\n" " // call to update_and_get more readable.\n" " let f = fn(n) { n + 2 }\n" " \n" " let assert Ok(val) = smut.get(state)\n" " echo val\n" " // 8001\n" " let assert Ok(new_val) = smut.update_and_get(f, state)\n" " echo new_val\n" " // Guaranteed to be 8003 as long as no other process changed `state`\n" " // between the calls to smut.get and smut.update_and_get.\n" " ```\n" ). -spec update_and_get(fun((FSE) -> FSE), internal@erl_impl:state(FSE)) -> {ok, FSE} | {error, nil}. update_and_get(With, State) -> internal@erl_impl:update_and_retrieve(With, State). -file("src/smut.gleam", 124). ?DOC( " Return the value of `state` and _then_ update it `with` the given\n" " function.\n" "\n" " This operation is guaranteed to be \"atomic\"; that is, no other process\n" " can affect the value of `state` between its retrieval and replacement.\n" " ```gleam\n" " // Our updater function, which we define ahead of time to make the\n" " // call to get_and_update more readable.\n" " let f = fn(n) { n + 2 }\n" "\n" " let assert Ok(val) = smut.get(state)\n" " echo val\n" " // 8001\n" " let assert Ok(same_val) = smut.get_and_update(f, state)\n" " echo same_val\n" " // Guaranteed to be 8001 as long as no other process changed `state`\n" " // between the calls to smut.get and smut.get_and_update.\n" " let assert Ok(new_val) = smut.get(state)\n" " // Guaranteed to be 8003 as long as no other process changed `state`\n" " // between the calls to smut.get_and_update and the second call\n" " // to smut.get.\n" " ```\n" ). -spec get_and_update(fun((FSI) -> FSI), internal@erl_impl:state(FSI)) -> {ok, FSI} | {error, nil}. get_and_update(With, State) -> internal@erl_impl:retrieve_and_update(With, State).