Exemple #1
0
    def createResourceStruct(resources,
                             formatAsTree=False,
                             updateOnlyExistingSprites=False):

        skippatt = re.compile(r'\.(meta|py)$', re.I)
        result = {}
        if formatAsTree:
            result = ExtMap()

        # Filter unwanted files
        for res in resources:
            if skippatt.search(res.path):
                continue
            result[res.id] = res

        # Update simple images
        for combImg in (x for x in result.values()
                        if isinstance(x, CombinedImage)):
            for embImg in combImg.embeds:
                if embImg.id in result:
                    result[embImg.id].attachCombinedImage(combImg)
                elif not updateOnlyExistingSprites:
                    embImg.attachCombinedImage(combImg)
                    result[embImg.id] = embImg

        # Flatten out the resource representation
        for resid, res in result.items():
            result[resid] = res.toResinfo()

        # ExtMap returns nested maps
        if formatAsTree:
            result = result.getData()

        return result
Exemple #2
0
    def createResourceStruct(resources, formatAsTree=False, updateOnlyExistingSprites=False):
        
        skippatt = re.compile(r'\.(meta|py)$', re.I)
        result = {}
        if formatAsTree:
            result = ExtMap()

        # Filter unwanted files
        for res in resources:
            if skippatt.search(res.path):
                continue
            result[res.id] = res

        # Update simple images
        for combImg in (x for x in result.values() if isinstance(x, CombinedImage)):
            for embImg in combImg.embeds:
                if embImg.id in result:
                    result[embImg.id].attachCombinedImage(combImg)
                elif not updateOnlyExistingSprites:
                    embImg.attachCombinedImage(combImg)
                    result[embImg.id] = embImg

        # Flatten out the resource representation
        for resid, res in result.items():
            result[resid] = res.toResinfo()

        # ExtMap returns nested maps
        if formatAsTree:
            result = result.getData()

        return result
Exemple #3
0
    def createResourceStruct(resources,
                             formatAsTree=False,
                             updateOnlyExistingSprites=False):

        skippatt = re.compile(r'\.(meta|py)$', re.I)
        result = {}
        if formatAsTree:
            result = ExtMap()

        # Filter unwanted files
        for res in resources:
            if skippatt.search(res.path):
                continue
            result[res.id] = res

        # Update simple images
        for combImg in (x for x in result.values()
                        if isinstance(x, CombinedImage)):
            for embImg in combImg.embeds:
                if embImg.id in result:
                    result[embImg.id].attachCombinedImage(combImg)
                elif not updateOnlyExistingSprites:
                    embImg.attachCombinedImage(combImg)
                    result[embImg.id] = embImg

        # Flatten out the resource representation
        for resid, res in result.items():
            result[resid] = res.toResinfo()

            # Unify font map aliases
            if isinstance(res, FontMap):
                for glyphname, code in res.mapping.iteritems():
                    fdsc = "@%s/%s" % (res.alias, glyphname)
                    if not fdsc in result:
                        try:
                            result[fdsc] = [
                                result[resid][1],
                                round(result[resid][2] / code[1]), code[0]
                            ]
                        except:
                            pass
                del result[resid][4]

        # ExtMap returns nested maps
        if formatAsTree:
            result = result.getData()

        return result
Exemple #4
0
    def createResourceStruct(resources, formatAsTree=False, updateOnlyExistingSprites=False):
        
        skippatt = re.compile(r'\.(meta|py)$', re.I)
        result = {}
        if formatAsTree:
            result = ExtMap()

        # Filter unwanted files
        for res in resources:
            if skippatt.search(res.path):
                continue
            result[res.id] = res

        # Update simple images
        for combImg in (x for x in result.values() if isinstance(x, CombinedImage)):
            for embImg in combImg.embeds:
                if embImg.id in result:
                    result[embImg.id].attachCombinedImage(combImg)
                elif not updateOnlyExistingSprites:
                    embImg.attachCombinedImage(combImg)
                    result[embImg.id] = embImg

        # Flatten out the resource representation
        for resid, res in result.items():
            result[resid] = res.toResinfo()

            # Unify font map aliases
            if isinstance(res, FontMap):
                for glyphname, code in res.mapping.iteritems():
                  fdsc = "@%s/%s" % (res.alias, glyphname)
                  if not fdsc in result:
                      result[fdsc] = [result[resid][1], round(result[resid][2] / code[1]), code[0]]
                del result[resid][4]

        # ExtMap returns nested maps
        if formatAsTree:
            result = result.getData()

        return result
Exemple #5
0
    def generateResourceInfoCode(self, script, settings, libs, format=False):

        # some helper functions
        def extractAssetPart(libresuri, imguri):
            pre,libsfx,imgsfx = Path.getCommonPrefix(libresuri, imguri) # split libresuri from imguri
            if imgsfx[0] == os.sep: imgsfx = imgsfx[1:]  # strip leading '/'
            return imgsfx                # use the bare img suffix as its asset Id

        ##
        # finds the package that needs this resource <assetId> and adds it
        # (polymorphic in the 4th param, use either simpleResVal *or* combImgObj as kwarg)
        # TODO: this might be very expensive (lots of lookup's)
        def addResourceToPackages(script, classToResourceMap, assetId, simpleResVal=None, combImgObj=None):

            ##
            # match an asset id or a combined image object
            def assetRexMatchItem(assetRex, item):
                if combImgObj:
                    # combined image = object(used:True/False, embeds: {id:ImgInfoFmt}, info:ImgInfoFmt)
                    for embId in item.embeds:
                        if assetRex.match(embId):
                            return True
                    return False
                else:
                    # assetId
                    return assetRex.match(item)

            # --------------------------------------------------------
            if combImgObj:
                resvalue = combImgObj.info.flatten()
                checkval = combImgObj
            else:
                resvalue = simpleResVal
                checkval = assetId

            classesUsing = set(())
            for clazz, assetSet in classToResourceMap.items():
                for assetRex in assetSet:
                    if assetRexMatchItem(assetRex, checkval):
                        classesUsing.add(clazz)
                        break
            for package in script.packages:
                if classesUsing.intersection(set(package.classes)):
                    package.data.resources[assetId] = resvalue
            return

        ##
        # return the (potentially empty) list of embedded image id's of a
        # combined image that are in filteredResources
        def requiredEmbeds(combImg, filteredResourceIds):  # combImg = {info: ImgInfoFmt, embeds: {id:ImgInfoFmt}}
            return (x for x in combImg.embeds if x in filteredResourceIds)


        ##
        # create the final form of the data to be returned by generateResourceInfoCode
        def serialize(filteredResources, combinedImages, resdata):
            for resId, resval in filteredResources.items():
                # build up resdata
                if isinstance(resval, ImgInfoFmt):
                    resvalue = resval.flatten()
                else:  # handle other resources
                    resvalue = resval
                resdata[resId] = resvalue
            return resdata


        ##
        # loop through resources, invoking addResourceToPackages
        def addResourcesToPackages(resdata, combinedImages, classToResourceMap):
            for resId, resvalue in resdata.items():
                # register the resource with the package needing it
                addResourceToPackages(script, classToResourceMap, resId, simpleResVal=resvalue)

            # for combined images, we have to check their embedded images against the packages
            for combId, combImg in combinedImages.items():
                if combId in resdata:
                    addResourceToPackages(script, classToResourceMap, combId, combImgObj=combImg)

            # handle tree structure of resource info
            if resources_tree:
                resdata = resdata._data

            return resdata


        ##
        # get the resource Id and resource value
        def analyseResource(resource, lib):
            ##
            # compute the resource value of an image for the script
            def imgResVal(resource):
                imgId = resource

                # Cache or generate
                if (imgId  in imgLookupTable and
                    imgLookupTable[imgId ]["time"] > os.stat(imgId ).st_mtime):
                    imageInfo = imgLookupTable[imgId ]["content"]
                else:
                    imageInfo = self._imageInfo.getImageInfo(imgId , assetId)
                    imgLookupTable[imgId ] = {"time": time.time(), "content": imageInfo}

                # Now process the image information
                # use an ImgInfoFmt object, to abstract from flat format
                imgfmt = ImgInfoFmt()
                imgfmt.lib = lib['namespace']
                if not 'type' in imageInfo:
                    raise RuntimeError, "Unable to get image info from file: %s" % imgId 
                imgfmt.type = imageInfo['type']

                # Add this image
                # imageInfo = {width, height, filetype}
                if not 'width' in imageInfo or not 'height' in imageInfo:
                    raise RuntimeError, "Unable to get image info from file: %s" % imgId 
                imgfmt.width  = imageInfo['width']
                imgfmt.height = imageInfo['height']
                imgfmt.type   = imageInfo['type']

                return imgfmt

            # ----------------------------------------------------------
            imgpatt = re.compile(r'\.(png|jpeg|jpg|gif)$', re.I)
            librespath = os.path.normpath(os.path.join(lib['path'], lib['resource']))
            assetId = extractAssetPart(librespath, resource)
            assetId = Path.posifyPath(assetId)
            if imgpatt.search(resource): # handle images
                resvalue = imgResVal(resource)
            else:  # handle other resources
                resvalue = lib['namespace']
            return assetId, resvalue


        ##
        # collect resources from the libs and put them in suitable data structures
        def registerResources(libs, filteredResources, combinedImages):
            skippatt = re.compile(r'\.(meta|py)$', re.I)
            for lib in libs:
                resourceList = self._resourceHandler.findAllResources([lib], None)
                # resourceList = [file1,file2,...]
                for resource in resourceList:
                    if skippatt.search(resource):
                        continue
                    if assetFilter(resource):  # add those anyway
                        resId, resVal            = analyseResource(resource, lib)
                        filteredResources[resId] = resVal
                    if self._resourceHandler.isCombinedImage(resource):  # register those for later evaluation
                        combId, combImgFmt     = analyseResource(resource, lib)
                        combObj                = CombinedImage(resource) # this parses also the .meta file
                        combObj.info           = combImgFmt
                        combinedImages[combId] = combObj
            return filteredResources, combinedImages

        ##
        # apply combined image info to the simple images, improving and extending
        # filteredResources
        def incorporateCombinedImages(filteredResources, combinedImages):
            for combId, combImg in combinedImages.items():  # combImg.embeds = {resId : ImgFmt}
                filteredResourceIds = filteredResources.keys()
                for embId in requiredEmbeds(combImg, filteredResourceIds):
                    # patch simle image info
                    lib = filteredResources[embId].lib                    # keep lib info
                    filteredResources[embId]      = combImg.embeds[embId] # replace info with combined info
                    filteredResources[embId].lib  = lib                   # restore original lib
                    # add combined image
                    if combId not in filteredResourceIds:
                        filteredResources[combId] = combImg.info
            return filteredResources


        # -- main --------------------------------------------------------------

        self._console.info("Analyzing assets...")
        self._console.indent()

        compConf       = self._job.get("compile-options")
        compConf       = ExtMap(compConf)
        resources_tree = compConf.get("code/resources-tree", False)
        resdata        = {}
        if resources_tree:
            resdata = ExtMap()

        self._imageInfo                = ImageInfo(self._console, self._cache)
        assetFilter, classToResourceMap= self._resourceHandler.getResourceFilterByAssets(self._classList)

        # read img cache file
        cacheId = "imginfo-%s" % self._config._fname
        imgLookupTable = cache.read(cacheId, None)
        if imgLookupTable == None:
            imgLookupTable = {}

        filteredResources = {}          # type {resId : ImgInfoFmt|string}
        combinedImages    = {}          # type {imgId : CombinedImage}
        # 1st pass gathering relevant images and other resources from the libraries
        filteredResources, combinedImages = registerResources(libs, filteredResources,
                                                              combinedImages)
        # 2nd pass patching simple image infos with combined info
        filteredResources = incorporateCombinedImages(filteredResources, combinedImages)

        # 3rd pass consume the info from filteredResources in various ways
        resdata     = serialize(filteredResources, combinedImages, resdata)
        addResourcesToPackages(resdata, combinedImages, classToResourceMap)
        if resources_tree:
            resdata = resdata.getData()
        
        # write img cache file
        cache.write(cacheId, imgLookupTable)
        self._console.outdent()

        return resdata