All pastes #172460 Raw Edit

Cherez

public python v1 · immutable
·published 2006-09-16 03:21 UTC
rendered paste body
"""Resource Caching ModuleMost game projects require graphics, sound and other resources to be loadedmultiple times - a sprite's image might be loaded for each instance of thatsprite. Normally, you'll write some sort of resource management system to ensurethat all these identical resources aren't kept in memory at once.This module wraps pygame's resource loading functions.  It ensures that only onecopy of any given resource will be in memory at any time - further requests forthat same resource will get a reference to the loaded copy.  This behavoir canbe overridden by specifying that the resource loading be forced - all clients ofthat resource will then refer to the new version.  The resource can be manuallyremoved from memory with the clear_* set of functions.This code might be useful if a game is going to be loading many copies of agiven disk resource.  Most of the time, you'd write your own cache; now you canjust use this one.Remember to call the 'set path' functions before trying to load anything;otherwise, you'll get a ValueError.Modified by Cherez to use WeakValueDictionary for low-memory situations."""__author__ = "David Clark"__copyright__ = "Copyright (c) 2001 David Clark"__license__ = "Public Domain"__version__ = "1.0"import pygame, os, weakref__images = weakref.WeakValueDictionary()__fonts = weakref.WeakValueDictionary()__sounds = weakref.WeakValueDictionary()__images_path = None__fonts_path = None__sounds_path = Nonedef get_image(filename, force_reload = 0):    """    get_image(filename, force_reload = 1) --> surface    Call this function instead of pygame.image.load - it will load the image    from the disk the first time, then just return a reference to the copy each    subsequent time.  This function does no colorkey setting or pixel format    conversion; you'll have to do that manually, if you wish.    """    if not __images_path:        raise ValueError, "resources.set_images_path() not called yet."    if (force_reload == 1 or filename not in __images.keys()):        try:            surface = pygame.image.load(os.path.join(__images_path, filename))        except pygame.error:            raise IOError, "File " + filename + " not found."        __images[filename] = surface        return surface    else:        return __images[filename]def has_image(filename):    """    has_image(filename) --> Boolean    Returns true if the image is in memory, false if it has to be loaded from    disk.    """    return __images.has_key(filename)def clear_image(filename):    """    clear_image(filename) --> Boolean    Eliminates the image from memory.  Subsequent calls will load it from the    disk.  Returns True if the resource was found in memory, False if it Wasn't.    Use this to reduce the memory footprint, if you're sure you won't be needing    the resource again.    """    try:        del __images[filename]        return 1    except KeyError:        return 0def get_font(filename, size, force_reload = 0):    """    get_font(filename, size, force_reload = 1) --> surface    Call this function instead of pygame.font.Font - it will load the font from    the disk the first time, then just return a reference to the copy each    subsequent time.    """    if not __fonts_path:        raise ValueError, "resources.set_fonts_path() not called yet."    if (force_reload == 1 or filename not in __fonts.keys()):        try:            font = pygame.font.Font(os.path.join(__fonts_path, filename), size)        except pygame.error:            raise IOError, "File " + filename + " not found."        __fonts[filename] = font        return font    else:        return __fonts[filename]def has_font(filename):    """    has_font(filename) --> Boolean    Returns true if the font is in memory, false if it has to be loaded from    disk.    """    return __fonts.has_key(filename)def clear_font(filename):    """    clear_font(filename) --> Boolean    Eliminates the font from memory.  Subsequent calls will load it from the    disk.  Returns True if the resource was found in memory, False if it Wasn't.    Use this to reduce the memory footprint, if you're sure you won't be needing    the resource again.    """    try:        del __fonts[filename]        return 1    except KeyError:        return 0def get_sound(filename, force_reload = 0):    """    get_sound(filename, force_reload = 1) --> sound    Call this function instead of pygame.mixer.Sound - it will load the sound    from the disk the first time, then just return a reference to the copy each    subsequent time.    """    if not __sounds_path:        raise ValueError, "resources.set_sounds_path() not called yet."    if (force_reload == 1 or filename not in __fonts.keys()):        try:            sound = pygame.mixer.Sound(os.path.join(__sounds_path, filename))        except pygame.error:            raise IOError, "File " + filename + " not found."        __sounds[filename] = sound        return sound    else:        return __sounds[filename]def has_sound(filename):    """    has_sound(filename) --> Boolean    Returns true if the sound is in memory, false if it has to be loaded from    disk.    """    return __sounds.has_key(filename)def clear_sound(filename):    """    clear_sound(filename) --> Boolean    Eliminates the sound from memory.  Subsequent calls will load it from the    disk.  Returns True if the resource was found in memory, False if it Wasn't.    Use this to reduce the memory footprint, if you're sure you won't be needing    the resource again.    """    try:        del __sounds[filename]        return 1    except KeyError:        return 0def set_images_path(path):    """    set_images_path(path) --> Boolean    Set the path you'll be loading the images off of.  Pass the string    representation of the new path.  Raises an exception if the path doesn't    exist, otherwise it returns True.    """    if not os.access(path, os.F_OK):        raise IOError, path + " not found."    if path.endswith(os.sep):        path = path[:-1]    global __images_path    __images_path = path    return 1def set_fonts_path(path):    """    set_fonts_path(path) --> Boolean    Set the path you'll be loading the fonts off of.  Pass the string    representation of the new path.  Raises an exception if the path doesn't    exist, otherwise it returns True.    """    if not os.access(path, os.F_OK):        raise IOError, path + " not found."    if path.endswith(os.sep):        path = path[:-1]    global __fonts_path    __fonts_path = path    return 1def set_sounds_path(path):    """    set_sounds_path(path) --> Boolean    Set the path you'll be loading the sounds off of.  Pass the string    representation of the new path.  Raises an exception if the path doesn't    exist, otherwise it returns True.    """    if not os.access(path, os.F_OK):        raise IOError, path + " not found."    if path.endswith(os.sep):        path = path[:-1]    global __sounds_path    __sounds_path = path    return 1def get_images_path():    """    get_images_path() --> String    Returns the current value of the images path, or None if it hasn't been set    yet.    """    return __images_pathdef get_fonts_path():    """    get_fonts_path() --> String    Returns the current value of the fonts path, or None if it hasn't been set    yet.    """    return __fonts_pathdef get_sounds_path():    """    get_sounds_path() --> String    Returns the current value of the sounds path, or None if it hasn't been set    yet.    """    return __sounds_path