Beispiel #1
0
def getShader(scriptName):
    """
    Attempts to retrieve a L{Shader} object resource. 
    
    @param scriptName: 
    Should name a resource that is a python script. The script should, upon
    execution, create a global (to itself) object C{theShader}, which is
    expected to be an instance of L{Shader}. This object is what is retrieved
    and cached by this function.
    @type scriptName: C{str}

    @return: L{Shader} or C{None}
    """
    # Return any cached copy of the desired shader object
    if (scriptName, 'theShader') in __resTable:
        return __resTable[(scriptName, 'theShader')]

    parole.info('Loading shader "%s"', scriptName)

    theShader = getObject(scriptName, 'theShader')
    if theShader and not isinstance(theShader, parole.Shader):
        parole.error(
            'Shader definition script bound "theShader" to non-Shader')
        return None

    # The shader definition worked and we have a bona fide Shader object
    # getObject should have already cached it
    return theShader
Beispiel #2
0
def getSound(name):
    """
    Attempts to retrieve the given sound resource as a PyGame C{Sound} object.
    The file can either be an uncompressed WAV or an OGG file.

    @return: C{pygame.mixer.Sound} or C{None}

    @param name: The path + filename of the sound resource to retrieve. 
    @type name: C{str}
    """
    # Return any cached copy of the texture surface object
    if name in __resTable:
        return __resTable[name]

    parole.info('Loading sound "%s"', name)

    # name should be a resource whose bytes are loadable by pygame's mixer
    # module
    bytes = getResource(name, binary=True)
    if not bytes:
        return None

    sound = None

    # Create a file-like object which pygame can use to read the bytes of
    # the sound
    soundf = cStringIO.StringIO(bytes)

    # Attempt to load the sound
    try:
        sound = pygame.mixer.Sound(soundf)
    except Exception, e:
        parole.error('Unable to load sound "%s": %s', name, e)
        return None
Beispiel #3
0
def __runScript(scriptName):
    # scriptName should be a resource whose bytes are python code
    bytes = getResource(scriptName)
    if not bytes:
        return None

    # compile the code, copy the current global namespace to execute it in
    scriptCode = compile(bytes, scriptName, 'exec')
    #modName = scriptName.replace('.py', '').replace('/', '.')
    modName = scriptName.split('/')[-1].replace('.py', '')
    scriptNamespace = {
        '__name__': modName,
        '__file__': scriptName,
        '__builtins__': globals()['__builtins__'],
        'parole': globals()['parole']
    }

    # Attempt to execute the code of the shader definition script.
    # It should create a global in its namespace called 'theShader', which
    # is the shader object we want to associate with this resource
    try:
        exec scriptCode in scriptNamespace
    except Exception, e:
        parole.error('Error executing "%s".\n%s', scriptName, e)
        return None
Beispiel #4
0
def getSound(name):
    """
    Attempts to retrieve the given sound resource as a PyGame C{Sound} object.
    The file can either be an uncompressed WAV or an OGG file.

    @return: C{pygame.mixer.Sound} or C{None}

    @param name: The path + filename of the sound resource to retrieve. 
    @type name: C{str}
    """
    # Return any cached copy of the texture surface object
    if name in __resTable:
        return __resTable[name]

    parole.info('Loading sound "%s"', name)

    # name should be a resource whose bytes are loadable by pygame's mixer
    # module
    bytes = getResource(name, binary=True)
    if not bytes:
        return None

    sound = None

    # Create a file-like object which pygame can use to read the bytes of
    # the sound
    soundf = cStringIO.StringIO(bytes)

    # Attempt to load the sound
    try:
        sound = pygame.mixer.Sound(soundf)
    except Exception, e:
        parole.error('Unable to load sound "%s": %s', name, e)
        return None
Beispiel #5
0
def getShader(scriptName):
    """
    Attempts to retrieve a L{Shader} object resource. 
    
    @param scriptName: 
    Should name a resource that is a python script. The script should, upon
    execution, create a global (to itself) object C{theShader}, which is
    expected to be an instance of L{Shader}. This object is what is retrieved
    and cached by this function.
    @type scriptName: C{str}

    @return: L{Shader} or C{None}
    """
    # Return any cached copy of the desired shader object
    if (scriptName, "theShader") in __resTable:
        return __resTable[(scriptName, "theShader")]

    parole.info('Loading shader "%s"', scriptName)

    theShader = getObject(scriptName, "theShader")
    if theShader and not isinstance(theShader, parole.Shader):
        parole.error('Shader definition script bound "theShader" to non-Shader')
        return None

    # The shader definition worked and we have a bona fide Shader object
    # getObject should have already cached it
    return theShader
Beispiel #6
0
def __init():
    """
    Initializes the resource module. Detects and loads all resource pakcages 
    in the gamedir directory. Automatically called during engine 
    startup -- user code shouldn't need to use this function.
    """
    global __gameDir, __inInit
    __inInit = True
    __resTable.clear()

    parole.conf.notify(__onConfigChange, True)
    __gameDir = parole.conf.resource.gamedir

    # Score some packages
    while len(packages):
        packages.pop()
    suff = parole.conf.resource.packsuffix
    for root, dirs, files in os.walk(__gameDir):
        if root == __gameDir:
            if bool(parole.conf.resource.allowdirs):
                packages.extend([(dir, None, __getResourceFromDir) for dir in dirs if dir.endswith(suff)])
            for arch in files:
                if not arch.endswith(suff):
                    continue
                if not zipfile.is_zipfile(os.sep.join([__gameDir, arch])):
                    parole.error("Ignoring bad archive resource package: %s: Not dir or zip.", arch)
                    continue
                # archf = None
                try:
                    archf = zipfile.ZipFile(os.sep.join([__gameDir, arch]), "r")
                    parole.info("archf = %r", archf)
                except Exception, e:
                    parole.error("Ignoring bad archive resource package: %s: %s", arch, e)
                    continue
                packages.append((arch, archf, __getResourceFromArch))
Beispiel #7
0
def __runScript(scriptName):
    # scriptName should be a resource whose bytes are python code
    bytes = getResource(scriptName)
    if not bytes:
        return None

    # compile the code, copy the current global namespace to execute it in
    scriptCode = compile(bytes, scriptName, "exec")
    # modName = scriptName.replace('.py', '').replace('/', '.')
    modName = scriptName.split("/")[-1].replace(".py", "")
    scriptNamespace = {
        "__name__": modName,
        "__file__": scriptName,
        "__builtins__": globals()["__builtins__"],
        "parole": globals()["parole"],
    }

    # Attempt to execute the code of the shader definition script.
    # It should create a global in its namespace called 'theShader', which
    # is the shader object we want to associate with this resource
    try:
        exec scriptCode in scriptNamespace
    except Exception, e:
        parole.error('Error executing "%s".\n%s', scriptName, e)
        return None
Beispiel #8
0
def __getResourceFrom(path, package, binary=False):
    """
    __getResourceFrom(path, package, binary=False) -> str or None
    
    Returns the bytes (as a string) of the resource at the given path in the
    given package, or None if an error is encountered. If binary is True, 
    attempts to read the resource in binary mode.
    """
    for (pkgname, archf, getter) in packages:
        if pkgname == package: return getter(path, archf or pkgname, binary)

    parole.error('__getResourceFrom(): unknown package: %s', package)
Beispiel #9
0
def __getResourceFrom(path, package, binary=False):
    """
    __getResourceFrom(path, package, binary=False) -> str or None
    
    Returns the bytes (as a string) of the resource at the given path in the
    given package, or None if an error is encountered. If binary is True, 
    attempts to read the resource in binary mode.
    """
    for (pkgname, archf, getter) in packages:
        if pkgname == package:
            return getter(path, archf or pkgname, binary)

    parole.error("__getResourceFrom(): unknown package: %s", package)
Beispiel #10
0
def getFont(name, size):
    """
    Attempts to retrieve the given font resource as a PyGame Font object.

    @return: C{pygame.font.Font} or C{None}

    @param name: The path + filename of the font resource to retrieve. Must name
    a font file in a format that PyGame can read (e.g., TrueType).
    @type name: C{str}
    """
    # Return any cached copy of the font object
    if (name, size) in __resTable:
        return __resTable[(name, size)]

    parole.info('Loading font "%s" %spt', name, size)

    # name should be a resource whose bytes are loadable by pygame's font
    # module
    bytes = getResource(name, binary=True)
    if not bytes:
        parole.error('"%s" names an empty font resource.', name)
        return None

    parole.debug("Got font bytes. (len=%d)", len(bytes))
    font = None

    # Create a file-like object which pygame can use to read the bytes of
    # the font file
    # pygame 1.9.1release segfaults when reading a font from cStringIO
    # fontf = cStringIO.StringIO(bytes)
    # Workaround:
    import tempfile

    tmpf = tempfile.NamedTemporaryFile(delete=False)
    tmpf.write(bytes)
    tmpf.close()
    fontf = tmpf.name

    # Attempt to load the font
    try:
        parole.debug("Parsing font bytes...")
        font = pygame.font.Font(fontf, size)
    except Exception, e:
        parole.error('Unable to load font "%s" %pt: %s', name, size, e)
        return None
Beispiel #11
0
def getFont(name, size):
    """
    Attempts to retrieve the given font resource as a PyGame Font object.

    @return: C{pygame.font.Font} or C{None}

    @param name: The path + filename of the font resource to retrieve. Must name
    a font file in a format that PyGame can read (e.g., TrueType).
    @type name: C{str}
    """
    # Return any cached copy of the font object
    if (name, size) in __resTable:
        return __resTable[(name, size)]

    parole.info('Loading font "%s" %spt', name, size)

    # name should be a resource whose bytes are loadable by pygame's font
    # module
    bytes = getResource(name, binary=True)
    if not bytes:
        parole.error('"%s" names an empty font resource.', name)
        return None

    parole.debug('Got font bytes. (len=%d)', len(bytes))
    font = None

    # Create a file-like object which pygame can use to read the bytes of
    # the font file
    # pygame 1.9.1release segfaults when reading a font from cStringIO
    #fontf = cStringIO.StringIO(bytes)
    # Workaround:
    import tempfile
    tmpf = tempfile.NamedTemporaryFile(delete=False)
    tmpf.write(bytes)
    tmpf.close()
    fontf = tmpf.name

    # Attempt to load the font
    try:
        parole.debug('Parsing font bytes...')
        font = pygame.font.Font(fontf, size)
    except Exception, e:
        parole.error('Unable to load font "%s" %pt: %s', name, size, e)
        return None
Beispiel #12
0
def __init():
    """
    Initializes the resource module. Detects and loads all resource pakcages 
    in the gamedir directory. Automatically called during engine 
    startup -- user code shouldn't need to use this function.
    """
    global __gameDir, __inInit
    __inInit = True
    __resTable.clear()

    parole.conf.notify(__onConfigChange, True)
    __gameDir = parole.conf.resource.gamedir

    # Score some packages
    while len(packages):
        packages.pop()
    suff = parole.conf.resource.packsuffix
    for root, dirs, files in os.walk(__gameDir):
        if root == __gameDir:
            if bool(parole.conf.resource.allowdirs):
                packages.extend([(dir, None, __getResourceFromDir) \
                        for dir in dirs if dir.endswith(suff)])
            for arch in files:
                if not arch.endswith(suff): continue
                if not zipfile.is_zipfile(os.sep.join([__gameDir, arch])):
                    parole.error(
                        'Ignoring bad archive resource package: %s: Not dir or zip.',
                        arch)
                    continue
                #archf = None
                try:
                    archf = zipfile.ZipFile(os.sep.join([__gameDir, arch]),
                                            'r')
                    parole.info('archf = %r', archf)
                except Exception, e:
                    parole.error(
                        'Ignoring bad archive resource package: %s: %s', arch,
                        e)
                    continue
                packages.append((arch, archf, __getResourceFromArch))
Beispiel #13
0
def exportResource(name, destination):
    """
    Exports the named resource to the given destination on disk.
    C{destination} should be the full path plus filname to which the
    byte-contents of the named resource should be copied.

    This function can be useful for extracting a sound resource from a zip
    package and writing it to disk as a standalone file so that
    it can be used by C{pygame.mixer.music}, for instance.
    """
    parole.info('Exporting resource "%s" to "%s".', name, destination)

    bytes = getResource(name, binary=True)
    if not bytes:
        parole.error('exportResource: resource "%s" not found.', name)

    destf = None
    try:
        destf = open(destination, "wb")
        destf.write(bytes)
    except IOError, e:
        parole.error('exportResource: IOError while writing resource "%s" to' ' "%s": %s', name, destination, e)
Beispiel #14
0
def getTexture(name):
    """
    Attempts to retrieve the given texture resource as a PyGame C{Surface}
    object.

    @todo: Return a dummy texture if not found.

    @return: C{pygame.Surface} or C{None}

    @param name: The path + filename of the texture resource to retrieve. Must
    name an image file in a format that PyGame can read (png, jpeg, tiff, etc.).
    @type name: C{str}
    """
    # Return any cached copy of the texture surface object
    if name in __resTable:
        return __resTable[name]

    parole.info('Loading texture "%s"', name)

    # name should be a resource whose bytes are loadable by pygame's image
    # module
    bytes = getResource(name, binary=True)
    if not bytes:
        return None

    tex = None

    # Create a file-like object which pygame can use to read the bytes of
    # the texture
    texf = cStringIO.StringIO(bytes)

    # Attempt to load the texture
    try:
        tex = pygame.image.load(texf, name).convert()
    except Exception, e:
        # TODO: return a dummy "not found" texture
        parole.error('Unable to load texture "%s": %s', name, e)
        return None
Beispiel #15
0
def getObject(scriptName, objName):
    """
    Retrieves a python object defined in the given python script 
    resource.

    @param scriptName:
    Should name a resource that is a python 
    script. The script should, upon execution, create a global (to itself) 
    object with the name C{objName}.
    @type scriptName: C{str}

    @param objName:
    The name of the object created in the script's global namespace to return.

    @return: C{object}
    """
    # Return any cached copy of the desired object
    if (scriptName, objName) in __resTable:
        return __resTable[(scriptName, objName)]

    parole.info('Loading object "%s" from "%s"', objName, scriptName)

    scriptNamespace = __runScript(scriptName)
    if not scriptNamespace:
        parole.error('Failed to load object "%s" from "%s"', objName,
                     scriptName)
        return None

    if objName not in scriptNamespace:
        parole.error('Script "%s" did not bind "s"', scriptName, objName)
        return None

    obj = scriptNamespace[objName]

    # The script worked and we have a bona fide object
    # Cache it and return it
    __resTable[(scriptName, objName)] = obj
    return obj
Beispiel #16
0
def getTexture(name):
    """
    Attempts to retrieve the given texture resource as a PyGame C{Surface}
    object.

    @todo: Return a dummy texture if not found.

    @return: C{pygame.Surface} or C{None}

    @param name: The path + filename of the texture resource to retrieve. Must
    name an image file in a format that PyGame can read (png, jpeg, tiff, etc.).
    @type name: C{str}
    """
    # Return any cached copy of the texture surface object
    if name in __resTable:
        return __resTable[name]

    parole.info('Loading texture "%s"', name)

    # name should be a resource whose bytes are loadable by pygame's image
    # module
    bytes = getResource(name, binary=True)
    if not bytes:
        return None

    tex = None

    # Create a file-like object which pygame can use to read the bytes of
    # the texture
    texf = cStringIO.StringIO(bytes)

    # Attempt to load the texture
    try:
        tex = pygame.image.load(texf, name).convert()
    except Exception, e:
        # TODO: return a dummy "not found" texture
        parole.error('Unable to load texture "%s": %s', name, e)
        return None
Beispiel #17
0
def getObject(scriptName, objName):
    """
    Retrieves a python object defined in the given python script 
    resource.

    @param scriptName:
    Should name a resource that is a python 
    script. The script should, upon execution, create a global (to itself) 
    object with the name C{objName}.
    @type scriptName: C{str}

    @param objName:
    The name of the object created in the script's global namespace to return.

    @return: C{object}
    """
    # Return any cached copy of the desired object
    if (scriptName, objName) in __resTable:
        return __resTable[(scriptName, objName)]

    parole.info('Loading object "%s" from "%s"', objName, scriptName)

    scriptNamespace = __runScript(scriptName)
    if not scriptNamespace:
        parole.error('Failed to load object "%s" from "%s"', objName, scriptName)
        return None

    if objName not in scriptNamespace:
        parole.error('Script "%s" did not bind "s"', scriptName, objName)
        return None

    obj = scriptNamespace[objName]

    # The script worked and we have a bona fide object
    # Cache it and return it
    __resTable[(scriptName, objName)] = obj
    return obj
Beispiel #18
0
def exportResource(name, destination):
    """
    Exports the named resource to the given destination on disk.
    C{destination} should be the full path plus filname to which the
    byte-contents of the named resource should be copied.

    This function can be useful for extracting a sound resource from a zip
    package and writing it to disk as a standalone file so that
    it can be used by C{pygame.mixer.music}, for instance.
    """
    parole.info('Exporting resource "%s" to "%s".', name, destination)

    bytes = getResource(name, binary=True)
    if not bytes:
        parole.error('exportResource: resource "%s" not found.', name)

    destf = None
    try:
        destf = open(destination, 'wb')
        destf.write(bytes)
    except IOError, e:
        parole.error(
            'exportResource: IOError while writing resource "%s" to'
            ' "%s": %s', name, destination, e)
Beispiel #19
0
    # we need to load it
    parole.info('Loading resource: "%s"', name)
    bytes = None

    # go through all packages until we find one with the resource
    # we need. The packages list should already be in the proper order
    for (package, f, g) in packages:
        try:
            bytes = __getResourceFrom(name, package, binary)
            parole.debug('"%s" found in "%s"', name, package)
            break
        except __NotFound, e:
            parole.debug('"%s" not found in "%s"', name, package)

    if not bytes:
        parole.error("Unknown resource: %s", name)
        return None

    # store the resource's bytes in the resource table
    __resTable[name] = bytes
    return bytes


# ==============================================================================


def clearResource(name):
    """
    Clears the cache of the given resource. Any future retrieval of the 
    resource will result in an actual disk read. The resource may not actually
    be freed from memory if any user code still contains references to it.
Beispiel #20
0
    # we need to load it
    parole.info('Loading resource: "%s"', name)
    bytes = None

    # go through all packages until we find one with the resource
    # we need. The packages list should already be in the proper order
    for (package, f, g) in packages:
        try:
            bytes = __getResourceFrom(name, package, binary)
            parole.debug('"%s" found in "%s"', name, package)
            break
        except __NotFound, e:
            parole.debug('"%s" not found in "%s"', name, package)

    if not bytes:
        parole.error('Unknown resource: %s', name)
        return None

    # store the resource's bytes in the resource table
    __resTable[name] = bytes
    return bytes


#==============================================================================


def clearResource(name):
    """
    Clears the cache of the given resource. Any future retrieval of the 
    resource will result in an actual disk read. The resource may not actually
    be freed from memory if any user code still contains references to it.