indexing description: "[ Delayed procedures. ]" date: "$Date$" revision: "$Revision$" class EM_DELAYED_PROCEDURES inherit EM_TIME_SINGLETON create make feature -- Initialization make is -- Init do create procedure_list.make are_timed_procedures_paused:=false end feature -- Basic operations add_timed_procedure(a_procedure: PROCEDURE[ANY,TUPLE]; a_time_offset_in_ms: INTEGER) is -- Add a_procedure which will be called in TIME_OFFSET miliseconds from "now" in the same thread! -- Use the feature "process" to call all procedures whose time is up. -- You could use EM_TIME_SINGLETON for global timing: The EM_EVENT_LOOP will call "process" each loop once. -- You can also use the EM_EVENT_LOOP to have a per scene executeion. require a_procedure /=Void a_time_offset_in_ms >= 0 do procedure_list.put_first (create {EM_PAIR[PROCEDURE[ANY,TUPLE],INTEGER]}.make(a_procedure,time.ticks + a_time_offset_in_ms)) end process_timed_procedures_in_same_thread is -- executes all stored procedures whose time is up... -- Make sure you don't add procedures which use a lot of computation time. Only small, short -- procedures are appropriate. Otherwise use add_timed_callback which runs functions in a different thread -- to avoid a laggy reaction to other events. local c : PROCEDURE[ANY,TUPLE] time_ticks: INTEGER do if not are_timed_procedures_paused then time_ticks := time.ticks from procedure_list.start until procedure_list.after loop if procedure_list.item_for_iteration.second < time_ticks then c := procedure_list.item_for_iteration.first c.call ([Void]) procedure_list.remove_at else procedure_list.forth end end end end wipe_out_all_timed_procedures is -- clear the whole "delayed procedure call" list (procedures added with add_procedure, executed with execute) do procedure_list.wipe_out end remove_timed_procedure (a_procedure: PROCEDURE[ANY,TUPLE]) is -- remove first occurency of `a_procedure' from the "delayed procedure call" list -- has no effect if `a_procedure' is not in the list require a_procedure_not_void: a_procedure /= Void local removed_procedure: BOOLEAN procedure_cursor: DS_LINKED_LIST_CURSOR [EM_PAIR[PROCEDURE[ANY,TUPLE],INTEGER]] do removed_procedure := False create procedure_cursor.make (procedure_list) from procedure_cursor.start until procedure_cursor.after or removed_procedure loop if procedure_cursor.item.first.is_equal (a_procedure) then removed_procedure := True end procedure_cursor.forth if removed_procedure then procedure_cursor.remove_left end end end feature -- Setters set_are_timed_procedures_paused(a_value: BOOLEAN) is -- Set are_timed_procedures_paused to a_value -- Use this to pause the procedure callbacks. This is really usefull if you want to pause a game! -- However, this will not pause functions added with add_timed_callback. local dt: INTEGER do if a_value = True and not are_timed_procedures_paused then pause_start_ticks := time.ticks elseif a_value = False and are_timed_procedures_paused then -- add time passed since starting the pause to the timers dt:=time.ticks - pause_start_ticks from procedure_list.start until procedure_list.after loop procedure_list.item_for_iteration.put_second (procedure_list.item_for_iteration.second + dt) procedure_list.forth end end are_timed_procedures_paused := a_value ensure are_timed_procedures_paused_set: are_timed_procedures_paused = a_value end feature -- Attributes are_timed_procedures_paused: BOOLEAN -- Are timed prcedures paused? feature {NONE} -- Implementation procedure_list : DS_LINKED_LIST[EM_PAIR[PROCEDURE[ANY,TUPLE],INTEGER]] -- list of procedures pause_start_ticks: INTEGER -- pause started ticks -- Used to compute a timedifference to implement pause mechanism. end