From 2ebb026543b72d84560903ad4c1a6d61f850965f Mon Sep 17 00:00:00 2001 From: Ray Date: Sat, 21 Feb 2009 18:19:49 -0500 Subject: [PATCH] Cleanup in HUD_main and HUD.py to simplify. HUD_run_me no longer needed but not removed. --- pyfpdb/GuiAutoImport.py | 4 +- pyfpdb/HUD_main.py | 237 ++++++++++++++++++++-------------------- pyfpdb/Hud.py | 5 +- 3 files changed, 126 insertions(+), 120 deletions(-) diff --git a/pyfpdb/GuiAutoImport.py b/pyfpdb/GuiAutoImport.py index 38535ad1..ceb3da0d 100644 --- a/pyfpdb/GuiAutoImport.py +++ b/pyfpdb/GuiAutoImport.py @@ -128,12 +128,12 @@ class GuiAutoImport (threading.Thread): widget.set_label(u'Stop Autoimport') if self.pipe_to_hud is None: if os.name == 'nt': - command = "python HUD_run_me.py" + " %s" % (self.database) + command = "python HUD_main.py" + " %s" % (self.database) bs = 0 # windows is not happy with line buffing here self.pipe_to_hud = subprocess.Popen(command, bufsize = bs, stdin = subprocess.PIPE, universal_newlines=True) else: - command = self.config.execution_path('HUD_run_me.py') + command = self.config.execution_path('HUD_main.py') bs = 1 self.pipe_to_hud = subprocess.Popen((command, self.database), bufsize = bs, stdin = subprocess.PIPE, universal_newlines=True) diff --git a/pyfpdb/HUD_main.py b/pyfpdb/HUD_main.py index af7e4e9f..9df7efad 100755 --- a/pyfpdb/HUD_main.py +++ b/pyfpdb/HUD_main.py @@ -26,7 +26,6 @@ Main for FreePokerTools HUD. # to do hud to echo, but ignore non numbers # to do no stat window for hero # to do things to add to config.xml -# to do font and size # Standard Library modules import sys @@ -47,141 +46,147 @@ import Database import Tables import Hud -# global dict for keeping the huds -hud_dict = {} -eb = 0 # our former event-box +class HUD_main(object): + """A main() object to own both the read_stdin thread and the gui.""" +# This class mainly provides state for controlling the multiple HUDs. -db_connection = 0; -config = 0; + def __init__(self, db_name = 'fpdb'): + self.db_name = db_name + self.config = Configuration.Config() + self.hud_dict = {} -def destroy(*args): # call back for terminating the main eventloop - gtk.main_quit() +# a thread to read stdin + gobject.threads_init() # this is required + thread.start_new_thread(self.read_stdin, ()) # starts the thread -def create_HUD(new_hand_id, table, db_name, table_name, max, poker_game, db_connection, config, stat_dict): - global hud_dict, eb +# a main window + self.main_window = gtk.Window() + self.main_window.connect("destroy", self.destroy) + self.vb = gtk.VBox() + self.label = gtk.Label('Closing this window will exit from the HUD.') + self.vb.add(self.label) + self.main_window.add(self.vb) + self.main_window.set_title("HUD Main Window") + self.main_window.show_all() + + def destroy(*args): # call back for terminating the main eventloop + gtk.main_quit() - def idle_func(): - global hud_dict, eb + def create_HUD(self, new_hand_id, table, table_name, max, poker_game, is_tournament, stat_dict): - gtk.gdk.threads_enter() - try: - newlabel = gtk.Label(table.site + " - " + table_name) - eb.add(newlabel) - newlabel.show() - - hud_dict[table_name] = Hud.Hud(table, max, poker_game, config, db_connection) - hud_dict[table_name].tablehudlabel = newlabel - hud_dict[table_name].create(new_hand_id, config) - for m in hud_dict[table_name].aux_windows: - m.update_data(new_hand_id, db_connection) - m.update_gui(new_hand_id) - hud_dict[table_name].update(new_hand_id, config, stat_dict) - hud_dict[table_name].reposition_windows() - return False - finally: - gtk.gdk.threads_leave() - gobject.idle_add(idle_func) - -def update_HUD(new_hand_id, table_name, config, stat_dict): - global hud_dict - def idle_func(): - gtk.gdk.threads_enter() - try: - hud_dict[table_name].update(new_hand_id, config, stat_dict) - for m in hud_dict[table_name].aux_windows: - m.update_gui(new_hand_id) - return False - finally: - gtk.gdk.threads_leave() - gobject.idle_add(idle_func) - -def HUD_removed(tablename): - global hud_dict, eb - - tablename = Tables.clean_title(tablename) - # TODO: There's a potential problem here somewhere, that this hacks around .. the table_name as being passed to HUD_create is cleaned, - # but the table.name as being passed here is not cleaned. I don't know why. -eric - if tablename in hud_dict and hud_dict[tablename].deleted: - eb.remove(hud_dict[tablename].tablehudlabel) - del hud_dict[tablename] - return False - - return True - -def read_stdin(): # This is the thread function - global hud_dict, eb - - db_connection = Database.Database(config, db_name, 'temp') - tourny_finder = re.compile('(\d+) (\d+)') - - while True: # wait for a new hand number on stdin - new_hand_id = sys.stdin.readline() - new_hand_id = string.rstrip(new_hand_id) - if new_hand_id == "": # blank line means quit - destroy() - break # this thread is not always killed immediately with gtk.main_quit() - -# get basic info about the new hand from the db - (table_name, max, poker_game) = db_connection.get_table_name(new_hand_id) - -# find out if this hand is from a tournament - is_tournament = False - (tour_number, tab_number) = (0, 0) - mat_obj = tourny_finder.search(table_name) - if mat_obj: - is_tournament = True - (tour_number, tab_number) = mat_obj.group(1, 2) + def idle_func(): - stat_dict = db_connection.get_stats_from_hand(new_hand_id) + gtk.gdk.threads_enter() + try: + newlabel = gtk.Label(table.site + " - " + table_name) + self.vb.add(newlabel) + newlabel.show() + + self.hud_dict[table_name] = Hud.Hud(self, table, max, poker_game, self.config, self.db_connection) + self.hud_dict[table_name].tablehudlabel = newlabel + self.hud_dict[table_name].create(new_hand_id, self.config) + for m in self.hud_dict[table_name].aux_windows: + m.update_data(new_hand_id, self.db_connection) + m.update_gui(new_hand_id) + self.hud_dict[table_name].update(new_hand_id, self.config, stat_dict) + self.hud_dict[table_name].reposition_windows() + return False + finally: + gtk.gdk.threads_leave() + gobject.idle_add(idle_func) + + def update_HUD(self, new_hand_id, table_name, config, stat_dict): + """Update a HUD gui from inside the non-gui read_stdin thread.""" +# This is written so that only 1 thread can touch the gui--mainly +# for compatibility with Windows. This method dispatches the +# function idle_func() to be run by the gui thread, at its leisure. + def idle_func(): + gtk.gdk.threads_enter() + try: + self.hud_dict[table_name].update(new_hand_id, config, stat_dict) + for m in self.hud_dict[table_name].aux_windows: + m.update_gui(new_hand_id) + return False + finally: + gtk.gdk.threads_leave() + gobject.idle_add(idle_func) + + def HUD_removed(self, tablename): + + tablename = Tables.clean_title(tablename) + # TODO: There's a potential problem here somewhere, that this hacks around .. the table_name as being passed to HUD_create is cleaned, + # but the table.name as being passed here is not cleaned. I don't know why. -eric + if tablename in self.hud_dict and self.hud_dict[tablename].deleted: + self.vb.remove(self.hud_dict[tablename].tablehudlabel) + del self.hud_dict[tablename] + return False + + return True + + def read_stdin(self): # This is the thread function + """Do all the non-gui heavy lifting for the HUD program.""" -# if a hud for this CASH table exists, just update it - if table_name in hud_dict: -# update the data for the aux_windows - for aw in hud_dict[table_name].aux_windows: - aw.update_data(new_hand_id, db_connection) - update_HUD(new_hand_id, table_name, config, stat_dict) - -# if a hud for this TOURNAMENT table exists, just update it - elif tour_number in hud_dict: - update_HUD(new_hand_id, tour_number, config, stat_dict) - -# otherwise create a new hud - else: - if is_tournament: - tablewindow = Tables.discover_tournament_table(config, tour_number, tab_number) - if tablewindow == None: - sys.stderr.write("tournament %s, table %s not found\n" % (tour_number, tab_number)) - else: - create_HUD(new_hand_id, tablewindow, db_name, tour_number, max, poker_game, db_connection, config, stat_dict) +# This db connection is for the read_stdin thread only. It should not +# be passed to HUDs for use in the gui thread. HUD objects should not +# need their own access to the database, but should open their own +# if it is required. + self.db_connection = Database.Database(self.config, self.db_name, 'temp') + tourny_finder = re.compile('(\d+) (\d+)') + + while True: # wait for a new hand number on stdin + new_hand_id = sys.stdin.readline() + new_hand_id = string.rstrip(new_hand_id) + if new_hand_id == "": # blank line means quit + self.destroy() + break # this thread is not always killed immediately with gtk.main_quit() + +# get basic info about the new hand from the db + (table_name, max, poker_game) = self.db_connection.get_table_name(new_hand_id) + stat_dict = self.db_connection.get_stats_from_hand(new_hand_id) + +# find out if this hand is from a tournament + mat_obj = tourny_finder.search(table_name) + if mat_obj: + is_tournament = True + (tour_number, tab_number) = mat_obj.group(1, 2) + temp_key = tour_number else: - tablewindow = Tables.discover_table_by_name(config, table_name) + is_tournament = False + (tour_number, tab_number) = (0, 0) + temp_key = table_name + +# Update an existing HUD + if temp_key in self.hud_dict: + for aw in self.hud_dict[temp_key].aux_windows: + aw.update_data(new_hand_id, self.db_connection) + self.update_HUD(new_hand_id, temp_key, self.config, stat_dict) + +# Or create a new hud + else: + if is_tournament: + tablewindow = Tables.discover_tournament_table(self.config, tour_number, tab_number) + else: + tablewindow = Tables.discover_table_by_name(self.config, table_name) + if tablewindow == None: + if is_tournament: + table_name = tour_number + " " + tab_number sys.stderr.write("table name "+table_name+" not found\n") else: - create_HUD(new_hand_id, tablewindow, db_name, table_name, max, poker_game, db_connection, config, stat_dict) + self.create_HUD(new_hand_id, tablewindow, temp_key, max, poker_game, is_tournament, stat_dict) if __name__== "__main__": sys.stderr.write("HUD_main starting\n") +# database name can be passed on command line try: db_name = sys.argv[1] except: db_name = 'fpdb' sys.stderr.write("Using db name = %s\n" % (db_name)) - config = Configuration.Config() +# start the HUD_main object + hm = HUD_main(db_name = db_name) - gobject.threads_init() # this is required - thread.start_new_thread(read_stdin, ()) # starts the thread - - main_window = gtk.Window() - main_window.connect("destroy", destroy) - eb = gtk.VBox() - label = gtk.Label('Closing this window will exit from the HUD.') - eb.add(label) - main_window.add(eb) - - main_window.set_title("HUD Main Window") - main_window.show_all() - +# start the event loop gtk.main() diff --git a/pyfpdb/Hud.py b/pyfpdb/Hud.py index b1794c5d..5eb1af48 100644 --- a/pyfpdb/Hud.py +++ b/pyfpdb/Hud.py @@ -47,7 +47,8 @@ import HUD_main class Hud: - def __init__(self, table, max, poker_game, config, db_connection): + def __init__(self, parent, table, max, poker_game, config, db_connection): + self.parent = parent self.table = table self.config = config self.poker_game = poker_game @@ -175,7 +176,7 @@ class Hud: self.deleted = True self.main_window.disconnect(self.main_window.destroyhandler) # so we don't potentially infiniteloop in here, right self.main_window.destroy() - HUD_main.HUD_removed(self.table.name) + self.parent.HUD_removed(self.table.name) def kill_hud_menu(self, *args): self.main_window.destroy()