Coverage for Hud.py: 18%
88 statements
« prev ^ index » next coverage.py v7.6.3, created at 2024-10-14 11:07 +0000
« prev ^ index » next coverage.py v7.6.3, created at 2024-10-14 11:07 +0000
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3"""Hud.py
5Create and manage the hud overlays.
6"""
7# Copyright 2008-2012 Ray E. Barker
9#
10# This program is free software; you can redistribute it and/or modify
11# it under the terms of the GNU General Public License as published by
12# the Free Software Foundation; either version 2 of the License, or
13# (at your option) any later version.
14#
15# This program is distributed in the hope that it will be useful,
16# but WITHOUT ANY WARRANTY; without even the implied warranty of
17# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18# GNU General Public License for more details.
19#
20# You should have received a copy of the GNU General Public License
21# along with this program; if not, write to the Free Software
22# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24########################################################################
25# todo
28# import L10n
29# _ = L10n.get_translation()
31# Standard Library modules
32import logging
33import copy
35# FreePokerTools modules
36import Database
37import Hand
39# logging has been set up in fpdb.py or HUD_main.py, use their settings:
40log = logging.getLogger("hud")
43def importName(module_name, name):
44 """Import a named object 'name' from module 'module_name'."""
45 # Recipe 16.3 in the Python Cookbook, 2nd ed. Thanks!!!!
47 try:
48 module = __import__(module_name, globals(), locals(), [name])
49 except Exception as e:
50 log.error("Could not load hud module %s: %s" % (module_name, e))
51 return None
52 return getattr(module, name)
55class Hud(object):
56 def __init__(self, parent, table, max, poker_game, game_type, config):
57 # __init__ is (now) intended to be called from the stdin thread, so it
58 # must not touch the gui
59 # if parent is None: # running from cli .. # fixme dont think this is working as expected
60 # self.parent = self
61 # else:
62 # self.parent = parent
63 # print "parent", parent
64 self.parent = parent
65 self.table = table
66 self.config = config
67 self.db_hud_connection = None
68 self.poker_game = poker_game
69 self.game_type = game_type # (ring|tour)
70 self.max = max
71 self.type = game_type
72 self.cards = None
73 self.site = table.site
74 self.hud_params = dict.copy(parent.hud_params) # we must dict.copy a fresh hud_params dict
75 # because each aux hud can control local hud param
76 # settings. Simply assigning the dictionary does not
77 # create a local/discrete version of the dictionary,
78 # so the different hud-windows get cross-contaminated
79 self.aux_windows = []
81 self.site_parameters = config.get_site_parameters(self.table.site)
82 self.supported_games_parameters = config.get_supported_games_parameters(self.poker_game, self.game_type)
83 self.layout_set = config.get_layout(self.table.site, self.game_type)
85 # Just throw error and die if any serious config issues are discovered
86 if self.supported_games_parameters is None:
87 log.error(("No <game_stat_set> found for %s games for type %s.\n") % (self.poker_game, self.game_type))
88 return
90 if self.layout_set is None:
91 log.error(("No layout found for %s games for site %s.\n") % (self.game_type, self.table.site))
92 return
94 if self.max not in self.layout_set.layout:
95 log.error(
96 ("No layout found for %d-max %s games for site %s.\n") % (self.max, self.game_type, self.table.site)
97 )
98 return
99 else:
100 self.layout = copy.deepcopy(
101 self.layout_set.layout[self.max]
102 ) # deepcopy required here, because self.layout is used
103 # to propagate block moves from hud to mucked display
104 # (needed because there is only 1 layout for all aux)
105 #
106 # if we didn't deepcopy, self.layout would be shared
107 # amongst all open huds - this is fine until one of the
108 # huds does a resize, and then we have a total mess to
109 # understand how a single block move on a resized screen
110 # should be propagated to other tables of different sizes
112 # if there are AUX windows configured, set them up
113 if not self.supported_games_parameters["aux"] == [""]:
114 for aux in self.supported_games_parameters["aux"].split(","):
115 aux = aux.strip() # remove leading/trailing spaces
116 aux_params = config.get_aux_parameters(aux)
117 my_import = importName(aux_params["module"], aux_params["class"])
118 if my_import is None:
119 continue
120 # The main action happening below !!!
121 # the module/class is instantiated and is fed the config
122 # and aux_params. Normally this is ultimately inherited
123 # at Mucked.Aux_seats() for a hud aux
124 #
125 # The instatiated aux object is recorded in the
126 # self.aux_windows list in this module
127 #
128 # Subsequent updates to the aux's are controlled by
129 # hud_main.pyw
130 #
131 self.aux_windows.append(my_import(self, config, aux_params))
133 self.creation_attrs = None
135 def move_table_position(self):
136 pass
138 def kill(self, *args):
139 # kill all stat_windows, popups and aux_windows in this HUD
140 # heap dead, burnt bodies, blood 'n guts, veins between my teeth
141 # kill all aux windows
142 for aux in self.aux_windows:
143 aux.destroy()
144 self.aux_windows = []
146 def resize_windows(self):
147 # resize self.layout object; this will then be picked-up
148 # by all attached aux's when called by hud_main.idle_update
150 x_scale = 1.0 * self.table.width / self.layout.width
151 y_scale = 1.0 * self.table.height / self.layout.height
153 for i in list(range(1, self.max + 1)):
154 if self.layout.location[i]:
155 self.layout.location[i] = (
156 (int(self.layout.location[i][0] * x_scale)),
157 (int(self.layout.location[i][1] * y_scale)),
158 )
160 self.layout.common = (int(self.layout.common[0] * x_scale), int(self.layout.common[1] * y_scale))
162 self.layout.width = self.table.width
163 self.layout.height = self.table.height
165 def reposition_windows(self, *args):
166 pass
168 def save_layout(self, *args):
169 # ask each aux to save its layout back to the config object
170 [aux.save_layout() for aux in self.aux_windows]
171 # write the layouts back to the HUD_config
172 self.config.save()
174 def create(self, hand, config, stat_dict):
175 # update this hud, to the stats and players as of "hand"
176 # hand is the hand id of the most recent hand played at this table
178 self.stat_dict = stat_dict # stat_dict from HUD_main.read_stdin is mapped here
179 # the db_connection created in HUD_Main is NOT available to the
180 # hud.py and aux handlers, so create a fresh connection in this class
181 # if the db connection is made in __init__, then the sqlite db threading will fail
182 # so the db connection is made here instead.
183 if self.db_hud_connection is None:
184 self.db_hud_connection = Database.Database(self.config)
185 self.cards = self.get_cards(hand)
186 self.db_hud_connection = Database.Database(self.config)
187 # Load a hand instance (factory will load correct type for this hand)
188 self.hand_instance = Hand.hand_factory(hand, config, self.db_hud_connection)
189 self.db_hud_connection.connection.rollback()
190 log.info(("Creating hud from hand ") + str(hand))
191 print((("Creating hud from hand ") + str(hand)))
193 def update(self, hand, config):
194 # re-load a hand instance (factory will load correct type for this hand)
195 self.hand_instance = Hand.hand_factory(hand, config, self.db_hud_connection)
196 log.debug("hud update after hand_factory")
197 self.db_hud_connection.connection.rollback()
199 def get_cards(self, hand):
200 cards = self.db_hud_connection.get_cards(hand)
201 if self.poker_game in ["holdem", "omahahi", "omahahilo"]:
202 comm_cards = self.db_hud_connection.get_common_cards(hand)
203 cards["common"] = comm_cards["common"]
204 return cards