Hello brothers and sisters of the monastery,

I came across a dated article by Philip Durbin (from 10/2011). I thought to give MCE::Hobo a try and see how it goes.

The STFL library, a curses-based widget set for text terminals, compiles seamlessly on the Linux platform. Ncurses development libraries and swig are needed on CentOS 7.3. I've not tested on other Unix platforms.

sudo yum install ncurses-devel swig tar xzf /path/to/stfl-0.24.tar.gz cd stfl-0.24 # Modify Makefile and comment out the SWIG lines #ifeq ($(FOUND_SWIG)$(FOUND_PERL5),11) #include perl5/Makefile.snippet #endif #ifeq ($(FOUND_SWIG)$(FOUND_PYTHON),11) #include python/Makefile.snippet #endif #ifeq ($(FOUND_SWIG)$(FOUND_RUBY),11) #include ruby/Makefile.snippet #endif sudo make install # Finally, build the Perl module cd perl5 swig -Wall -perl stfl.i perl Makefile.PL sudo make install

example.stfl

From the STFL documentation, a special language is used to describe the STFL GUI.

** * example.stfl: STFL layout for example1.pl and example2.pl. ** vbox hbox .expand:0 @style_normal:bg=yellow,fg=black label text:'Little STFL Program' label["label 1"] text["text 1"]:"10000" label["label 2"] text["text 2"]:"20000" label["label 3"] text["text 3"]:"30000" table .expand:0 @input#style_focus:bg=blue,fg=white,attr=bold @input#style_normal:bg=blue,fg=black @input#.border:rtb @L#style_normal:fg=red @L#.expand:0 @L#.border:ltb @L#.spacer:r label#L text:'Field A:' input .colspan:3 text[value_a]:'foo' tablebr label#L text:'Field B:' input text[value_b]:'bar' label#L text:'Field C:' input text[value_c]:'baz' label .expand:v .tie:bl text[helpmsg]:''

example_p1.pl

Each worker increments a shared counter. What is cool about STFL is being able to enter text while the counters increment simultaneously in the terminal. Pressing F2 signals the workers to exit. F1 spawns new Hobo workers. Pressing ESC or Ctrl-C (handled by MCE::Signal) exits the application.

#!/usr/bin/env perl use strict; use warnings; use stfl; use MCE::Hobo 1.831; use MCE::Shared; use Time::HiRes qw/sleep/; my $count1 = MCE::Shared->scalar(10000); my $count2 = MCE::Shared->scalar(20000); my $count3 = MCE::Shared->scalar(30000); my $layout; { open my $fh, "<", "example.stfl" or die "open error 'example.stfl': $!"; local $/; $layout = <$fh>; } my $f = stfl::create($layout); my $s = 0; # MCE::Hobo 1.832 and later releases will set posix_exit # automatically when present, $INC{'stfl.pm'}. MCE::Hobo->init( posix_exit => 1 ); sub bg_start { unless ($s) { mce_async { sleep(0.9), $count1->incr() while 1 }; mce_async { sleep(0.6), $count2->incr() while 1 }; mce_async { sleep(0.3), $count3->incr() while 1 }; $s = 1; } } sub bg_stop { if ($s) { $_->exit()->join() for MCE::Hobo->list(); $s = 0; } } $f->set('helpmsg', '[ ESC = exit | F1 = start | F2 = stop ]'); bg_start(); while (1) { my $event = $f->run(50); if ($s) { # must stringify in case numeric value $f->set('text 1', ''.$count1->get()); $f->set('text 2', ''.$count2->get()); $f->set('text 3', ''.$count3->get()); } next unless (defined $event); bg_start() if $event eq 'F1'; bg_stop() if $event eq 'F2'; last if $event eq 'ESC'; } bg_stop();

example_p2.pl

Here, workers enqueue the form ID and value into a queue. The main process makes one trip to the shared-manager, maximum 3 replies.

#!/usr/bin/env perl use strict; use warnings; use stfl; use MCE::Hobo 1.831; use MCE::Shared; use Time::HiRes qw/sleep/; my $q = MCE::Shared->queue(); my $layout; { open my $fh, "<", "example.stfl" or die "open error 'example.stfl': $!"; local $/; $layout = <$fh>; } my $f = stfl::create($layout); my $s = 0; # MCE::Hobo 1.832 and later releases will set posix_exit # automatically when present, $INC{'stfl.pm'}. MCE::Hobo->init( posix_exit => 1 ); mce_async { my $c = 10000; sleep(0.9), $q->enqueue([ 'text 1', ++$c ]) while 1; }; mce_async { my $c = 20000; sleep(0.6), $q->enqueue([ 'text 2', ++$c ]) while 1; }; mce_async { my $c = 30000; sleep(0.3), $q->enqueue([ 'text 3', ++$c ]) while 1; }; $f->set('helpmsg', '[ ESC = exit ]'); while (1) { my $event = $f->run(50); foreach my $ret ($q->dequeue_nb(3)) { # must stringify in case numeric value $f->set($ret->[0], ''.$ret->[1]); } next unless (defined $event); last if $event eq "ESC"; } $_->exit()->join() for MCE::Hobo->list();

Entering text into an input box and have other areas of the form update automatically is quite nice. Furthermore, a worker may run an event loop and not impact the main process. There are a lot of possibilities.

Regards, Mario


In reply to STFL Terminal UI - Concurrency Demonstrations by marioroy

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.