use warnings;
use strict;
use Storable;
use Storable qw(nstore retrieve);
use threads;
use threads::shared;
use Data::Dumper;
use Mozilla::CA;
use LWP::UserAgent;
use HTTP::Cookies;
use XML::Tiny;
use YAML qw(DumpFile LoadFile);
use Tkx;
Tkx::package_require("tile");
use constant DebugTrace => 0;
my @defaultFG = (-fg=>'#509AC8');
my @defaultBG = (-bg=>'#142029');
my @defaultBBG = (-bg=>'#0C1319');
my %statusColors = (Idle => '#008000',
Ready => '#808000',
Processing => '#FF8000',
'On Hold' => '#FF0000',
'Invalid Game' => '#808080',
'Invalid Mod' => '#808080',
default=>'#FFFFFF');
my @gameListRows = ();
my $sharedVars = {}; share($sharedVars);
$sharedVars->{status} = 'Initializing Autohost';
my $infohash = {}; share($infohash);
$sharedVars->{gameInfo} = $infohash;
# Global gui elements
my $mw;
my $gameListFrame;
my $statusLabel;
# Global PBW's filesize restriction
my $maxFileSize = 20e6;
$|=1;
# Init gui or die, before starting the processing thread.
initGUI() or die "Can't initialize GUI\n";
# Processing thread will clear this if it starts successfully.
$sharedVars->{fatalReason} = 'Processing thread failed to initialize';
# Fire and forget the processing thread
my $pthread = threads->new(\&processingThread);
$pthread->detach();
# Sleep to give processing thread time to start and clear fatalReason
sleep 2;
# Do the gui
updateGameRows();
Tkx::MainLoop();
So, what I did there was:
- Set up all shared variables
- Create the basic window and elements
- Spawn a child thread to do whatever and update the shared vars
- Use the parent to run the GUI, with a regular polling of the shared variables every 1/2 second.
Just in case, I made the gui elements only touch local vars; there are local copies of the shared variables before looping over them and such.
Warning: I'm not sure how safe all that really is, but I've been using it in a non-critical app with a very low rate of change for the shared values. It hasn't yet crashed or done anything weird for the last 6 months. YMMV |