DarrenM-

I've struggled with this same problem myself, and I offer the solution that I've come up with. It may not be a very popular one, but it suits my needs, and I've come to like it.

If you're familiar with Object-Oriented Patterns, you may recognize this as the Publisher-Subscriber pattern. In the olden days, we referred to this as a vector-table in writing C code.

The basic problem occurs when you want this bit of code way over here, to know about something from that bit of code way over there, and the logistics of setting up subroutine calls is too messy. Simply put, a publisher-subscriber (PS) setup allows a piece of code to say Anytime someone announces that THIS happens (the publisher), please run THAT bit of code for me (the subscriber). I use this in my big PerlTK GUIs when I have a number of windows that all need to highlight something upon a mouseclick in a single window.

The implementation of this is very simple, but it does make following the code a bit more difficult for new folks (or for yourself if your memory is as bad as mine). Here was my first implementation of PS as a module:

package itemDispatch; use strict; use warnings; # The index to the dispatch hash is an item name, the contents is # a list of the callbacks that have been subscribed... my %DISPATCH; # Dispatch hash #################################################################### # Subroutine: Subscribe (external) # This routine subscribes a callback function to a dispatch item # Arguments: # $_[0] - Item Name # $_[1] - Callback function #################################################################### sub Subscribe { my $item = shift || die "missing dispatch item"; my $callback = shift || die "Missing callback function"; push(@{$DISPATCH{$item}}, $callback); } #################################################################### # Subroutine: Activate (external) # This routine activates a dispatch item # Arguments: # $_[0] - Item Name # $_[1]..$[-1] - Callback args #################################################################### sub Activate { # Get arguments... my $item = shift || die "Missing dispatch item"; my @args = @_; # Callback arguments my $coderef; foreach $coderef (@{$DISPATCH{$item}}) { &$coderef(@args); } } 1;
If you combine that module, with a module that does some work, like this example module:
package doWork; use strict; use Tk; use itemDispatch; my $PROGRESS = 0; sub StartWork { my $increment = shift || die "Missing Increment"; my $c=0; while ($c<99) { sleep 1; itemDispatch::Activate('PROGRESS', $increment); $c += $increment; } } 1;
Then an example perl script using these two modules would look like this:
use strict; use Tk; use Tk::StatusBar; use itemDispatch; use doWork; # Subscribe to PROGRESS events... itemDispatch::Subscribe('PROGRESS', \&_updateProgress); my $PROGRESS = 0; my $INCREMENT = 5; my $mw = MainWindow->new(); $mw->Button( -text => 'Start', -command => # Publish a START event... sub{ doWork::StartWork($INCREMENT)})->pack(); my $sb = $mw->StatusBar(); $sb->addProgressBar( -length => 60, -from => 0, -to => 99, -variable => \$PROGRESS, ); MainLoop(); sub _updateProgress { my $progress = shift || die "Missing Progress\n"; print STDERR "Updating progress by $progress\n"; $PROGRESS += $progress; $mw->update; }
Hope that helps!

-Craig


In reply to Re: Structure of a large Perl GUI application by cmv
in thread Structure of a large Perl GUI application by DarrenM

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.