mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 02:42:49 -04:00
simpler spec autosave/backup
This commit is contained in:
parent
8326fd6198
commit
a9aaed8d15
@ -20,7 +20,6 @@ class DistributedLevelAI(DistributedObjectAI.DistributedObjectAI,
|
||||
self.zoneId = zoneId
|
||||
if __debug__:
|
||||
self.modified = 0
|
||||
self.makeBackup = 1
|
||||
|
||||
def generate(self, levelSpec):
|
||||
self.notify.debug('generate')
|
||||
@ -41,7 +40,7 @@ class DistributedLevelAI(DistributedObjectAI.DistributedObjectAI,
|
||||
def delete(self):
|
||||
self.notify.debug('delete')
|
||||
if __debug__:
|
||||
self.saveSpec()
|
||||
self.removeBackupTask()
|
||||
self.destroyLevel()
|
||||
DistributedObjectAI.DistributedObjectAI.delete(self)
|
||||
|
||||
@ -103,35 +102,43 @@ class DistributedLevelAI(DistributedObjectAI.DistributedObjectAI,
|
||||
self.levelSpec.setAttribChange(entId, attribName, value, username)
|
||||
|
||||
self.modified = 1
|
||||
self.scheduleSave()
|
||||
self.scheduleAutosave()
|
||||
|
||||
SavePeriod = simbase.config.GetInt('factory-save-period', 10)
|
||||
BackupPeriod = simbase.config.GetInt('factory-backup-period-minutes',5)
|
||||
# backups are made every N minutes, starting from the time that
|
||||
# the first edit is made
|
||||
AutosavePeriod = simbase.config.GetFloat(
|
||||
'level-autosave-period-minutes', 5)
|
||||
|
||||
def scheduleSave(self):
|
||||
if hasattr(self, 'saveTask'):
|
||||
def scheduleAutosave(self):
|
||||
if hasattr(self, 'autosaveTask'):
|
||||
return
|
||||
self.saveTask = taskMgr.doMethodLater(
|
||||
DistributedLevelAI.SavePeriod,
|
||||
self.saveSpec,
|
||||
self.uniqueName('saveSpec'))
|
||||
self.autosaveTaskName = self.uniqueName('saveSpec')
|
||||
self.autosaveTask = taskMgr.doMethodLater(
|
||||
DistributedLevelAI.AutosavePeriod * 60,
|
||||
self.autosaveSpec,
|
||||
self.autosaveTaskName)
|
||||
|
||||
def removeAutosaveTask(self):
|
||||
if hasattr(self, 'autosaveTask'):
|
||||
taskMgr.remove(self.autosaveTaskName)
|
||||
del self.autosaveTask
|
||||
|
||||
def autosaveSpec(self, task=None):
|
||||
self.removeAutosaveTask()
|
||||
if self.modified:
|
||||
DistributedLevelAI.notify.info('autosaving spec')
|
||||
filename = self.levelSpec.getFilename()
|
||||
filename = '%s.autosave' % filename
|
||||
self.levelSpec.saveToDisk(filename, makeBackup=0)
|
||||
|
||||
def saveSpec(self, task=None):
|
||||
DistributedLevelAI.notify.info('saving spec')
|
||||
if hasattr(self, 'saveTask'):
|
||||
del self.saveTask
|
||||
self.removeAutosaveTask()
|
||||
if not self.modified:
|
||||
DistributedLevelAI.notify.info('no changes to save')
|
||||
return
|
||||
self.levelSpec.saveToDisk(createBackup=self.makeBackup)
|
||||
self.levelSpec.saveToDisk()
|
||||
self.modified = 0
|
||||
self.makeBackup = 0
|
||||
def setMakeBackup(task, self=self):
|
||||
self.makeBackup = 1
|
||||
self.backupTask = taskMgr.doMethodLater(
|
||||
DistributedLevelAI.BackupPeriod * 60,
|
||||
setMakeBackup,
|
||||
self.uniqueName('setMakeBackup'))
|
||||
|
||||
def requestCurrentLevelSpec(self, specHash, entTypeRegHash):
|
||||
senderId = self.air.msgSender
|
||||
|
@ -3,6 +3,8 @@
|
||||
import DirectNotifyGlobal
|
||||
from PythonUtil import list2dict, uniqueElements
|
||||
import string
|
||||
if __debug__:
|
||||
import os
|
||||
|
||||
class LevelSpec:
|
||||
"""contains spec data for a level, is responsible for handing the data
|
||||
@ -138,42 +140,32 @@ class LevelSpec:
|
||||
# name of module that should be imported by spec py file
|
||||
return 'SpecImports'
|
||||
|
||||
def saveToDisk(self, filename=None, createBackup=1):
|
||||
"""returns zero on failure"""
|
||||
import os
|
||||
def getFilename(self):
|
||||
return self.filename
|
||||
|
||||
def privGetBackupFilename(self):
|
||||
return '%s.bak' % self.getFilename()
|
||||
|
||||
def saveToDisk(self, filename=None, makeBackup=1):
|
||||
"""returns zero on failure"""
|
||||
if filename is None:
|
||||
filename = self.filename
|
||||
|
||||
if createBackup:
|
||||
if makeBackup and self.privFileExists(filename):
|
||||
# create a backup
|
||||
try:
|
||||
# does the file exist?
|
||||
exists = 0
|
||||
try:
|
||||
os.stat(filename)
|
||||
exists = 1
|
||||
except OSError:
|
||||
pass
|
||||
if exists:
|
||||
def getBackupFilename(num, filename=filename):
|
||||
return '%s.%03i' % (filename, num)
|
||||
numBackups = 200
|
||||
try:
|
||||
os.unlink(getBackupFilename(numBackups-1))
|
||||
except OSError:
|
||||
pass
|
||||
for i in range(numBackups-1,0,-1):
|
||||
try:
|
||||
os.rename(getBackupFilename(i-1),
|
||||
getBackupFilename(i))
|
||||
except OSError:
|
||||
pass
|
||||
os.rename(filename, getBackupFilename(0))
|
||||
backupFilename = self.privGetBackupFilename()
|
||||
self.privRemoveFile(backupFilename)
|
||||
os.rename(filename, backupFilename)
|
||||
except OSError, e:
|
||||
LevelSpec.notify.warning(
|
||||
'error during backup: %s' % str(e))
|
||||
|
||||
self.privRemoveFile(filename)
|
||||
self.privSaveToDisk(filename)
|
||||
|
||||
def privSaveToDisk(self, filename):
|
||||
"""internal. saves spec to file. returns zero on failure"""
|
||||
retval = 1
|
||||
# wb to create a UNIX-format file
|
||||
f = file(filename, 'wb')
|
||||
@ -184,6 +176,20 @@ class LevelSpec:
|
||||
f.close()
|
||||
return retval
|
||||
|
||||
def privFileExists(self, filename):
|
||||
try:
|
||||
os.stat(filename)
|
||||
return 1
|
||||
except OSError:
|
||||
return 0
|
||||
|
||||
def privRemoveFile(self, filename):
|
||||
try:
|
||||
os.remove(filename)
|
||||
return 1
|
||||
except OSError:
|
||||
return 0
|
||||
|
||||
def getPrettyString(self):
|
||||
"""Returns a string that contains the spec data, nicely formatted.
|
||||
This should be used when writing the spec out to file."""
|
||||
|
Loading…
x
Reference in New Issue
Block a user