comparison orpg/mapper/images.py @ 71:449a8900f9ac ornery-dev

Code refining almost completed, for this round. Some included files are still in need of some clean up, but this is test worthy.
author sirebral
date Thu, 20 Aug 2009 03:00:39 -0500
parents c54768cffbd4
children 37a11fea3304
comparison
equal deleted inserted replaced
70:52a5fa913008 71:449a8900f9ac
31 import Queue 31 import Queue
32 import thread 32 import thread
33 from threading import Lock 33 from threading import Lock
34 import time 34 import time
35 from orpg.orpg_wx import * 35 from orpg.orpg_wx import *
36 from orpg.orpgCore import * 36 from orpg.orpgCore import component
37 from orpg.dirpath import dir_struct 37 from orpg.dirpath import dir_struct
38 from orpg.tools.orpg_log import logger
38 39
39 def singleton(cls): 40 def singleton(cls):
40 instances = {} 41 instances = {}
41 def getinstance(): 42 def getinstance():
42 if cls not in instances: 43 if cls not in instances:
49 __fetching = {} 50 __fetching = {}
50 __queue = Queue.Queue(0) 51 __queue = Queue.Queue(0)
51 __lock = Lock() 52 __lock = Lock()
52 53
53 def load(self, path, image_type, imageId): 54 def load(self, path, image_type, imageId):
54 # Load an image, with a intermideary fetching image shown while it loads in a background thread 55 """Load an image, with a intermideary fetching image shown while it loads in a background thread"""
55 if self.__cache.has_key(path): return wx.ImageFromMime(self.__cache[path][1], 56 if self.__cache.has_key(path): return wx.ImageFromMime(self.__cache[path][1],
56 self.__cache[path][2]).ConvertToBitmap() 57 self.__cache[path][2]).ConvertToBitmap()
57 if not self.__fetching.has_key(path): 58 if not self.__fetching.has_key(path):
58 self.__fetching[path] = True 59 self.__fetching[path] = True
59 #Start Image Loading Thread 60 """Start Image Loading Thread"""
60 thread.start_new_thread(self.__loadThread, (path, image_type, imageId)) 61 thread.start_new_thread(self.__loadThread, (path, image_type, imageId))
61 else: 62 else:
62 if self.__fetching[path] is True: thread.start_new_thread(self.__loadCacheThread, (path, image_type, imageId)) 63 if self.__fetching[path] is True: thread.start_new_thread(self.__loadCacheThread, (path, image_type, imageId))
63 return wx.Bitmap(dir_struct["icon"] + "fetching.png", wx.BITMAP_TYPE_PNG) 64 return wx.Bitmap(dir_struct["icon"] + "fetching.png", wx.BITMAP_TYPE_PNG)
64 65
65 def directLoad(self, path): 66 def directLoad(self, path):
66 # Directly load an image, no threads 67 """Directly load an image, no threads"""
67 if self.__cache.has_key(path): return wx.ImageFromMime(self.__cache[path][1], 68 if self.__cache.has_key(path): return wx.ImageFromMime(self.__cache[path][1],
68 self.__cache[path][2]).ConvertToBitmap() 69 self.__cache[path][2]).ConvertToBitmap()
69 uriPath = urllib.unquote(path) 70 uriPath = urllib.unquote(path)
70 try: 71 try:
71 d = urllib.urlretrieve(uriPath) 72 d = urllib.urlretrieve(uriPath)
72 # We have to make sure that not only did we fetch something, but that 73 """We have to make sure that not only did we fetch something, but that
73 # it was an image that we got back. 74 it was an image that we got back."""
74 if d[0] and d[1].getmaintype() == "image": 75 if d[0] and d[1].getmaintype() == "image":
75 self.__cache[path] = (path, d[0], d[1].gettype(), None) 76 self.__cache[path] = (path, d[0], d[1].gettype(), None)
76 return wx.ImageFromMime(self.__cache[path][1], self.__cache[path][2]).ConvertToBitmap() 77 return wx.ImageFromMime(self.__cache[path][1], self.__cache[path][2]).ConvertToBitmap()
77 else: 78 else:
78 component.get('log').log("Image refused to load or URI did not reference a valid image: " + path, 79 logger.general("Image refused to load or URI did not reference a valid image: " + path) ##logger.general
79 ORPG_GENERAL, True)
80 return None 80 return None
81 except IOError: 81 except IOError:
82 component.get('log').log("Unable to resolve/open the specified URI; image was NOT loaded: " + path, 82 logger.general("Unable to resolve/open the specified URI; image was NOT loaded: " + path) ##logger.general
83 ORPG_GENERAL, True)
84 return None 83 return None
85 84
86 def cleanCache(self): 85 def cleanCache(self):
87 # Shrinks the Cache down to the proper size 86 """Shrinks the Cache down to the proper size"""
88 try: cacheSize = int(component.get('settings').get_setting("ImageCacheSize")) 87 try: cacheSize = int(component.get('settings').get_setting("ImageCacheSize"))
89 except: cacheSize = 32 88 except: cacheSize = 32
90 cache = self.__cache.keys() 89 cache = self.__cache.keys()
91 cache.sort() 90 cache.sort()
92 for key in cache[cacheSize:]: del self.__cache[key] 91 for key in cache[cacheSize:]: del self.__cache[key]
93 92
94 def flushCache(self): 93 def flushCache(self):
95 # This function will flush all images contained within the image cache. 94 """This function will flush all images contained within the image cache."""
96 self.__lock.acquire() 95 self.__lock.acquire()
97 try: 96 try:
98 keyList = self.__cache.keys() 97 keyList = self.__cache.keys()
99 for key in keyList: del self.__cache[key] 98 for key in keyList: del self.__cache[key]
100 finally: self.__lock.release() 99 finally: self.__lock.release()
101 urllib.urlcleanup() 100 urllib.urlcleanup()
102 101
103 #Private Methods 102 """Private Methods"""
104 def __loadThread(self, path, image_type, imageId): 103 def __loadThread(self, path, image_type, imageId):
105 uriPath = urllib.unquote(path) 104 uriPath = urllib.unquote(path)
106 self.__lock.acquire() 105 self.__lock.acquire()
107 try: 106 try:
108 d = urllib.urlretrieve(uriPath) 107 d = urllib.urlretrieve(uriPath)
109 # We have to make sure that not only did we fetch something, but that 108 """We have to make sure that not only did we fetch something, but that
110 # it was an image that we got back. 109 it was an image that we got back."""
111 if d[0] and d[1].getmaintype() == "image": 110 if d[0] and d[1].getmaintype() == "image":
112 self.__cache[path] = (path, d[0], d[1].gettype(), imageId) 111 self.__cache[path] = (path, d[0], d[1].gettype(), imageId)
113 self.__queue.put((self.__cache[path], image_type, imageId)) 112 self.__queue.put((self.__cache[path], image_type, imageId))
114 if self.__fetching.has_key(path): del self.__fetching[path] 113 if self.__fetching.has_key(path): self.__fetching[path] = False #Fix for failed multi-load?
115 else: 114 else:
116 component.get('log').log("Image refused to load or URI did not reference a valid image: " + path, 115 logger.general("Image refused to load or URI did not reference a valid image: " + path) ##logger.general
117 ORPG_GENERAL, True)
118 del self.__fetching[path] 116 del self.__fetching[path]
119 except IOError: 117 except IOError:
120 del self.__fetching[path] 118 del self.__fetching[path]
121 component.get('log').log("Unable to resolve/open the specified URI; image was NOT laoded: " + path, 119 logger.general("Unable to resolve/open the specified URI; image was NOT laoded: " + path) ##logger.general
122 ORPG_GENERAL, True)
123 finally: self.__lock.release() 120 finally: self.__lock.release()
124 121
125 def __loadCacheThread(self, path, image_type, imageId): 122 def __loadCacheThread(self, path, image_type, imageId):
126 if self.__cache.has_key(path): 123 if self.__cache.has_key(path):
127 try: 124 try:
128 st = time.time() 125 st = time.time()
129 while self.__fetching.has_key(path) and self.__fetching[path] is not False: 126 while self.__fetching.has_key(path) and self.__fetching[path] is not False:
130 time.sleep(0.025) 127 time.sleep(0.025)
131 if (time.time()-st) > 120: 128 if (time.time()-st) > 120:
132 component.get('log').log("Timeout: " + path, ORPG_GENERAL, True) 129 logger.general("Timeout: " + path)
133 break 130 break
134 except: 131 except:
135 del self.__fetching[path] 132 del self.__fetching[path]
136 component.get('log').log("Unable to resolve/open the specified URI; image was NOT loaded: " + path, ORPG_GENERAL, True) 133 logger.general("Unable to resolve/open the specified URI; image was NOT loaded: " + path) ##logger.general
137 return 134 return
138 self.__lock.acquire() 135 self.__lock.acquire()
139 try: 136 try:
140 component.get('log').log("Adding Image to Queue from Cache: " + str(self.__cache[path]), ORPG_DEBUG) 137 logger.debug("Adding Image to Queue from Cache: " + str(self.__cache[path]))
141 self.__queue.put((self.__cache[path], image_type, imageId)) 138 self.__queue.put((self.__cache[path], image_type, imageId))
142 finally: self.__lock.release() 139 finally: self.__lock.release()
143 140
144 #Property Methods 141 """Property Methods"""
145 def _getCache(self): 142 def _getCache(self):
146 return self.__cache 143 return self.__cache
147 144
148 def _getQueue(self): 145 def _getQueue(self):
149 return self.__queue 146 return self.__queue
150 147
151 #Properties 148 """Properties"""
152 Cache = property(_getCache) 149 Cache = property(_getCache)
153 Queue = property(_getQueue) 150 Queue = property(_getQueue)
154 151
155 ImageHandler = singleton(ImageHandlerClass) 152 ImageHandler = singleton(ImageHandlerClass)