From: Martin <martin.dowie@btopenworld.com>
Subject: Re: Breaking a circularity
Date: Mon, 28 Mar 2011 04:06:26 -0700 (PDT)
Date: 2011-03-28T04:06:26-07:00 [thread overview]
Message-ID: <0477ecf8-3ff0-4511-82af-f38587704ca3@l11g2000yqb.googlegroups.com> (raw)
In-Reply-To: dd0c7179-9e48-4366-9b1f-c5586b2c6e3c@e21g2000yqe.googlegroups.com
On Mar 28, 5:11 am, Gene <gene.ress...@gmail.com> wrote:
> Need some expert help here with a circularity in the data structures
> for a discrete event simulation.
>
> We need event queues and an arbitrary number of event types. The
> handlers for events must have access to a simulation state record, so
> used a generic thus:
>
> generic
> type State_Type is private;
> package Event_Queues is
>
> type Event_Type is abstract tagged limited private;
>
> procedure Handle(State : in out State_Type;
> Event : access Event_Type) is abstract;
>
> type Event_Ptr_Type is access all Event_Type'Class;
>
> procedure Add(Event_Queue : in out Event_Queue_Type;
> Time : in Time_Type;
> Event : access Event_Type'Class);
>
> -- other methods not shown.
> private
>
> type Event_Type is abstract record
> Id : Positive;
> Time : Time_Type;
> end record;
>
> function Sooner_Than(A, B : in Event_Ptr_Type) return Boolean;
>
> -- We are just going to put a thin wrapper around Ada ordered sets
> to
> -- implement our event queue.
> package Event_Queues is
> new Ada.Containers.Ordered_Sets(Event_Ptr_Type, Sooner_Than,
> "=");
> type Event_Queue_Type is new Event_Queues.Set with null record;
>
> end Event_Queues;
>
> Here's the circularity: Instantiating an event queue requires the
> simulation state type, but the simulation state must contain an event
> queue (of the instantiated type).
>
> This is the best I've come up with so far:
>
> private
> type Event_Queue_Wrapper_Type;
>
> type State_Type is
> record
> Future_Events : access Event_Queue_Wrapper_Type;
> -- other stuff not shown
> end record;
>
> package Simulation_Events is
> new Event_Queues(State_Type);
>
> -- Now we can define the wrapper to contain the event queue.
> type Event_Queue_Wrapper_Type is
> record
> Queue : Simulation_Events.Event_Queue_Type;
> end record;
>
> Is there a cleaner way to do this? The painful part is introducing a
> pointer to the event queue in State_Type just to break the
> circularity, when this seems superfluous and means I should make
> State_Type controlled to release the queue.
Not sure you can do better in the sense of removing the access but
perhaps you can bundle all that up into a generic wrapper? e.g.
package States is
type State is record
I : Integer;
end record;
end States;
with Ada.Containers.Ordered_Sets;
generic
type State_Type is private;
package Event_Queues is
subtype Time_Type is Duration;
type Event_Type is abstract tagged limited private;
procedure Handle (State : in out State_Type;
Event : access Event_Type) is abstract;
type Event_Ptr_Type is access all Event_Type'Class;
type Event_Queue_Type is private;
procedure Add (Event_Queue : in out Event_Queue_Type;
Time : in Time_Type;
Event : access Event_Type'Class);
private
type Event_Type is abstract tagged limited record
Id : Positive;
Time : Time_Type;
end record;
function Sooner_Than (A, B : in Event_Ptr_Type) return Boolean;
package Event_Queues is new Ada.Containers.Ordered_Sets
(Event_Ptr_Type, Sooner_Than, "=");
type Event_Queue_Type is new Event_Queues.Set with null record;
end Event_Queues;
with Event_Queues;
generic
type State_Type is private;
package Event_Queue_Wrappers is
type Event_Queue_Wrapper_Type is private;
private
type EQW_State_Type is
record
State : State_Type;
Future_Events : access Event_Queue_Wrapper_Type;
end record;
package Simulation_Events is new Event_Queues (EQW_State_Type);
type Event_Queue_Wrapper_Type is record
Queue : Simulation_Events.Event_Queue_Type;
end record;
end Event_Queue_Wrappers;
with Event_Queue_Wrappers;
with States;
procedure Temp is
package EQW is new Event_Queue_Wrappers (State_Type =>
States.State);
EQ : EQW.Event_Queue_Wrapper_Type;
begin
null;
end Temp;
At least that decouples the state your interested in from the queue
mechanism.
Better names might help too, why expose that it is a 'wrapper' to the
user? I'd probably call what I have a '_Wrapper' as 'Event_Queue' and
then find a better name for the Event_Queues - Event_Queues_With_State
perhaps.
-- Martin
next prev parent reply other threads:[~2011-03-28 11:06 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-03-28 4:11 Breaking a circularity Gene
2011-03-28 9:59 ` Ludovic Brenta
2011-03-28 11:37 ` Simon Wright
2011-03-28 22:38 ` Gene
2011-03-29 3:01 ` Randy Brukardt
2011-03-28 19:47 ` Gene
2011-03-28 10:15 ` Simon Wright
2011-03-28 21:31 ` Gene
2011-03-28 11:06 ` Martin [this message]
2011-03-28 22:26 ` Gene
2011-03-29 16:28 ` Martin
replies disabled
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox