Created
September 18, 2016 17:51
-
-
Save anonymous/6411668858edb9991ad25b1135e4b56d to your computer and use it in GitHub Desktop.
Custom sdl2.ext.System using attrs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import attr | |
import sdl2.error | |
import sdl2.sdlttf | |
import sdl2.pixels | |
import sdl2.render | |
import sdl2.ext | |
from attr.validators import instance_of | |
class SDLError(Exception): | |
""" | |
This exception indicates that there was an issue with the SDL2 library. | |
""" | |
def __init__(self, msg=None): | |
super(SDLError, self).__init__() | |
if msg is None: | |
self.msg = sdl2.error.SDL_GetError() | |
else: | |
self.msg = msg | |
def __str__(self): | |
return repr(self.msg) | |
class SDLTTFError(Exception): | |
""" | |
This exception indicates that there was an issue with SDL2 TTF. | |
""" | |
def __init__(self, msg=None): | |
super(SDLTTFError, self).__init__() | |
if msg is None: | |
self.msg = sdl2.sdlttf.TTF_GetError() | |
else: | |
self.msg = msg | |
def __str__(self): | |
return repr(self.msg) | |
@attr.s(slots=True) | |
class Sprite(object): | |
x = attr.ib(validator=instance_of(int)) | |
y = attr.ib(validator=instance_of(int)) | |
_width = attr.ib(validator=instance_of(int)) | |
_height = attr.ib(validator=instance_of(int)) | |
_depth = attr.ib(validator=instance_of(int)) | |
_renderer = attr.ib(default=None) | |
_surface = attr.ib(default=None) | |
_texture = attr.ib(default=None) | |
@property | |
def position(self): | |
""" | |
The position of the top-left corner of the Sprite | |
:return: | |
""" | |
return self.x, self.y | |
@position.setter | |
def position(self, value): | |
""" | |
Set position of the Sprite using its top-left corner. | |
:param value: | |
:return: | |
""" | |
self.x, self.y = value | |
@property | |
def shape(self): | |
""" | |
Return the size of the Sprite as tuple. | |
:return: | |
""" | |
return self._width, self._height | |
@property | |
def depth(self): | |
""" | |
Return the render depth of the Sprite. | |
:return: | |
""" | |
return self._depth | |
@depth.setter | |
def depth(self, value): | |
""" | |
Set the render depth. | |
:param value: | |
:return: | |
""" | |
self._depth = value | |
@property | |
def surface(self): | |
return self._surface | |
@property | |
def texture(self): | |
return self._texture | |
@texture.setter | |
def texture(self, value): | |
if self._texture is not None: | |
sdl2.render.SDL_DestroyTexture(self._texture) | |
self._texture = value | |
@texture.deleter | |
def texture(self): | |
if self._texture is not None: | |
sdl2.render.SDL_DestroyTexture(self._texture) | |
@classmethod | |
def create(cls, position, shape, depth=0, | |
renderer=None, pixel_format=sdl2.pixels.SDL_PIXELFORMAT_RGBA8888, | |
access=sdl2.render.SDL_TEXTUREACCESS_STATIC, bpp=32, masks=(0, 0, 0, 0)): | |
if renderer is not None: | |
if isinstance(renderer, sdl2.render.SDL_Renderer): | |
sdl_renderer = renderer | |
else: | |
sdl_renderer = renderer.renderer | |
tex = sdl2.render.SDL_CreateTexture( | |
sdl_renderer, pixel_format, access, shape[0], shape[1] | |
) | |
if tex is None: | |
raise SDLError() | |
return cls( | |
position[0], position[1], shape[0], shape[1], depth, | |
texture=tex.contents | |
) | |
else: | |
surf = sdl2.surface.SDL_CreateRGBSurface( | |
0, shape[0], shape[1], bpp, *masks | |
) | |
if surf is None: | |
raise SDLError() | |
return cls( | |
position[0], position[1], shape[0], shape[1], depth, | |
surface=surf.contents | |
) | |
def __del__(self): | |
""" | |
Frees the resources bound to the sprite. | |
:return: | |
""" | |
if self._surface is not None: | |
sdl2.surface.SDL_FreeSurface(self._surface) | |
self._surface = None | |
if self._texture is not None: | |
sdl2.render.SDL_DestroyTexture(self._texture) | |
self._texture = None | |
def main(): | |
# Initialise SDL2 and SDL2-TTF | |
sdl2.ext.init() | |
if sdl2.sdlttf.TTF_Init() != 0: | |
raise SDLTTFError() | |
try: | |
test_text = "Test string\nWith line breaks." | |
font_color = sdl2.pixels.SDL_Color(0xff, 0xff, 0xff, 0xff) | |
font_size = 10 | |
font = sdl2.sdlttf.TTF_OpenFont("Courier New.ttf".encode("utf-8"), font_size) | |
renderer = sdl2.render.SDL_Renderer() | |
sprite = Sprite.create((0, 0), (100, 100), renderer=renderer) | |
if font is None: | |
raise SDLTTFError() | |
if len(test_text) > 0: | |
txt_surface = sdl2.sdlttf.TTF_RenderUTF8_Blended( | |
font, test_text.encode("utf-8"), font_color | |
) | |
if txt_surface is None: | |
raise SDLTTFError() | |
txt_texture = sdl2.render.SDL_CreateTextureFromSurface( | |
renderer, txt_surface | |
) | |
if txt_texture is None: | |
raise SDLError() | |
sdl2.surface.SDL_FreeSurface(txt_surface.contents) | |
sprite.texture = txt_texture.contents | |
finally: | |
# Close down SDL2 | |
sdl2.ext.quit() | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment