comparison orpg/mapper/images.py @ 0:4385a7d0efd1 grumpy-goblin

Deleted and repushed it with the 'grumpy-goblin' branch. I forgot a y
author sirebral
date Tue, 14 Jul 2009 16:41:58 -0500
parents
children d5e81dac98ff
comparison
equal deleted inserted replaced
-1:000000000000 0:4385a7d0efd1
1 # Copyright (C) 2000-2001 The OpenRPG Project
2 #
3 # openrpg-dev@lists.sourceforge.net
4 #
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 2 of the License, or
8 # (at your option) any later version.
9 #
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 # --
19 #
20 # File: mapper/images.py
21 # Author: OpenRPG
22 # Maintainer:
23 # Version:
24 # $Id: images.py,v 1.21 2007/12/11 04:07:15 digitalxero Exp $
25 #
26 # Description:
27 #
28 __version__ = "$Id: images.py,v 1.21 2007/12/11 04:07:15 digitalxero Exp $"
29
30 import urllib
31 import Queue
32 import thread
33 from threading import Lock
34 import time
35 from orpg.orpg_wx import *
36 from orpg.orpgCore import *
37
38 def singleton(cls):
39 instances = {}
40 def getinstance():
41 if cls not in instances:
42 instances[cls] = cls()
43 return instances[cls]
44 return getinstance()
45
46 class ImageHandlerClass(object):
47 __cache = {}
48 __fetching = {}
49 __queue = Queue.Queue(0)
50 __lock = Lock()
51
52 def load(self, path, image_type, imageId):
53 # Load an image, with a intermideary fetching image shown while it loads in a background thread
54 if self.__cache.has_key(path):
55 return wx.ImageFromMime(self.__cache[path][1], self.__cache[path][2]).ConvertToBitmap()
56 if not self.__fetching.has_key(path):
57 self.__fetching[path] = True
58 #Start Image Loading Thread
59 thread.start_new_thread(self.__loadThread, (path, image_type, imageId))
60 else:
61 if self.__fetching[path] is True:
62 thread.start_new_thread(self.__loadCacheThread, (path, image_type, imageId))
63 return wx.Bitmap(open_rpg.get_component("dir_struct")["icon"] + "fetching.png", wx.BITMAP_TYPE_PNG)
64
65 def directLoad(self, path):
66 # Directly load an image, no threads
67 if self.__cache.has_key(path):
68 return wx.ImageFromMime(self.__cache[path][1], self.__cache[path][2]).ConvertToBitmap()
69 uriPath = urllib.unquote(path)
70 try:
71 d = urllib.urlretrieve(uriPath)
72 # We have to make sure that not only did we fetch something, but that
73 # it was an image that we got back.
74 if d[0] and d[1].getmaintype() == "image":
75 self.__cache[path] = (path, d[0], d[1].gettype(), None)
76 return wx.ImageFromMime(self.__cache[path][1], self.__cache[path][2]).ConvertToBitmap()
77 else:
78 open_rpg.get_component('log').log("Image refused to load or URI did not reference a valid image: " + path, ORPG_GENERAL, True)
79 return None
80 except IOError:
81 open_rpg.get_component('log').log("Unable to resolve/open the specified URI; image was NOT loaded: " + path, ORPG_GENERAL, True)
82 return None
83
84 def cleanCache(self):
85 # Shrinks the Cache down to the proper size
86 try:
87 cacheSize = int(open_rpg.get_component('settings').get_setting("ImageCacheSize"))
88 except:
89 cacheSize = 32
90 cache = self.__cache.keys()
91 cache.sort()
92 for key in cache[cacheSize:]:
93 del self.__cache[key]
94
95 def flushCache(self):
96 # This function will flush all images contained within the image cache.
97 self.__lock.acquire()
98 try:
99 keyList = self.__cache.keys()
100 for key in keyList:
101 del self.__cache[key]
102 finally:
103 self.__lock.release()
104 urllib.urlcleanup()
105
106 #Private Methods
107 def __loadThread(self, path, image_type, imageId):
108 uriPath = urllib.unquote(path)
109 self.__lock.acquire()
110 try:
111 d = urllib.urlretrieve(uriPath)
112 # We have to make sure that not only did we fetch something, but that
113 # it was an image that we got back.
114 if d[0] and d[1].getmaintype() == "image":
115 self.__cache[path] = (path, d[0], d[1].gettype(), imageId)
116 self.__queue.put((self.__cache[path], image_type, imageId))
117 if self.__fetching.has_key(path):
118 del self.__fetching[path]
119 else:
120 open_rpg.get_component('log').log("Image refused to load or URI did not reference a valid image: " + path, ORPG_GENERAL, True)
121 self.__fetching[path] = False
122 except IOError:
123 self.__fetching[path] = False
124 open_rpg.get_component('log').log("Unable to resolve/open the specified URI; image was NOT laoded: " + path, ORPG_GENERAL, True)
125 finally:
126 self.__lock.release()
127
128 def __loadCacheThread(self, path, image_type, imageId):
129 try:
130 st = time.time()
131 while self.__fetching.has_key(path) and self.__fetching[path] is not False:
132 time.sleep(0.025)
133 if (time.time()-st) > 120:
134 open_rpg.get_component('log').log("Timeout: " + path, ORPG_GENERAL, True)
135 break
136 except:
137 self.__fetching[path] = False
138 open_rpg.get_component('log').log("Unable to resolve/open the specified URI; image was NOT loaded: " + path, ORPG_GENERAL, True)
139 return
140 self.__lock.acquire()
141 try:
142 open_rpg.get_component('log').log("Adding Image to Queue from Cache: " + str(self.__cache[path]), ORPG_DEBUG)
143 self.__queue.put((self.__cache[path], image_type, imageId))
144 finally:
145 self.__lock.release()
146
147 #Property Methods
148 def _getCache(self):
149 return self.__cache
150
151 def _getQueue(self):
152 return self.__queue
153
154 #Properties
155 Cache = property(_getCache)
156 Queue = property(_getQueue)
157
158 ImageHandler = singleton(ImageHandlerClass)