Packages
membrane_core
0.10.2
1.3.4
1.3.3
1.3.2
1.3.1
1.3.0
1.2.7
1.2.6
1.2.5
retired
1.2.4
1.2.3
1.2.2
1.2.1
1.2.0
1.2.0-rc1
1.1.2
1.1.1
1.1.0
1.1.0-rc1
1.1.0-rc0
1.0.1
1.0.0
1.0.0-rc1
1.0.0-rc0
0.12.9
0.12.8
0.12.7
0.12.6
0.12.5
0.12.4
0.12.3
0.12.2
0.12.1
0.12.0
retired
0.11.5
0.11.4
0.11.3
0.11.2
0.11.1
0.11.0
0.10.2
0.10.1
0.10.0
0.9.0
0.8.2
0.8.1
0.8.0
0.7.0
0.6.1
0.6.0
0.5.3
0.5.2
0.5.1
0.5.0
0.4.3
0.4.2
0.4.1
0.4.0
0.3.2
0.3.1
0.3.0
0.2.2
0.2.1
0.2.0
0.1.1
0.1.0
Membrane Multimedia Framework (Core)
Current section
Files
Jump to
Current section
Files
lib/membrane/core/timer.ex
defmodule Membrane.Core.Timer do
@moduledoc false
alias Membrane.Clock
alias Membrane.Core.Message
alias Membrane.Time
require Membrane.Core.Message
@type id_t :: any()
@type interval_t :: Ratio.t() | non_neg_integer | :no_interval
@type t :: %__MODULE__{
id: id_t,
interval: interval_t,
init_time: Time.t(),
clock: Clock.t(),
time_passed: Time.t(),
ratio: Clock.ratio_t(),
timer_ref: reference() | nil
}
@enforce_keys [:interval, :clock, :init_time, :id]
defstruct @enforce_keys ++ [time_passed: 0, ratio: 1, timer_ref: nil]
@spec start(id_t, interval_t, Clock.t()) :: t
def start(id, interval, clock) do
%__MODULE__{id: id, interval: interval, init_time: Time.monotonic_time(), clock: clock}
|> tick
end
@spec stop(t) :: :ok
def stop(timer) do
Process.cancel_timer(timer.timer_ref)
:ok
end
@spec update_ratio(t, Clock.ratio_t()) :: t
def update_ratio(timer, ratio) do
%__MODULE__{timer | ratio: ratio}
end
@spec tick(t) :: t
def tick(%__MODULE__{interval: :no_interval} = timer) do
timer
end
def tick(timer) do
use Ratio
%__MODULE__{
id: id,
interval: interval,
init_time: init_time,
time_passed: time_passed,
ratio: ratio
} = timer
time_passed = time_passed + interval
time = (init_time + time_passed / ratio) |> Ratio.floor() |> Time.to_milliseconds()
timer_ref = Process.send_after(self(), Message.new(:timer_tick, id), time, abs: true)
%__MODULE__{timer | time_passed: time_passed, timer_ref: timer_ref}
end
@spec set_interval(t, interval_t) :: t
def set_interval(%__MODULE__{interval: :no_interval} = timer, interval) do
tick(%__MODULE__{timer | interval: interval})
end
def set_interval(timer, interval) do
%__MODULE__{timer | interval: interval}
end
end