データを保存およびロードする — サンプル コード - Stingray Lua API リファレンス

データを保存およびロードする — サンプル コード

説明

この例では、stingray.SaveSystem インタフェースを使用してディスク上のファイルにランタイム データを保存し、後でプロジェクトに読み込み直す方法を示します。

保存およびロードのいずれの操作でもハード ディスクへのアクセスが発生するため、速度が低下する可能性があります。したがって、保存とロードはどちらも非同期操作となり、コード内の次の行が実行を継続している間にバックグラウンドで処理されます。実際は、以降のフレームになるまで操作が終了しない可能性があります。つまり、データを即座に使用できなくなります。フレームごとに stingray.SaveSystem を使用して、操作が終了しているかどうかを確認する必要があります。

stingray.SaveSystem に一部のデータを保存またはロードするよう要求するたびに、この特定の要求を識別するトークンが提供されます。要求を行ったら、stingray.SaveSystem.progress() を呼び出してトークンを渡し、この要求のステータスを含むテーブルを取得します。stingray.SaveSystem にデータをロードするよう要求した場合は、このステータス テーブルの .data フィールドにロードされたデータも格納されます。

保存またはロード要求が完了し、ステータス テーブルからデータを読み取ったら、stingray.SaveSystem.close() を呼び出してトークンを渡し、この要求で使用されているメモリをクリアする必要があります。

このシンプルなサンプルでは、9 および 0 キーを使用して保存およびロードをそれぞれトリガします。

コード


-- cache tokens in variables that will persist to future frames
save_filename = "my_data_file"
save_token = nil
load_token = nil

-- this update code is taken from a `project.lua` file in one of the standard Stingray template projects that
-- uses the Appkit.
function Project.update(dt)

    -- some data to test our save and load code.
    -- replace this with your own data.
    local data_to_save = {
        string_field = "hello world!",
        table_field = {
            boolean_one = true,
            boolean_two = false
        }
        -- let's use a random number that gets re-generated each frame, so we can tell
        -- that we're loading the same data we last saved.
        number_field = stingray.Math.random(0,100),
    }

    -- translate error codes into something human-readable and log them.
    function handle_error(code)
        if save_progress.error == "STINGRAY_SAVEDATA_ERROR_MISSING" then
            print("The file you're looking for does not exist.")
        elseif save_progress.error == "STINGRAY_SAVEDATA_INVALID_FILENAME" then
            print("The filename you've asked for isn't valid on this platform.")
        elseif save_progress.error == "STINGRAY_SAVEDATA_IO_ERROR" then
            print("A disk error occurred reading or writing data.")
        elseif save_progress.error == "STINGRAY_SAVEDATA_BROKEN" then
            print("Your save data seems to be corrupted.")
        elseif save_progress.error == "STINGRAY_SAVEDATA_UNSUPPORTED_VERSION" then
            print("The data was saved using an older version of Stingray, and isn't compatible with this version.")
        end
    end

    -- this helper function checks the different states a progress token can have, and
    -- decides how to handle each one.
    function check_token(token)
        if token then
            local save_progress = stingray.SaveSystem.progress(token)
            if not save_progress then return end
            if save_progress.error then
                print("An error occurred in the save or load operation!")
                handle_error(save_progress.error)
            elseif save_progress.done then
                print("Completed.")
                stingray.SaveSystem.close(token)
                -- For load operations, we return the loaded data.
                -- For save operations, we return true to indicate the token has been cleared.
                return save_progress.data or true
            elseif save_progress.progress > 0 then
                local percentage = save_progress.progress * 100
                print(tostring(percentage) .. "% completed.")
            end
        end
        return false
    end

    -- when the project needs to save some data:
    -- if a save isn't already in progress, start one and get a token.
    if stingray.Keyboard.pressed(stingray.Keyboard.button_id("9")) and not save_token then
        save_token = stingray.SaveSystem.auto_save(save_filename, data_to_save)
        print("The saved random number is: " .. tostring(data_to_save.number_field))
    end
    -- if a save is currently in progress:
    if save_token then
        -- if the save operation is done, clear the cached token.
        if check_token(save_token) then save_token = nil end
    end

    -- when the project needs to load some data:
    -- if a load isn't already in progress, start one and get a token.
    if stingray.Keyboard.pressed(stingray.Keyboard.button_id("0")) and not load_token then
        load_token = stingray.SaveSystem.auto_load(save_filename)
    end
    -- if a load is currently in progress:
    if load_token then
        -- if the load operation is done
        local retrieved_data = check_token(load_token)
        if retrieved_data then
            -- clear the cached token
            load_token = nil
            -- and do something with the data read from the save file.
            -- replace this with your own code.
            print("Data retrieved.")
            print("String field: " .. retrieved_data.string_field)
            print("Number field: " .. tostring(retrieved_data.number_field))
            print("The number should match the last saved number shown in the console log.")
            print("Nested boolean field one: " .. tostring(retrieved_data.table_field.boolean_one))
            print("Nested boolean field two: " .. tostring(retrieved_data.table_field.boolean_two))
        end
    end

end