On Tuesday 13 Jan 2004 3:04 pm, James Edward Gray II wrote:
> On Jan 13, 2004, at 6:24 AM, Gary Stainburn wrote:
>
> [snip background]
>
> > 3) As everything else will be created from the Trainset instance, they
> > will have a link to it. This will be stored as $self->{_OWNER}. This will
> > then (hopefully) provide quick direct access to the Trainset variables
> > (were Class globals). I think I should be able to simply call something 
> > like$self->{_OWNER}{_BLOCKS}
>
> Or you could always do something like $self->{_Trainset}->get_blocks(),
> which is probably a little better style.  Always use methods when you
> can.

This then gets back to the speed vs control discussion in the OOP perldocs.  
For the sake of speed I've made the decision to stick with direct access to 
variables within my code, but will eventually write methods for the external 
interface.

>
> > The example code (not tested yet) will create a long length of track
> > (TCB1 and > > TCB2), and a siding (S1).  It will then create a switch
> >  (Y-shape) point and connect that to TCB2 and S1.
> >
> > It will then create a signalbox, and in that signalbox create a lever
> > to control the set of points.
> >
> > my $tset=Trainset->new;
> > $tset->add_track('TCB1','TCB');             # create 1st block of track
> > $tset->add_track('TCB2','TCB');             # create 2nd block of track
> > $tset->add_track('S1','TCB');               # create Siding 1
>
> An add_tracks() method might be handy.  What's that second parameter,
> if I may ask?

TCB = Track Circuit Block, a block that can detect the presence of a vehicle 
(via an residual eltrical current which passes through the metal axle of the 
vehicle) as oposed to a normal 'Block' section.

I could reverse the parameter sequence so that the block type is first, then 
allow multiple block names to be specified, thus reducing the work involved.  
I'll probably make it so that it creates the links between the blocks too.

>
> > $points=$tset->add_point('GSP1','SWITCH'); # create switch point to
> > siding
> >
> > $tset->add_link('TCB1',0,'TCB2',0); # link TCB1 (rear) to TCB2
> > (advance)
> > $tset->add_link('TCB2',0,'GSP1',0); # link TCB2 to points GSP1
> > $tset->add_link('S1',0,'GSP1',1);   # link Siding1 to points GSP1
> > (offset1)
>
> Again, what are the number parameters?

To model a switch, I've got a simple block of track which has two connections 
at one end, specifically an array to hold links to the adjacent blocks, so 
that the onward link from TCB2 connects to position '0' on switch GSP1, while 
the link from siding S1 connects to position '1' on switch GSP1.  This way, 
to set the route, I simply set a subscript to '0' or '1'.

I could possibly do something like:

$tset->add_point('GSP1','SWITCH',['TCB2','S1'],[]);

>
> In my opinion the above could probably be done in one method call,
> which would make for a much nicer interface.  Heck, have it create
> tracks too if the don't exist.
>
> > $box=$tset->add_signalbox('Grosmont');      # Create Grosmont signalbox
> > $lever=$tset->add_lever('GS1');             # Create lever GS1
> > $box->use_lever($lever,0);          # Put lever1 in signalbox
>

I could do something like:

$tset->add_signalbox('Grosmont','GS1'........);

where add_signalbox could call add_lever for any lever that doesn't already 
exist (I'd still need to define the actions for the lever seperately).

> Again, too much work.  The whole point of using the Trainset object as
> the code interface is to hide all these ugly details from users.  Does
> a signal box always have at least one lever?  Create it in the signal
> box constructor then.  Or modify add_signalbox() to accept a list of
> levers to add to it.  Do all that in the Trainset code.  That's what
> it's for.
>
> > # would be nice if I could replace the above with a shortcut like
> >
> > #  $box=$tset->add_signalbox('Grosmont'); # create signalbox
> > #  $lever=$box->add_lever('GS1',0); # create lever and put in s'box
>
> Yes it would, but think bigger on the simplification scale.  Maybe you
> even leave all these low-level methods in place as there may be a time
> when I need them, but give me a high-level interface that makes my life
> easier most of the time.

Eventually, I intend to have:

my $tset=Trainset->new('<filename>');

and $tset->save('<filemame>');

at which point I can write a seperate route editor program, but I'm getting a 
bit ahead here.

>
> > $lever->set_use(0,$points,'TCB2');  # position 0 = select TCB2
> > $lever->set_use(1,$points,'S1');    # position 1 = select S1
> >
> > $lever->throw(0);                   # throw lever
> >
> > I hope that this has shown (a) what I am hoping to aim for with this
> > project
> > and (b) that I've taken on board the comments and hopefully
> > implemented the
> > suggestions correctly.
> >
> > Now the new questions.
> >
> > 1) I've put:
> >
> > use base (Trainset::Trains Trainset::Track Trainset::Signals
> >       Trainset::Levers Trainset::Boxes);
> >
> > inside Trainset.pm. Is this the correct way to call in the other
> > classes?
>
> No it's not.
>
> use Trainset::Trains;
> use Trainset::Track;
> use Trainset::Signals;
> use Trainset::Levers;
> use Trainset::Boxes;
>
> > If  so, would this also give Trainset::Boxes access to
> > Trainset::Levers::add_lever to enable the shortcut I mentioned above?
>
> After you switch to the code above sure, but I'm not sure it needs to.
> Trainset is the glue object.  Use it that way.  Trainsets'
> add_signalbox() should create the box, create the lever(s) and link
> them together.  Trainset::Boxes just needs to worry about itself, in
> construction at least.

So basically, within the add_signalbox would simply call $owner->add_lever 
asuming $owner points to the $tset object?

>
> > 2) What I do with the data will obviously depend on the program using
> > my
> > object, but would probably be things like update the screen (Term, TK,
> > Win32), or to send instructions to a control system (e.g. throw points
> > on
> > model railway).
> >
> > What is the best method to pass control back to the program from
> > within a
> > method?
>
> I don't think I understand this question.  The obvious answer to me is
> return (exit the method).  Control will pass back to the caller at this
> point, as it always does.  If I misunderstood, please try explaining it
> again.

What I mean is that if e.g. a train movement updates the status of a block, 
Trainset::Track::Update is called for that track object.  This will update 
must be given back to the calling program so that the screen can be updated.  

However, exit won't work here because the original program didn't call the 
update method, a train object did.

Also, updating the state of one block may also update adjacent blocks, so 
Trainset::Track::Update needs to be called for each of those, again with the 
updates needing repainting on-screen before returning to the train object.

Paul Johnson's suggestion of using Call-back routines looks to fit the bill, 
because it then can perform whatever action is required.  I'll look into 
doing that.

>
> James

Thanks all for the comments.  As work keeps getting in the way I've not 
actually been able to implement any of today's suggestions yet, but it looks 
like they're going to greatly simplify my code.
-- 
Gary Stainburn
 
This email does not contain private or confidential material as it
may be snooped on by interested government parties for unknown
and undisclosed purposes - Regulation of Investigatory Powers Act, 2000     


-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
<http://learn.perl.org/> <http://learn.perl.org/first-response>


Reply via email to