|
project_directory$ - the project folder an interrupted SaveWorldDocumentSet was saving to finish (optional) - False to put the original files back (default); True to finish the interrupted save instead |
|
Puts a project folder right after a SaveWorldDocumentSet was interrupted. SaveWorldDocumentSet saves carefully: it writes the new files, backups of the old ones and a journal into a .b3d-save-journal folder first, and only then replaces the files one by one. If the program, the computer or the disk stops part-way, the journal is left behind. RecoverWorldDocumentSet then puts every original file back and removes the files the save had created - or, with finish True, completes the save. Every backup and destination is checked before anything is written, and recovery refuses to overwrite a file that someone changed since. Afterwards, open the affected documents again: recovery changes the files on disk, not documents you already have open. Look for the journal folder first; with no interrupted save there is nothing to recover, and it returns False: If FileType("MyProject/.b3d-save-journal")=2 Then RecoverWorldDocumentSet "MyProject" Returns True, or False with the reason in WorldDocumentError(). From the command line, b3dworldc --recover folder rollback (or finish) does the same, as does the World Editor's File > Recover Interrupted Save. For the full story - the edit protocol, Save All, recovery, export plans and limits - see the Saving and exporting resource projects guide. See also: SaveWorldDocumentSet, ExportWorldProject, WorldDocumentError, FileType. |
; SaveWorldDocumentSet Example
; ----------------------------
Print "This example saves a tiny project into demo_project next to itself,"
Print "exports a copy into demo_export, then deletes both folders."
Print "Press Y to continue, any other key to skip."
WaitKey
If KeyDown(21)
; A world that uses a paint material: the project's first two files
CreateDir "demo_project"
paint_text$="{'format':'blitz3d.material','version':1,'id':'paint','assets':[],"
paint_text=Replace(paint_text+"'definition':{'model':'classic','color':[0.2,0.5,0.9,1]}}","'",Chr(34))
scene_text$="{'format':'blitz3d.world','version':1,'id':'scene','entities':[],"
scene_text=scene_text+"'assets':[{'id':'paint','kind':'material','source':'paint.material','loading':'required'}]}"
WriteTextAtomic "demo_project/paint.material",paint_text
WriteTextAtomic "demo_project/scene.world",Replace(scene_text,"'",Chr(34))
world=LoadWorldDocument("demo_project/scene.world")
paint=LoadResourceDocument("demo_project/paint.material")
; Repaint the material in memory: a draft that is not saved yet
ReplaceResourceDocumentSource paint,Replace(paint_text,"0.2,0.5,0.9","0.9,0.3,0.1"),ResourceDocumentRevision(paint)
Print ""
Print "Before saving, the paint draft is dirty: "+ResourceDocumentDirty(paint)
; Save the world and the paint together, as one checked set
text$="[{'document':"+paint+",'revision':"+ResourceDocumentRevision(paint)+"}]"
drafts=ParseJson(Replace(text,"'",Chr(34)))
If Not SaveWorldDocumentSet(world,drafts,WorldDocumentRevision(world),"demo_project") Then RuntimeError WorldDocumentError()
FreeJson drafts
Print "SaveWorldDocumentSet returned True; the paint is dirty: "+ResourceDocumentDirty(paint)
; A save that was cut short leaves a journal folder to recover from
If FileType("demo_project/.b3d-save-journal")=2 Then
If Not RecoverWorldDocumentSet("demo_project") Then RuntimeError WorldDocumentError()
Print "Recovered an interrupted save"
Else
Print "No save was interrupted, so RecoverWorldDocumentSet has nothing to do"
EndIf
; Export the world and everything it needs into a new folder
text="{'format':'blitz3d.resource-export','version':1,'projectRoot':'.','roots':['scene.world']}"
WriteTextAtomic "demo_project/export.json",Replace(text,"'",Chr(34))
manifest=ExportWorldProject("demo_project/export.json","demo_export")
If manifest=0 Then RuntimeError WorldDocumentError()
files=JsonObjectGet(manifest,"files")
Print "ExportWorldProject copied "+JsonCount(files)+" files into demo_export"
FreeJson files
FreeJson manifest
FreeResourceDocument paint
FreeWorldDocument world
RemoveDemoFolder("demo_export")
RemoveDemoFolder("demo_project")
Print "Demo folders deleted"
Else
Print "Skipped"
EndIf
Print ""
Print "Press any key to close the example"
WaitKey
End
; Delete a folder this example made, with the files in it
Function RemoveDemoFolder(folder$)
listing=ReadDir(folder)
Repeat
file$=NextFile(listing)
If FileType(folder+"/"+file)=1 Then DeleteFile folder+"/"+file
Until file=""
CloseDir listing
DeleteDir folder
End Function