Custom ResourceManager

kendoran

22-08-2009 03:17:24

I am trying to write a custom resource manager to load my map and script files, but am not having much success yet.

The tutorial (Resources and ResourceManagers) I'm attempting to recreate in python-ogre refers to the _registerResourceManager function in the ResourceManager class, but it seems to be unavailable in python-ogre.

Here is the initial attempt:


class TypeFileManager(ogre.ResourceManager):
def __init__(self):
ogre.ResourceManager.__init__(self)
ogre.ResourceManager.ResourceType = "TypeFile"
ogre.ResourceManager.resourceType = "TypeFile"
ogre.ResourceManager.loadingOrder = "30.0"
s = ogre.ResourceGroupManager.getSingleton()
s._registerResourceManager(ogre.ResourceManager.ResourceType, self);

def createImpl(self, name, handle, group, isManual, loader, createParams):
pass

def load(self, name, group):
pass


Any suggestions on what to do here?

andy

23-08-2009 01:34:15

_registerResourceManager is certainly exposed -- what is the actual error you are having?

Andy

kendoran

24-08-2009 10:47:08

Hey, thanks for the reply.

I'm still very new to Ogre and Python-Ogre, and made a newbie mistake :) After some investigation, the problem was due to not instantiating ogre.Root(). The error I was getting was the standard python error when methods don't exist in an object. All good now though.

I'm still following the tutorial I linked in the first post, and am having some trouble detailed below. Has anybody written a custom resource manager with python-ogre? Is there any sample code available?

There is another problem I'm having. I declared the custom TextFileManager and TextFile classes like in the tutorial, however when I call self.TFM.load("hello.txt", ogre.ResourceGroupManager.DEFAULT_RESOURCE_GROUP_NAME), the object returned is of type ogre.Resource, rather than TextFile like I would have expected. The returned object does not contain the getString method, or the "text" field.

The TextFile class is registered, and putting a breakpoint in:

def createImpl(self, name, handle, group, isManual, loader, createParams):
self.textfile = TextFile(self, name, handle, group, isManual, loader)
return self.textfile


I can see that the object is correctly set up and is returned.

The resource returned by self.TFM.load has the same value I set in

def calculateSize(self):
return len(self.text)


Any ideas what is happening here, and why the resource manager is only returning resource, rather than the custom text file resource I set up?

For reference, here is the full source (the textfile "hello.txt" is sitting in the media directory, and just contains "Hello world!"):

#!/usr/bin/env python

import sys
import os

import ogre.renderer.OGRE as ogre
import ogre.gui.CEGUI as CEGUI
import ogre.io.OIS as OIS

class TextFileSerializer(ogre.Serializer):
def exportTextFile(self, text, fileName):
pass

def importTextFile(self, stream, dest):
dest.setString(stream.getAsString())

class TextFile(ogre.Resource):
text = None
serializer = TextFileSerializer()

def __init__(self, creator, name, handle, group, isManual, loader):
ogre.Resource.__init__(self, creator, name, handle, group, isManual, loader)

def __del__(self):
unload()

def loadImpl(self):
rgm = ogre.ResourceGroupManager.getSingleton()
stream = rgm.openResource(self.Name, "General", True, self)
self.serializer.importTextFile(stream, self)

def unloadImpl(self):
self.text = ""

def calculateSize(self):
return len(self.text)

def setString(self, text):
self.text = text

def getString(self):
return self.text


class TextFileManager(ogre.ResourceManager):
# Borg Singleton http://code.activestate.com/recipes/66531/
__shared_state = {}
initialized = False

textfile = None
tx = None

def __init__(self):
self.__dict__ = self.__shared_state # Singleton
if self.initialized: return

ogre.ResourceManager.__init__(self)
ogre.ResourceManager.resourceType = "TextFile"
ogre.ResourceManager.ResourceType = "TextFile"

# low, because it will likely reference other resources
ogre.ResourceManager.LoadingOrder = 30.0
ogre.ResourceManager.loadingOrder = 30.0

rgm = ogre.ResourceGroupManager.getSingleton()
rgm._registerResourceManager(self.resourceType, self)

self.initialized = True

def __del__(self):
rgm = ogre.ResourceGroupManager.getSingleton()
rgm._unregisterResourceManager(resourceType)

def load(self, name, group):
self.tx = self.getByName(name)

if not self.tx:
self.tx = self.create(name, group)

self.tx.load()

return self.tx

def createImpl(self, name, handle, group, isManual, loader, createParams):
self.textfile = TextFile(self, name, handle, group, isManual, loader)
return self.textfile

def removeImpl(self, resource):
pass

def unloadAll(self):
pass

class ManualTextFileLoader(ogre.ManualResourceLoader):
def loadResource(self, resource):
resource.setString("manually loaded")

def getPluginPath():
""" Return the absolute path to a valid plugins.cfg file.
look in the current directory for plugins.cfg followed by plugins.cfg.nt|linux|mac
If not found look one directory up
"""

paths = [os.path.join(os.getcwd(), 'plugins.cfg'),
os.path.join(os.getcwd(), '..','plugins.cfg'),
]
if os.sys.platform == 'darwin':
paths.insert(1, os.path.join(os.getcwd(), 'plugins.cfg.mac'))
paths.append(os.path.join(os.getcwd(), '..', 'plugins.cfg.mac'))
else:
paths.insert(1,os.path.join(os.getcwd(), 'plugins.cfg.'+os.name))
paths.append(os.path.join(os.getcwd(), '..', 'plugins.cfg.'+os.name))

for path in paths:
if os.path.exists(path):
return path

sys.stderr.write("\n"
"** Warning: Unable to locate a suitable plugins.cfg file.\n"
"** Warning: Please check your ogre installation and copy a\n"
"** Warning: working plugins.cfg file to the current directory.\n\n")
raise ogre.Exception(0, "can't locate a suitable 'plugins' file", "")


class Application(object):
"This class is the base for an Ogre application."
debugText=""

def __init__(self):
self.frameListener = None
self.root = None
self.camera = None
self.renderWindow = None
self.sceneManager = None
self.world = None

self.unittest = False

def __del__(self):
"Clear variables, this should not actually be needed."
del self.camera
del self.sceneManager
del self.frameListener
if self.world:
del self.world
del self.root
del self.renderWindow

def go(self):
"Starts the rendering loop."
if not self._setUp():
return

self.root.startRendering()

def goOneFrame(self):
"Starts the rendering loop. Show how to use the renderOneFrame Method"
if not self._setUp():
return

self.root.getRenderSystem()._initRenderTargets()
while True:
ogre.WindowEventUtilities().messagePump()
if not self.root.renderOneFrame():
break

def _setUp(self):
"""This sets up the ogre application, and returns false if the user
hits "cancel" in the dialog box."""

pluginFile = getPluginPath() ## option here to switch to manually loading file if it doesn't exist
if self.unittest:
if os.path.isfile('ogre.cfg'):
self.root = ogre.Root( pluginFile )
else:
self.root = ogre.Root( pluginFile, '../ogre.cfg')
else:
self.root = ogre.Root( pluginFile )
self.root.setFrameSmoothingPeriod (5.0)

self._setUpResources()
if not self._configure():
return False

self._loadResources()

return True

def _setUpResources(self):
"""This sets up Ogre's resources, which are required to be in
resources.cfg."""

config = ogre.ConfigFile()
try:
config.load('resources.cfg')
except ogre.OgreFileNotFoundException:
try:
config.load('../resources.cfg')
except:
raise
except:
raise

seci = config.getSectionIterator()
while seci.hasMoreElements():
SectionName = seci.peekNextKey()
Section = seci.getNext()
for item in Section:
ogre.ResourceGroupManager.getSingleton().\
addResourceLocation(item.value, item.key, SectionName)

def _loadResources(self):
"""This loads all initial resources. Redefine this if you do not want
to load all resources at startup."""

self.TFM = TextFileManager()
self.RGM = ogre.ResourceGroupManager.getSingleton()
self.RGM.declareResource("hello.txt", "TextFile")

self.RGM.initialiseAllResourceGroups()

textfile = self.TFM.load("hello.txt", ogre.ResourceGroupManager.DEFAULT_RESOURCE_GROUP_NAME)
self.TFM.removeAll()
str = textfile.getString()
pass

def _configure(self):
"""This shows the config dialog and creates the renderWindow."""
if not self.unittest: # we show this if not doing a unittest
carryOn = self.root.showConfigDialog()
else:
carryOn = self.root.restoreConfig()
if carryOn:
windowTitle = os.path.join( os.getcwd(), sys.argv[0])
if not windowTitle:
windotTitle = "Ogre Render Window"
self.renderWindow = self.root.initialise(True,windowTitle)
return carryOn


if __name__ == '__main__':
try:
application = Application()
application.go()
except ogre.OgreException, e:
print e