misc.py (5032B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\carbon\client\script\util\misc.py 2 import os 3 import blue 4 import stackless 5 import sys 6 import types 7 import uthread 8 import log 9 import functools 10 11 class _ResFileRaw(object): 12 __slots__ = ['resfile', 'closed'] 13 14 def __init__(self, respath): 15 self.resfile = blue.ResFile() 16 self.resfile.OpenAlways(respath) 17 self.closed = False 18 19 def read(self, size = -1): 20 if self.closed: 21 raise ValueError('file is closed') 22 return self.resfile.Read(size) 23 24 def seek(self, offset, whence = 0): 25 if whence == 0: 26 r = self.resfile.Seek(offset) 27 elif whence == 1: 28 r = self.resfile.Seek(offset + self.file.pos) 29 elif whence == -1: 30 r = self.resfile.Seek(self.file.size - offset) 31 else: 32 raise ValueError("'whence' must be 0, 1 or -1, not %s" % whence) 33 34 def tell(self): 35 return self.resfile.pos 36 37 def close(self): 38 if not self.closed: 39 self.resfile.Close() 40 self.closed = True 41 42 43 def ResFile(respath, mode = 'rb', bufsize = -1): 44 if mode.count('b'): 45 return _ResFileRaw(respath) 46 else: 47 s = _ResFileRaw(respath).read().replace('\r\n', '\n') 48 import StringIO 49 return StringIO.StringIO(s) 50 51 52 def ResFileToCache(respath): 53 try: 54 filename = respath[respath.rfind('/') + 1:] 55 targetName = blue.paths.ResolvePath(u'cache:/Temp/') + filename 56 if not os.path.exists(targetName): 57 resFile = blue.ResFile() 58 resFile.Open(respath) 59 rawData = resFile.read() 60 resFile.close() 61 outImage = file(targetName, 'wb') 62 outImage.writelines(rawData) 63 outImage.close() 64 return targetName 65 except: 66 sys.exc_clear() 67 return '' 68 69 70 def BlueFile(bluefilename, mode = 'r', bufsize = -1): 71 filename = blue.paths.ResolvePath(bluefilename) 72 try: 73 f = file(filename, mode, bufsize) 74 except IOError: 75 f = ResFile(bluefilename, mode, bufsize) 76 sys.exc_clear() 77 78 return f 79 80 81 def DelTree(path): 82 83 def DelFiles(arg, dirname, fnames): 84 for each in fnames: 85 tmp = os.path.join(dirname, each) 86 if not os.path.isdir(tmp): 87 os.remove(tmp) 88 89 os.path.walk(path, DelFiles, None) 90 _RemoveDirs(path, 0) 91 92 93 def _RemoveDirs(path, nukebase): 94 for each in os.listdir(path): 95 _RemoveDirs(os.path.join(path, each), 1) 96 97 if nukebase: 98 os.rmdir(path) 99 100 101 def GetAttrs(obj, *names): 102 for name in names: 103 obj = getattr(obj, name, None) 104 if obj is None: 105 return 106 107 return obj 108 109 110 def HasAttrs(obj, *names): 111 for name in names: 112 if not hasattr(obj, name): 113 return False 114 obj = getattr(obj, name, None) 115 116 return True 117 118 119 def TryDel(dictOrSet, key): 120 try: 121 if isinstance(dictOrSet, set): 122 dictOrSet.remove(key) 123 else: 124 del dictOrSet[key] 125 except KeyError: 126 sys.exc_clear() 127 128 129 def Doppleganger(wrap, original): 130 return types.FunctionType(wrap.__code__, wrap.__globals__, original.__name__, closure=wrap.__closure__) 131 132 133 def Decorator(f): 134 135 @functools.wraps(f) 136 def deco(inner, *args, **kw): 137 return Doppleganger(f(inner, *args, **kw), inner) 138 139 return deco 140 141 142 Decorator = Decorator(Decorator) 143 144 def Uthreaded(f, name = None): 145 if name is None: 146 name = f.__name__ 147 148 def deco(*args, **kw): 149 uthread.worker(name, lambda : f(*args, **kw)) 150 151 return deco 152 153 154 Uthreaded = Decorator(Uthreaded) 155 156 def RunOnceMethod(fn): 157 runAlreadyName = '_run%s%sAlready' % (fn.__name__, id(fn)) 158 159 def deco(self, *args, **kw): 160 if not hasattr(self, runAlreadyName): 161 setattr(self, runAlreadyName, True) 162 fn(self, *args, **kw) 163 164 return deco 165 166 167 class Despammer: 168 169 def __init__(self, fn, delay = 0): 170 self._fn = fn 171 self._delay = delay 172 self._channel = stackless.channel() 173 uthread.worker('Despammed::%s' % self._fn.__name__, self._Receiver) 174 self._running = True 175 176 def Send(self, *args, **kw): 177 if self._running: 178 self._channel.send((args, kw)) 179 180 Send = Uthreaded(Send) 181 182 def Stop(self): 183 if self._running: 184 self._running = False 185 self._channel.send_exception(self._StopExc) 186 del self._channel 187 del self._fn 188 189 class _StopExc(Exception): 190 pass 191 192 def _Receiver(self): 193 ch = self._channel 194 while True: 195 try: 196 args, kw = ch.receive() 197 blue.pyos.synchro.SleepWallclock(self._delay) 198 while ch.balance != 0: 199 args, kw = ch.receive() 200 201 self._fn(*args, **kw) 202 except self._StopExc: 203 sys.exc_clear() 204 return 205 except Exception: 206 log.LogException() 207 sys.exc_clear()