Fixup bad threading (no, you cannot access rcheevo's _runtime in a separate thread! main thread use only!). Should fix up some random crashes
Slightly change up the request model, now InternalDoRequest does not block Fixup logic of ToSoftcoreMode (and comments so it isn't screwed up again)
This commit is contained in:
parent
8ef1d93891
commit
248b8ab984
|
@ -145,50 +145,62 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
_activeModeUnlocksRequest.Wait();
|
||||
|
||||
foreach (var cheevo in _gameData.CheevoEnumerable)
|
||||
{
|
||||
if (cheevo.IsEnabled && !cheevo.IsUnlocked(HardcoreMode))
|
||||
{
|
||||
_lib.rc_runtime_deactivate_achievement(ref _runtime, cheevo.ID);
|
||||
}
|
||||
}
|
||||
|
||||
DeactivateCheevos(HardcoreMode);
|
||||
AllowUnofficialCheevos ^= true;
|
||||
|
||||
foreach (var cheevo in _gameData.CheevoEnumerable)
|
||||
{
|
||||
if (cheevo.IsEnabled && !cheevo.IsUnlocked(HardcoreMode))
|
||||
{
|
||||
_lib.rc_runtime_activate_achievement(ref _runtime, cheevo.ID, cheevo.Definition, IntPtr.Zero, 0);
|
||||
}
|
||||
}
|
||||
ActivateCheevos(HardcoreMode);
|
||||
}
|
||||
|
||||
private void ToSoftcoreMode()
|
||||
{
|
||||
if (_gameData == null || _gameData.GameID == 0) return;
|
||||
|
||||
// don't worry if the meanings of _active and _inactive are wrong
|
||||
// if they are, then they're both already finished
|
||||
|
||||
// first deactivate any hardcore cheevos
|
||||
// if _activeModeUnlocksRequest is still active, it's hardcore mode
|
||||
_activeModeUnlocksRequest.Wait();
|
||||
DeactivateCheevos(true);
|
||||
|
||||
// now activate the softcore cheevos
|
||||
// if _inactiveModeUnlocksRequest is still active, it's softcore mode
|
||||
_inactiveModeUnlocksRequest.Wait();
|
||||
ActivateCheevos(false);
|
||||
|
||||
Update();
|
||||
}
|
||||
|
||||
private void DeactivateCheevos(bool hardcore)
|
||||
{
|
||||
foreach (var cheevo in _gameData.CheevoEnumerable)
|
||||
{
|
||||
if (cheevo.IsEnabled && !cheevo.IsUnlocked(false))
|
||||
if (cheevo.IsEnabled && !cheevo.IsUnlocked(hardcore))
|
||||
{
|
||||
_lib.rc_runtime_deactivate_achievement(ref _runtime, cheevo.ID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_activeModeUnlocksRequest.Wait();
|
||||
private bool _activeModeCheevosOnceActivated;
|
||||
|
||||
private void ActivateCheevos(bool hardcore)
|
||||
{
|
||||
foreach (var cheevo in _gameData.CheevoEnumerable)
|
||||
{
|
||||
if (cheevo.IsEnabled && !cheevo.IsUnlocked(true))
|
||||
if (cheevo.IsEnabled && !cheevo.IsUnlocked(hardcore))
|
||||
{
|
||||
_lib.rc_runtime_activate_achievement(ref _runtime, cheevo.ID, cheevo.Definition, IntPtr.Zero, 0);
|
||||
}
|
||||
}
|
||||
|
||||
Update();
|
||||
_activeModeCheevosOnceActivated = true;
|
||||
}
|
||||
|
||||
private void OneShotActivateActiveModeCheevos()
|
||||
{
|
||||
if (_activeModeCheevosOnceActivated) return;
|
||||
_activeModeUnlocksRequest.Wait();
|
||||
ActivateCheevos(HardcoreMode);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -25,7 +25,6 @@ namespace BizHawk.Client.EmuHawk
|
|||
{
|
||||
private LibRCheevos.rc_api_fetch_user_unlocks_request_t _apiParams;
|
||||
private readonly IReadOnlyDictionary<int, Cheevo> _cheevos;
|
||||
private readonly Action _activeModeCallback;
|
||||
|
||||
protected override void ResponseCallback(byte[] serv_resp)
|
||||
{
|
||||
|
@ -43,8 +42,6 @@ namespace BizHawk.Client.EmuHawk
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
_activeModeCallback?.Invoke();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -60,12 +57,10 @@ namespace BizHawk.Client.EmuHawk
|
|||
InternalDoRequest(apiParamsResult, ref api_req);
|
||||
}
|
||||
|
||||
public UserUnlocksRequest(string username, string api_token, int game_id, bool hardcore,
|
||||
IReadOnlyDictionary<int, Cheevo> cheevos, Action activeModeCallback = null)
|
||||
public UserUnlocksRequest(string username, string api_token, int game_id, bool hardcore, IReadOnlyDictionary<int, Cheevo> cheevos)
|
||||
{
|
||||
_apiParams = new(username, api_token, game_id, hardcore);
|
||||
_cheevos = cheevos;
|
||||
_activeModeCallback = activeModeCallback;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -167,9 +162,9 @@ namespace BizHawk.Client.EmuHawk
|
|||
public Cheevo GetCheevoById(int i) => _cheevos[i];
|
||||
public LBoard GetLboardById(int i) => _lboards[i];
|
||||
|
||||
public UserUnlocksRequest InitUnlocks(string username, string api_token, bool hardcore, Action callback = null)
|
||||
public UserUnlocksRequest InitUnlocks(string username, string api_token, bool hardcore)
|
||||
{
|
||||
return new(username, api_token, GameID, hardcore, _cheevos, callback);
|
||||
return new(username, api_token, GameID, hardcore, _cheevos);
|
||||
}
|
||||
|
||||
public IEnumerable<RCheevoHttpRequest> LoadImages()
|
||||
|
@ -301,16 +296,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
private void InitGameData()
|
||||
{
|
||||
_activeModeUnlocksRequest = _gameData.InitUnlocks(Username, ApiToken, HardcoreMode, () =>
|
||||
{
|
||||
foreach (var cheevo in _gameData.CheevoEnumerable)
|
||||
{
|
||||
if (cheevo.IsEnabled && !cheevo.IsUnlocked(HardcoreMode))
|
||||
{
|
||||
_lib.rc_runtime_activate_achievement(ref _runtime, cheevo.ID, cheevo.Definition, IntPtr.Zero, 0);
|
||||
}
|
||||
}
|
||||
});
|
||||
_activeModeUnlocksRequest = _gameData.InitUnlocks(Username, ApiToken, HardcoreMode);
|
||||
_inactiveHttpRequests.Push(_activeModeUnlocksRequest);
|
||||
|
||||
_inactiveModeUnlocksRequest = _gameData.InitUnlocks(Username, ApiToken, !HardcoreMode);
|
||||
|
|
|
@ -112,20 +112,23 @@ namespace BizHawk.Client.EmuHawk
|
|||
: HttpGet(request.URL);
|
||||
apiTask.ConfigureAwait(false);
|
||||
|
||||
_lib.rc_api_destroy_request(ref request);
|
||||
var result = apiTask.Result; // FIXME: THIS IS BAD (but kind of needed?)
|
||||
|
||||
if (result is null) // likely a timeout
|
||||
apiTask.ContinueWith(async t =>
|
||||
{
|
||||
ShouldRetry = true;
|
||||
_completionEvent.Set();
|
||||
return;
|
||||
}
|
||||
var result = await t;
|
||||
if (result is null) // likely a timeout
|
||||
{
|
||||
ShouldRetry = true;
|
||||
_completionEvent.Set();
|
||||
}
|
||||
else
|
||||
{
|
||||
ResponseCallback(result);
|
||||
ShouldRetry = false; // this is a bit naive, but if the response callback "fails," retrying will just result in the same thing
|
||||
_completionEvent.Set();
|
||||
}
|
||||
});
|
||||
|
||||
ResponseCallback(result);
|
||||
|
||||
ShouldRetry = false; // this is a bit naive, but if the response callback "fails," retrying will just result in the same thing
|
||||
_completionEvent.Set();
|
||||
_lib.rc_api_destroy_request(ref request);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -158,14 +161,14 @@ namespace BizHawk.Client.EmuHawk
|
|||
{
|
||||
while (_inactiveHttpRequests.TryPop(out var request))
|
||||
{
|
||||
Task.Run(request.DoRequest);
|
||||
request.DoRequest();
|
||||
_activeHttpRequests.Add(request);
|
||||
}
|
||||
|
||||
foreach (var activeRequest in _activeHttpRequests.Where(activeRequest => activeRequest.IsCompleted && activeRequest.ShouldRetry).ToArray())
|
||||
{
|
||||
activeRequest.Reset();
|
||||
Task.Run(activeRequest.DoRequest);
|
||||
activeRequest.DoRequest();
|
||||
}
|
||||
|
||||
_activeHttpRequests.RemoveAll(activeRequest =>
|
||||
|
|
|
@ -2,6 +2,7 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Windows.Forms;
|
||||
|
||||
using BizHawk.BizInvoke;
|
||||
|
@ -120,7 +121,6 @@ namespace BizHawk.Client.EmuHawk
|
|||
enableHardcoreItem.CheckedChanged += (_, _) =>
|
||||
{
|
||||
_hardcoreMode ^= true;
|
||||
enableLboardsItem.Enabled = HardcoreMode;
|
||||
|
||||
if (HardcoreMode)
|
||||
{
|
||||
|
@ -130,6 +130,8 @@ namespace BizHawk.Client.EmuHawk
|
|||
{
|
||||
ToSoftcoreMode();
|
||||
}
|
||||
|
||||
enableLboardsItem.Enabled = HardcoreMode;
|
||||
};
|
||||
raDropDownItems.Add(enableHardcoreItem);
|
||||
|
||||
|
@ -195,7 +197,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
: base(mainForm, inputManager, tools, getConfig, raDropDownItems, shutdownRACallback)
|
||||
{
|
||||
_isActive = true;
|
||||
_httpThread = new(HttpRequestThreadProc) { IsBackground = true };
|
||||
_httpThread = new(HttpRequestThreadProc) { IsBackground = true, Priority = ThreadPriority.BelowNormal };
|
||||
_httpThread.Start();
|
||||
|
||||
_runtime = default;
|
||||
|
@ -243,7 +245,8 @@ namespace BizHawk.Client.EmuHawk
|
|||
return;
|
||||
}
|
||||
|
||||
_activeModeUnlocksRequest.Wait();
|
||||
OneShotActivateActiveModeCheevos();
|
||||
|
||||
var size = _lib.rc_runtime_progress_size(ref _runtime, IntPtr.Zero);
|
||||
if (size > 0)
|
||||
{
|
||||
|
@ -266,7 +269,8 @@ namespace BizHawk.Client.EmuHawk
|
|||
HandleHardcoreModeDisable("Loading savestates is not allowed in hardcore mode.");
|
||||
}
|
||||
|
||||
_activeModeUnlocksRequest.Wait();
|
||||
OneShotActivateActiveModeCheevos();
|
||||
|
||||
_lib.rc_runtime_reset(ref _runtime);
|
||||
|
||||
if (!File.Exists(path + ".rap")) return;
|
||||
|
@ -314,6 +318,8 @@ namespace BizHawk.Client.EmuHawk
|
|||
}
|
||||
}
|
||||
|
||||
_activeModeCheevosOnceActivated = false;
|
||||
|
||||
if (!LoggedIn)
|
||||
{
|
||||
return;
|
||||
|
@ -599,6 +605,8 @@ namespace BizHawk.Client.EmuHawk
|
|||
return;
|
||||
}
|
||||
|
||||
OneShotActivateActiveModeCheevos();
|
||||
|
||||
var input = _inputManager.ControllerOutput;
|
||||
if (input.Definition.BoolButtons.Any(b => (b.Contains("Power") || b.Contains("Reset")) && input.IsPressed(b)))
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue