<commit_before>#!/usr/bin/env python

'''
'''

__docformat__ = 'restructuredtext'
__version__ = '$Id$'

import math

from pyglet.gl import *
from pyglet import clock
from pyglet import event
from pyglet import graphics
from pyglet import image

class SpriteState(graphics.AbstractState):
    def __init__(self, texture, blend_src, blend_dest, parent=None):
        super(SpriteState, self).__init__(parent)
        self.texture = texture
        self.blend_src = blend_src
        self.blend_dest = blend_dest

    def set(self):
        glEnable(self.texture.target)
        glBindTexture(self.texture.target, self.texture.id)

        glPushAttrib(GL_COLOR_BUFFER_BIT)
        glEnable(GL_BLEND)
        glBlendFunc(self.blend_src, self.blend_dest)

    def unset(self):
        glPopAttrib()
        glDisable(self.texture.target)

    def __eq__(self, other):
        return (other.__class__ is self.__class__ and 
                self.parent is other.parent and 
                self.texture.target == other.texture.target and
                self.texture.id == other.texture.id and
                self.blend_src == other.blend_src and
                self.blend_dest == other.blend_dest)

    def __hash__(self):
        return hash((id(self.parent), 
                     self.texture.id, self.texture.target,
                     self.blend_src, self.blend_dest))

class Sprite(event.EventDispatcher):
    _batch = None
    _animation = None
    _rotation = 0
    _opacity = 255
    _scale = 1.0
    vertex_list = None

    def __init__(self, 
                 img, x=0, y=0, 
                 blend_src=GL_SRC_ALPHA,
                 blend_dest=GL_ONE_MINUS_SRC_ALPHA,
                 batch=None,
                 parent_state=None):

        # make sure parent_state is accompanied by a batch
        if parent_state is not None and batch is None:
            raise ValueError('parent_state requires batch rendering')

        if batch is not None:
            self._batch = batch

        self._x = x
        self._y = y

        if isinstance(img, image.Animation):
            self._animation = img
            self._frame_index = 0
            self._texture = img.frames[0].image.get_texture()
            self._next_dt = img.frames[0].delay
            clock.schedule_once(self._animate, self._next_dt)
        else:
            self._texture = img.get_texture()

        self._state = SpriteState(self._texture, blend_src, blend_dest,
                                  parent_state)
        self._create_vertex_list()

    def __del__(self):
        if self._vertex_list is not None:
            self._vertex_list.delete()

    def delete(self):
        '''Force immediate removal from video memory.  
        
        This is often necessary when using batches, as the Python garbage
        collector will not necessarily call the finalizer as soon as the
        sprite is garbage.
        '''
        if self._animation:
            clock.unschedule(self._animate)
        self._vertex_list.delete()
        self._vertex_list = None

    def _animate(self, dt):
        self._frame_index += 1
        if self._frame_index >= len(self._animation.frames):
            self.dispatch_event('on_animation_end')
            self._frame_index = 0

        frame = self._animation.frames[self._frame_index]
        self._set_texture(frame.image.get_texture())

        if frame.delay is not None:
            delay = frame.delay - (self._next_dt - dt)
            delay = min(max(0, delay), frame.delay)
            clock.schedule_once(self._animate, delay)
            self._next_dt = delay
        else:
            self.dispatch_event('on_animation_end')

    batch = property(lambda self: self._batch)

    def _get_image(self):
        if self._animation:
            return self._animation
        return self._texture

    def _set_image(self, img):
        if self._animation is not None:
            clock.unschedule(self._animate)
            self._animation = None

        if isinstance(img, image.Animation):
            self._animation = img
            self._frame_index = 0
            self._set_texture(img.frames[0].image.get_texture())
            self._next_dt = img.frames[0].delay
            clock.schedule_once(self._animate, self._next_dt)
        else:
            self._set_texture(img.get_texture())

    image = property(_get_image,
                     _set_image)

    def _set_texture(self, texture):
        if texture is not self._texture:
            self._state = SpriteState(texture, 
                                      self._state.blend_src, 
                                      self._state.blend_dest,
                                      self._state.parent)
            if self._batch is None:
                self._vertex_list.tex_coords[:] = texture.tex_coords
            else:
                self._vertex_list.delete()
                self._create_vertex_list()<commit_msg>Allow parent state change in sprite, fix texture change.<commit_after>#!/usr/bin/env python

'''
'''

__docformat__ = 'restructuredtext'
__version__ = '$Id$'

import math

from pyglet.gl import *
from pyglet import clock
from pyglet import event
from pyglet import graphics
from pyglet import image

class SpriteState(graphics.AbstractState):
    def __init__(self, texture, blend_src, blend_dest, parent=None):
        super(SpriteState, self).__init__(parent)
        self.texture = texture
        self.blend_src = blend_src
        self.blend_dest = blend_dest

    def set(self):
        glEnable(self.texture.target)
        glBindTexture(self.texture.target, self.texture.id)

        glPushAttrib(GL_COLOR_BUFFER_BIT)
        glEnable(GL_BLEND)
        glBlendFunc(self.blend_src, self.blend_dest)

    def unset(self):
        glPopAttrib()
        glDisable(self.texture.target)

    def __eq__(self, other):
        return (other.__class__ is self.__class__ and 
                self.parent is other.parent and 
                self.texture.target == other.texture.target and
                self.texture.id == other.texture.id and
                self.blend_src == other.blend_src and
                self.blend_dest == other.blend_dest)

    def __hash__(self):
        return hash((id(self.parent), 
                     self.texture.id, self.texture.target,
                     self.blend_src, self.blend_dest))

class Sprite(event.EventDispatcher):
    _batch = None
    _animation = None
    _rotation = 0
    _opacity = 255
    _scale = 1.0
    vertex_list = None

    def __init__(self, 
                 img, x=0, y=0, 
                 blend_src=GL_SRC_ALPHA,
                 blend_dest=GL_ONE_MINUS_SRC_ALPHA,
                 batch=None,
                 parent_state=None):

        # make sure parent_state is accompanied by a batch
        if parent_state is not None and batch is None:
            raise ValueError('parent_state requires batch rendering')

        if batch is not None:
            self._batch = batch

        self._x = x
        self._y = y

        if isinstance(img, image.Animation):
            self._animation = img
            self._frame_index = 0
            self._texture = img.frames[0].image.get_texture()
            self._next_dt = img.frames[0].delay
            clock.schedule_once(self._animate, self._next_dt)
        else:
            self._texture = img.get_texture()

        self._state = SpriteState(self._texture, blend_src, blend_dest,
                                  parent_state)
        self._create_vertex_list()

    def __del__(self):
        if self._vertex_list is not None:
            self._vertex_list.delete()

    def delete(self):
        '''Force immediate removal from video memory.  
        
        This is often necessary when using batches, as the Python garbage
        collector will not necessarily call the finalizer as soon as the
        sprite is garbage.
        '''
        if self._animation:
            clock.unschedule(self._animate)
        self._vertex_list.delete()
        self._vertex_list = None

    def _animate(self, dt):
        self._frame_index += 1
        if self._frame_index >= len(self._animation.frames):
            self.dispatch_event('on_animation_end')
            self._frame_index = 0

        frame = self._animation.frames[self._frame_index]
        self._set_texture(frame.image.get_texture())

        if frame.delay is not None:
            delay = frame.delay - (self._next_dt - dt)
            delay = min(max(0, delay), frame.delay)
            clock.schedule_once(self._animate, delay)
            self._next_dt = delay
        else:
            self.dispatch_event('on_animation_end')

    # TODO set batch
    batch = property(lambda self: self._batch)

    def _set_parent_state(self, parent_state):
        if self._state.parent == parent_state:
            return

        if self._batch is not None:
            self._state = SpriteState(self._texture, 
                                      self._state.blend_src, 
                                      self._state.blend_dest,
                                      parent_state)
            self._vertex_list.delete()
            self._create_vertex_list()
        
    def _get_parent_state(self):
        return self._state.parent

    parent_state = property(_get_parent_state, _set_parent_state)

    def _get_image(self):
        if self._animation:
            return self._animation
        return self._texture

    def _set_image(self, img):
        if self._animation is not None:
            clock.unschedule(self._animate)
            self._animation = None

        if isinstance(img, image.Animation):
            self._animation = img
            self._frame_index = 0
            self._set_texture(img.frames[0].image.get_texture())
            self._next_dt = img.frames[0].delay
            clock.schedule_once(self._animate, self._next_dt)
        else:
            self._set_texture(img.get_texture())
        self._update_position()

    image = property(_get_image,
                     _set_image)

    def _set_texture(self, texture):
        if texture.id is not self._texture.id:
            self._state = SpriteState(texture, 
                                      self._state.blend_src, 
                                      self._state.blend_dest,
                                      self._state.parent)
            if self._batch is None:
                self._vertex_list.tex_coords[:] = texture.tex_coords
            else:
                self._vertex_list.delete()
                self._texture = texture
                self._create_vertex_list()
{'fraction_non_alphanumeric': 0.08314500941619586, 'fraction_numerical': 0.0032015065913370997, 'mean_word_length': 1.8194850013273163, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 11, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1019344', 'n_tokens_mistral': 3017, 'n_tokens_neox': 2892, 'n_words': 653}