RecoverWorldDocumentSet ( project_directory$[,finish] )

Parameters

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

Description

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.

Example

; 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

Index