internal NativeConflictResolver(GooglePlayGames.Native.PInvoke.SnapshotManager manager, string conflictId, NativeSnapshotMetadata original, NativeSnapshotMetadata unmerged, Action <SavedGameRequestStatus, ISavedGameMetadata> completeCallback, Action retryOpen) { mManager = Misc.CheckNotNull(manager); mConflictId = Misc.CheckNotNull(conflictId); mOriginal = Misc.CheckNotNull(original); mUnmerged = Misc.CheckNotNull(unmerged); mCompleteCallback = Misc.CheckNotNull(completeCallback); mRetryFileOpen = Misc.CheckNotNull(retryOpen); }
internal NativeConflictResolver(SnapshotManager manager, string conflictId, NativeSnapshotMetadata original, NativeSnapshotMetadata unmerged, Action <SavedGameRequestStatus, ISavedGameMetadata> completeCallback, Action retryOpen) { this.mManager = bubble.CheckNotNull(manager); this.mConflictId = bubble.CheckNotNull(conflictId); this.mOriginal = bubble.CheckNotNull(original); this.mUnmerged = bubble.CheckNotNull(unmerged); this.mCompleteCallback = bubble.CheckNotNull(completeCallback); this.mRetryFileOpen = bubble.CheckNotNull(retryOpen); }
public void CommitUpdate(ISavedGameMetadata metadata, SavedGameMetadataUpdate updateForMetadata, byte[] updatedBinaryData, Action <SavedGameRequestStatus, ISavedGameMetadata> callback) { Misc.CheckNotNull(metadata); Misc.CheckNotNull(updatedBinaryData); Misc.CheckNotNull(callback); callback = ToOnGameThread(callback); NativeSnapshotMetadata convertedMetadata = metadata as NativeSnapshotMetadata; if (convertedMetadata == null) { Logger.e("Encountered metadata that was not generated by this ISavedGameClient"); callback(SavedGameRequestStatus.BadInputError, null); return; } if (!convertedMetadata.IsOpen) { Logger.e("This method requires an open ISavedGameMetadata."); callback(SavedGameRequestStatus.BadInputError, null); return; } mSnapshotManager.Commit(convertedMetadata, AsMetadataChange(updateForMetadata), updatedBinaryData, response => { if (!response.RequestSucceeded()) { callback(AsRequestStatus(response.ResponseStatus()), null); } else { callback(SavedGameRequestStatus.Success, response.Data()); } } ); }
private void InternalManualOpen(string filename, DataSource source, bool prefetchDataOnConflict, ConflictCallback conflictCallback, Action <SavedGameRequestStatus, ISavedGameMetadata> completedCallback) { mSnapshotManager.Open(filename, AsDataSource(source), Types.SnapshotConflictPolicy.MANUAL, delegate(GooglePlayGames.Native.PInvoke.SnapshotManager.OpenResponse response) { if (!response.RequestSucceeded()) { completedCallback(AsRequestStatus(response.ResponseStatus()), null); } else if (response.ResponseStatus() == CommonErrorStatus.SnapshotOpenStatus.VALID) { completedCallback(SavedGameRequestStatus.Success, response.Data()); } else if (response.ResponseStatus() == CommonErrorStatus.SnapshotOpenStatus.VALID_WITH_CONFLICT) { NativeSnapshotMetadata original = response.ConflictOriginal(); NativeSnapshotMetadata unmerged = response.ConflictUnmerged(); NativeConflictResolver resolver = new NativeConflictResolver(mSnapshotManager, response.ConflictId(), original, unmerged, completedCallback, delegate { InternalManualOpen(filename, source, prefetchDataOnConflict, conflictCallback, completedCallback); }); if (!prefetchDataOnConflict) { conflictCallback(resolver, original, null, unmerged, null); } else { Prefetcher @object = new Prefetcher(delegate(byte[] originalData, byte[] unmergedData) { conflictCallback(resolver, original, originalData, unmerged, unmergedData); }, completedCallback); mSnapshotManager.Read(original, @object.OnOriginalDataRead); mSnapshotManager.Read(unmerged, @object.OnUnmergedDataRead); } } else { Logger.e("Unhandled response status"); completedCallback(SavedGameRequestStatus.InternalError, null); } }); }
public void ReadBinaryData(ISavedGameMetadata metadata, Action <SavedGameRequestStatus, byte[]> completedCallback) { bubble.CheckNotNull(metadata); bubble.CheckNotNull(completedCallback); completedCallback = ToOnGameThread(completedCallback); NativeSnapshotMetadata convertedMetadata = metadata as NativeSnapshotMetadata; if (convertedMetadata == null) { Logger.e("Encountered metadata that was not generated by this ISavedGameClient"); completedCallback(SavedGameRequestStatus.BadInputError, null); return; } if (!convertedMetadata.IsOpen) { Logger.e("This method requires an open ISavedGameMetadata."); completedCallback(SavedGameRequestStatus.BadInputError, null); return; } mSnapshotManager.Read(convertedMetadata, response => { if (!response.RequestSucceeded()) { completedCallback(AsRequestStatus(response.ResponseStatus()), null); } else { completedCallback(SavedGameRequestStatus.Success, response.Data()); } } ); }
public void ChooseMetadata(ISavedGameMetadata chosenMetadata) { NativeSnapshotMetadata nativeSnapshotMetadata = chosenMetadata as NativeSnapshotMetadata; if (nativeSnapshotMetadata != mOriginal && nativeSnapshotMetadata != mUnmerged) { Logger.e("Caller attempted to choose a version of the metadata that was not part of the conflict"); mCompleteCallback(SavedGameRequestStatus.BadInputError, null); } else { mManager.Resolve(nativeSnapshotMetadata, new NativeSnapshotMetadataChange.Builder().Build(), mConflictId, delegate(GooglePlayGames.Native.PInvoke.SnapshotManager.CommitResponse response) { if (!response.RequestSucceeded()) { mCompleteCallback(AsRequestStatus(response.ResponseStatus()), null); } else { mRetryFileOpen(); } }); } }
public void ChooseMetadata(ISavedGameMetadata chosenMetadata) { NativeSnapshotMetadata metadata = chosenMetadata as NativeSnapshotMetadata; if (metadata != this.mOriginal && metadata != this.mUnmerged) { Logger.e("Caller attempted to choose a version of the metadata that was not part of the conflict"); this.mCompleteCallback(SavedGameRequestStatus.BadInputError, (ISavedGameMetadata)null); } else { this.mManager.Resolve(metadata, new NativeSnapshotMetadataChange.Builder().Build(), this.mConflictId, (Action <GooglePlayGames.Native.PInvoke.SnapshotManager.CommitResponse>)(response => { if (!response.RequestSucceeded()) { this.mCompleteCallback(NativeSavedGameClient.AsRequestStatus(response.ResponseStatus()), (ISavedGameMetadata)null); } else { this.mRetryFileOpen(); } })); } }
private void InternalOpen(string filename, DataSource source, ConflictResolutionStrategy resolutionStrategy, bool prefetchDataOnConflict, ConflictCallback conflictCallback, Action <SavedGameRequestStatus, ISavedGameMetadata> completedCallback) { Types.SnapshotConflictPolicy policy; switch (resolutionStrategy) { case ConflictResolutionStrategy.UseLastKnownGood: policy = Types.SnapshotConflictPolicy.LAST_KNOWN_GOOD; break; case ConflictResolutionStrategy.UseMostRecentlySaved: policy = Types.SnapshotConflictPolicy.MOST_RECENTLY_MODIFIED; break; case ConflictResolutionStrategy.UseLongestPlaytime: policy = Types.SnapshotConflictPolicy.LONGEST_PLAYTIME; break; case ConflictResolutionStrategy.UseManual: policy = Types.SnapshotConflictPolicy.MANUAL; break; default: policy = Types.SnapshotConflictPolicy.MOST_RECENTLY_MODIFIED; break; } mSnapshotManager.Open(filename, AsDataSource(source), policy, response => { if (!response.RequestSucceeded()) { completedCallback(AsRequestStatus(response.ResponseStatus()), null); } else if (response.ResponseStatus() == Status.SnapshotOpenStatus.VALID) { completedCallback(SavedGameRequestStatus.Success, response.Data()); } else if (response.ResponseStatus() == Status.SnapshotOpenStatus.VALID_WITH_CONFLICT) { // If we get here, manual conflict resolution is required. NativeSnapshotMetadata original = response.ConflictOriginal(); NativeSnapshotMetadata unmerged = response.ConflictUnmerged(); // Instantiate the conflict resolver. Note that the retry callback closes over // all the parameters we need to retry the open attempt. Once the conflict is // resolved by invoking the appropriate resolution method on // NativeConflictResolver, the resolver will invoke this callback, which will // result in this method being re-executed. This recursion will continue until // all conflicts are resolved or an error occurs. NativeConflictResolver resolver = new NativeConflictResolver( mSnapshotManager, response.ConflictId(), original, unmerged, completedCallback, () => InternalOpen(filename, source, resolutionStrategy, prefetchDataOnConflict, conflictCallback, completedCallback) ); // If we don't have to pre-fetch the saved games' binary data, we can // immediately invoke the conflict callback. Note that this callback is // constructed to execute on the game thread in // OpenWithManualConflictResolution. if (!prefetchDataOnConflict) { conflictCallback(resolver, original, null, unmerged, null); return; } // If we have to prefetch the data, we delegate invoking the conflict resolution // callback to the joiner instance (once both callbacks resolve, the joiner will // invoke the lambda that we declare here, using the fetched data). Prefetcher joiner = new Prefetcher((originalData, unmergedData) => conflictCallback(resolver, original, originalData, unmerged, unmergedData), completedCallback); // Kick off the read calls. mSnapshotManager.Read(original, joiner.OnOriginalDataRead); mSnapshotManager.Read(unmerged, joiner.OnUnmergedDataRead); } else { Logger.e("Unhandled response status"); completedCallback(SavedGameRequestStatus.InternalError, null); } }); }