import { WWASaveConsts , WWAData } from "../wwa_data" ; import WWACompress from "./WWACompress" ; import WWASave from "./WWASave" ; import WWASaveDataDB from "./WWASaveDataDB" ; import WWASaveDataList from "./WWASaveDataList" ; import { LoadErrorCode , OnCheckLoadingSaveDataFunction , OnCompleteLoadingSaveDataFunction } from "./common" ; type WWASaveDataItem = { url ? : string ; id : number ; hash : string ; image : string ; data : object ; date : Date ; worldName : string | undefined ; mapDataRevisionKey : string | undefined ; } ; type FailedLoadingSaveDataInformation = { id : number ; cause : LoadErrorCode ; } ; export default class WWASaveDataDBList extends WWASaveDataList { private selectDatas : object [ ] ; private selectLoad : boolean = false ; private indexedDB : IDBFactory = window [ "indexedDB" ] || window [ "webkitIndexedDB" ] || window [ "mozIndexedDB" ] ; private IDBTransaction : object = { READ_ONLY : "readonly" , READ_WRITE : "readwrite" , VERSION_CHANGE : "versionchangetransaction" } ; see WWASave private onCheckLoadingSaveData : OnCheckLoadingSaveDataFunction ; private onCompleteLoadingSaveData : OnCompleteLoadingSaveDataFunction ; /**
     * 何もしません。主に IndexedDB のイベントに割り当てる際に使用します。
     */ private static doNotAnything = ( ) => { } ; /**
     * データベース作成時に指定する keyPath です。
     * TypeScript には IDBKeyPath という専用の型が付与されていますが、 string 型しか受け付けておりません。
     * 代わりに独自の型を定義しています。
     */ protected keyPath : string | string [ ] = [ "id" , "url" ] ; constructor ( onCheckLoadingSaveData , onCompleteLoadingSaveData , prototype = WWASaveDataDBList . prototype ) { super ( ) ; Object . setPrototypeOf ( this , Object . create ( prototype ) ) ; for ( var i = 0 ; i < WWASaveConsts . QUICK_SAVE_MAX ; i ++ ) { this [ i ] = new WWASaveDataDB ( i , this ) ; } if ( this . indexedDB ) { try { if ( this . indexedDB . open ) { } else { this . indexedDB = null ; } } catch ( e ) { this . indexedDB = null ; } } try { var databaselog = this . indexedDB . open ( 'test' ) ; if ( databaselog . error ) { this . indexedDB = null ; } } catch ( e ) { } if ( ! this . indexedDB ) { return ; } this . onCheckLoadingSaveData = onCheckLoadingSaveData ; this . onCompleteLoadingSaveData = onCompleteLoadingSaveData ; this . createDataBase ( ) ; this . selectSaveData ( ) ; } /**
     *  IE/EDGEでgetAll関数が存在しなく、ロード失敗するため挙動をエミュレートする
     */ private getAlEmulate ( ) { var getAll = function ( query ) { var queryResult = this . openCursor ( query ) ; var dataList = [ ] ; var callBackResult = { onsuccess : null , onerror : null } ; queryResult . onsuccess = ( e ) => { var cursor = e . target . result ; if ( cursor === null ) { var callBackEvent = { target : { result : dataList } } ; if ( typeof callBackResult . onsuccess === "function" ) { callBackResult . onsuccess ( callBackEvent ) ; } } else { dataList . push ( e . target . result . value ) ; cursor . continue ( ) ; } } ; queryResult . onerror = ( e ) => { if ( typeof callBackResult . onerror === "function" ) { callBackResult . onerror ( e ) ; } } ; return callBackResult ; } ; if ( window . IDBIndex . prototype . getAll === undefined ) { window . IDBIndex . prototype . getAll = getAll ; } if ( window . IDBObjectStore . prototype . getAll === undefined ) { window . IDBObjectStore . prototype . getAll = getAll ; } } private indexDBOpen ( ) { this . getAlEmulate ( ) ; return this . indexedDB . open ( WWASaveConsts . INDEXEDDB_DB_NAME , 201205201 ) ; } private createDataBase ( ) { try { var reqOpen = this . indexDBOpen ( ) ; reqOpen . onupgradeneeded = ( e ) => { var indexedDBSystem = reqOpen . result ; var oDBOptions = { keyPath : this . keyPath } ; if ( ! indexedDBSystem . objectStoreNames . contains ( WWASaveConsts . INDEXEDDB_TABLE_NAME ) ) { var objectStore = indexedDBSystem . createObjectStore ( WWASaveConsts . INDEXEDDB_TABLE_NAME , oDBOptions ) ; objectStore . createIndex ( "url" , "url" , { unique : false } ) ; } } ; reqOpen . onsuccess = WWASaveDataDBList . doNotAnything ; reqOpen . onerror = WWASaveDataDBList . doNotAnything ; reqOpen . onblocked = ( err ) => { this . indexedDB = null ; } ; } catch ( error ) { } } todo private getObjectStore ( requestResult ) { const indexedDBSystem = requestResult ; try { var transaction = indexedDBSystem . transaction ( WWASaveConsts . INDEXEDDB_TABLE_NAME , this . IDBTransaction [ "READ_WRITE" ] ) ; var store = transaction . objectStore ( WWASaveConsts . INDEXEDDB_TABLE_NAME ) ; } catch ( error ) { return ; } return store ; } param saveID param gameCvs param compressedData param date returns protected makeSaveDataItem ( saveID , gameCvs , compressedData , date ) { return { "url" : location . href , "id" : saveID , "hash" : WWASave . checkOriginalMapString , "image" : gameCvs . toDataURL ( ) , "data" : compressedData , "date" : date , "worldName" : WWASave . worldName , "mapDataRevisionKey" : WWASave . mapDataRevisionKey } ; } /**
     * 現在プレイしている WWA のセーブデータを取り出します。
     */ protected getSaveDataResult ( store , onsuccess ) { const index = store . index ( "url" ) ; const range = IDBKeyRange . only ( location . href ) ; const result = index . getAll ( range ) ; result . onsuccess = ( ) => { onsuccess ( result . result ) ; } ; result . onerror = ( ) => { this . indexedDB = null ; } ; } public dbUpdateSaveData ( saveID , gameCvs , _quickSaveData , date ) { if ( ! this . indexedDB ) { return ; } var reqOpen = this . indexDBOpen ( ) ; reqOpen . onupgradeneeded = WWASaveDataDBList . doNotAnything ; reqOpen . onsuccess = ( e ) => { const store = this . getObjectStore ( reqOpen . result ) ; var compressData = WWACompress . compress ( _quickSaveData ) ; var addData = this . makeSaveDataItem ( saveID , gameCvs , compressData , date ) ; this . selectDatas [ saveID ] = addData ; try { var reqAdd = store . put ( addData ) ; } catch ( error ) { return ; } reqAdd . onsuccess = WWASaveDataDBList . doNotAnything ; reqAdd . onerror = WWASaveDataDBList . doNotAnything ; } ; reqOpen . onerror = WWASaveDataDBList . doNotAnything ; reqOpen . onblocked = WWASaveDataDBList . doNotAnything ; } param saveIDs public dbDeleteSaveData ( saveIDs ) { if ( ! this . indexedDB ) { return ; } const reqOpen = this . indexDBOpen ( ) ; reqOpen . onupgradeneeded = WWASaveDataDBList . doNotAnything ; reqOpen . onsuccess = ( ) => { const store = this . getObjectStore ( reqOpen . result ) ; saveIDs . forEach ( saveId => { store . delete ( [ saveId , location . href ] ) ; } ) ; } ; reqOpen . onerror = WWASaveDataDBList . doNotAnything ; reqOpen . onblocked = WWASaveDataDBList . doNotAnything ; } private selectSaveData ( ) { if ( ! this . indexedDB ) { return ; } var reqOpen = this . indexDBOpen ( ) ; reqOpen . onupgradeneeded = WWASaveDataDBList . doNotAnything ; reqOpen . onsuccess = ( ) => { const store = this . getObjectStore ( reqOpen . result ) ; this . selectDatas = [ ] ; this . selectLoad = false ; const onsuccess = ( result ) => { var i , len , saveData ; let failedLoadingSaveData = [ ] ; len = result . length ; for ( i = 0 ; i < len ; i ++ ) { var resultData = result [ i ] ; try { saveData = { id : resultData . id , hash : resultData . hash , data : resultData . data , date : resultData . date , image : resultData . image , worldName : resultData . worldName , mapDataRevisionKey : resultData . mapDataRevisionKey } ; } catch ( error ) { continue ; } const failedCause = this . onCheckLoadingSaveData ( saveData . worldName , saveData . hash , saveData . mapDataRevisionKey ) ; if ( failedCause !== null ) { failedLoadingSaveData . push ( { id : saveData . id , cause : failedCause } ) ; continue ; } if ( ! this [ saveData . id ] ) { continue ; } const [ quickSaveData ] = WWACompress . decompress ( saveData . data ) ; this [ saveData . id ] . saveDataSet ( saveData . image , quickSaveData , saveData . date ) ; } if ( failedLoadingSaveData . length > 0 ) { this . dbDeleteSaveData ( failedLoadingSaveData . map ( data => data . id ) ) ; } this . selectLoad = true ; const failedLoadingCauses = failedLoadingSaveData . map ( data => data . cause ) . filter ( ( cause , index , self ) => { return self . indexOf ( cause ) === index ; } ) ; this . onCompleteLoadingSaveData ( failedLoadingCauses ) ; } ; this . getSaveDataResult ( store , onsuccess ) ; } ; reqOpen . onerror = WWASaveDataDBList . doNotAnything ; reqOpen . onblocked = WWASaveDataDBList . doNotAnything ; } }