% Copyright 2025 BradBot_1 % Licensed under the Apache License, Version 2.0 (the "License"); % you may not use this file except in compliance with the License. % You may obtain a copy of the License at % http://www.apache.org/licenses/LICENSE-2.0 % Unless required by applicable law or agreed to in writing, software % distributed under the License is distributed on an "AS IS" BASIS, % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. % See the License for the specific language governing permissions and % limitations under the License. -module(future_manual). -export([create/0]). %% Creates a future that only resolves when it recieves a message %% %% The future will resolve with the value of the message %% %% To send a message use the returned functions %% %% Returns [resolve, reject, fail, future] %% %% > Please note that lifecycle management of this future is managed by YOU! %% > You MUST release it when you are done with it else have a memory leak! (This comes from how the erlang gc works) %% > If you want to immediately release the future on completion then use `auto_release`! create() -> Ref = make_ref(), FuturePid = 'futureFfi':start(fun(RequiredRef) when is_reference(RequiredRef) -> receive {ok, RequiredRef, Result} -> {ok, Result}; {error, RequiredRef, Result} -> {error, Result}; {failed, RequiredRef, Result} when is_binary(Result) -> {failed, Result}; {failed, RequiredRef, _} -> {failed, <<"Manual future recieved invalid message. Must fail with a binary reason."/utf8>>} end end, Ref), case catch gen_server:call(FuturePid, get_child) of {'EXIT', _} -> throw(<<"Manual future failed to start"/utf8>>); nil -> throw(<<"Manual future resolved too early"/utf8>>); ChildPid when is_pid(ChildPid) -> {fun (Value) -> ChildPid ! {ok, Ref, Value}, ok end, fun (Value) -> ChildPid ! {error, Ref, Value}, ok end, fun (Reason) when is_binary(Reason) -> ChildPid ! {failed, Ref, Reason}, ok end, FuturePid}; _ -> throw(<<"Manual future has invalid child pid response"/utf8>>) end.