import DEVS2Agents: time_advance, internal_transition!, external_transition!, confluent_transition!, output!, setup_ports!, format_state, format_message @enum GenState G_Waiting=1 G_Active=2 G_Passive=3 struct Generate <: DEVSMessage activate::UnitRange{Int} end @agent struct Generator(AtomicDEVS) num_outputs::Int = 1 period::Float64 = 1.0 cycles::Int = 1 current_cycle::Int = 0 state::GenState = G_Waiting end format_state(gen::Generator) = "State.$(gen.state)_Cycle.$(gen.current_cycle)" format_message(msg::Generate) = "$(msg.activate)" function setup_ports!(gen::Generator) add_out_port!(gen, :o_out) end function time_advance(gen::Generator, model) if gen.state == G_Active return 0.0 elseif gen.state == G_Waiting return gen.period else return Inf end end function internal_transition!(gen::Generator, model) if gen.current_cycle >= gen.cycles gen.state = G_Passive elseif gen.state == G_Active gen.state = G_Waiting gen.current_cycle += 1 elseif gen.state == G_Waiting gen.state = G_Active else gen.state = Passive end end function output!(gen::Generator, model) if gen.state == G_Active return ( ( :o_out, (Generate(0:(gen.num_outputs - 1)), )), ) end return nothing end