//
// PeriodicBinding.cs
//
// Copyright (c) František Boháček. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System.Diagnostics;
using NosSmooth.LocalBinding.Errors;
using NosSmooth.LocalBinding.Extensions;
using NosSmooth.LocalBinding.Options;
using Reloaded.Hooks.Definitions.X86;
using Remora.Results;
namespace NosSmooth.LocalBinding.Objects;
///
/// Binds to a periodic function to allow synchronizing.
///
public class PeriodicBinding
{
[Function
(
new FunctionAttribute.Register[0],
FunctionAttribute.Register.eax,
FunctionAttribute.StackCleanup.Callee,
new[] { FunctionAttribute.Register.ebx, FunctionAttribute.Register.esi, FunctionAttribute.Register.edi, FunctionAttribute.Register.ebp, FunctionAttribute.Register.eax, FunctionAttribute.Register.edx, FunctionAttribute.Register.ecx }
)]
private delegate void PeriodicDelegate();
///
/// Create the periodic binding with finding the periodic function.
///
/// The binding manager.
/// The options for the binding.
/// A periodic binding or an error.
public static Result Create(NosBindingManager bindingManager, PeriodicBindingOptions options)
{
var binding = new PeriodicBinding();
var periodicHookResult = bindingManager.CreateCustomAsmHookFromPattern
("PeriodicBinding.Periodic", binding.PeriodicDetour, options.PeriodicHook);
if (!periodicHookResult.IsDefined(out var periodicHook))
{
return Result.FromError(periodicHookResult);
}
binding._periodicHook = periodicHook;
return binding;
}
private NosAsmHook? _periodicHook;
private PeriodicBinding()
{
}
///
/// An action called on every period.
///
public event EventHandler? PeriodicCall;
///
/// Enable all networking hooks.
///
public void EnableHooks()
{
_periodicHook?.Hook.EnableOrActivate();
}
///
/// Disable all the hooks that are currently enabled.
///
public void DisableHooks()
{
_periodicHook?.Hook.Disable();
}
private void PeriodicDetour()
{
PeriodicCall?.Invoke(this, System.EventArgs.Empty);
}
}