77import ctypes
88import weakref
99import array
10+ import itertools
1011
1112from . import event
1213from .__tcod import _lib , _Color , _unpackfile
1314
1415_IS_PYTHON3 = (sys .version_info [0 ] == 3 )
15- #_encoding = 'cp437 '
16+ _USE_FILL = False 'Set to True to use the libtcod fill optimization. This is actually slower than the normal mode. '
1617
1718def _format_string (string ): # still used for filepaths, and that's about it
1819 "changes string into bytes if running in python 3, for sending to ctypes"
@@ -23,7 +24,6 @@ def _format_string(string): # still used for filepaths, and that's about it
2324#def _encodeString(string):
2425# pass
2526
26-
2727def _formatChar (char ):
2828 """Prepares a single character for passing to ctypes calls, needs to return
2929 an integer but can also pass None which will keep the current character
@@ -380,19 +380,33 @@ def __init__(self, width, height):
380380 self ._as_parameter_ = _lib .TCOD_console_new (width , height )
381381 self .width = width
382382 self .height = height
383+ self ._initArrays ()
383384 self .clear ()
384-
385+
385386 @classmethod
386387 def _newConsole (cls , console ):
387388 """Make a Console instance, from a console ctype"""
388389 self = cls .__new__ (cls )
389390 self ._as_parameter_ = console
390391 self .width = _lib .TCOD_console_get_width (self )
391392 self .height = _lib .TCOD_console_get_height (self )
392- self .cursorX = self . cursorY = 0
393+ self ._initArrays ()
393394 self .clear ()
394395 return self
395396
397+ def _initArrays (self ):
398+ if not _USE_FILL :
399+ return
400+ # used for the libtcod fill optimization
401+ IntArray = ctypes .c_int * (self .width * self .height )
402+ self .chArray = IntArray ()
403+ self .fgArrays = (IntArray (),
404+ IntArray (),
405+ IntArray ())
406+ self .bgArrays = (IntArray (),
407+ IntArray (),
408+ IntArray ())
409+
396410 def __del__ (self ):
397411 """
398412 If the main console is garbage collected then the window will be closed as well
@@ -437,10 +451,18 @@ def clear(self, fgcolor=(255, 255, 255), bgcolor=(0, 0, 0)):
437451 _lib .TCOD_console_set_default_foreground (self , _formatColor (fgcolor ))
438452 _lib .TCOD_console_clear (self )
439453
440- def _setChar (self , x , y , char , fgcolor = None , bgcolor = None , bgblend = 1 ):
454+ def _setCharFill (self , x , y , char , fgcolor = None , bgcolor = None ):
455+ """An optimized version using the fill wrappers that didn't work out to be any faster"""
456+ index = x + y * self .width
457+ self .chArray [index ] = char
458+ for channel , color in zip (itertools .chain (self .fgArrays , self .bgArrays ),
459+ itertools .chain (fgcolor , bgcolor )):
460+ channel [index ] = color
461+
462+ def _setCharCall (self , x , y , char , fgcolor = None , bgcolor = None , bgblend = 1 ):
441463 """
442- Sets a character without moving the virtual cursor, this is called
443- often and is designed to be as fast as possible.
464+ Sets a character.
465+ This is called often and is designed to be as fast as possible.
444466
445467 Because of the need for speed this function will do NO TYPE CHECKING
446468 AT ALL, it's up to the drawing functions to use the functions:
@@ -453,6 +475,11 @@ def _setChar(self, x, y, char, fgcolor=None, bgcolor=None, bgblend=1):
453475 _setfore (self , x , y , fgcolor )
454476 if bgcolor is not None :
455477 _setback (self , x , y , bgcolor , bgblend )
478+
479+ if _USE_FILL :
480+ _setChar = _setCharFill
481+ else :
482+ _setChar = _setCharCall
456483
457484 def getChar (self , x , y ):
458485 """Return the character and colors of a cell as
@@ -590,15 +617,13 @@ def flush():
590617 """
591618 if not _rootinitialized :
592619 raise TDLError ('Cannot flush without first initializing with tdl.init' )
593-
594- # old hack to prevent locking up on old libtcod
595- # you can probably delete all autoflush releated stuff
596- #if event._autoflush and not event._eventsflushed:
597- # event.get()
598- #else: # do not flush events after the user starts using them
599- # event._autoflush = False
600-
601- #event._eventsflushed = False
620+
621+ if _USE_FILL :
622+ console = _rootconsole ()
623+ _lib .TCOD_console_fill_background (console , * console .bgArrays )
624+ _lib .TCOD_console_fill_foreground (console , * console .fgArrays )
625+ _lib .TCOD_console_fill_char (console , console .chArray )
626+
602627 _lib .TCOD_console_flush ()
603628
604629def setFont (path , tileWidth , tileHeight , colomn = False ,
@@ -741,5 +766,5 @@ def forceResolution(width, height):
741766 """
742767 _lib .TCOD_sys_force_fullscreen_resolution (width , height )
743768
744- __all__ = [_var for _var in locals ().keys () if _var [0 ] != '_' and _var not in ['sys' , 'os' , 'ctypes' , 'array' , 'weakref' ]]
769+ __all__ = [_var for _var in locals ().keys () if _var [0 ] != '_' and _var not in ['sys' , 'os' , 'ctypes' , 'array' , 'weakref' , 'itertools' ]]
745770__all__ += ['_MetaConsole' ] # keep this object public to show the documentation in epydoc
0 commit comments