openDecal/Managed/Decal.Adapter/Decal.Adapter.Wrappers/RenderServiceWrapper.cs
erik d1442e3747 Initial commit: Complete open-source Decal rebuild
All 5 phases of the open-source Decal rebuild:

Phase 1: 14 decompiled .NET projects (Interop.*, Adapter, FileService, DecalUtil)
Phase 2: 10 native DLLs rewritten as C# COM servers with matching GUIDs
  - DecalDat, DHS, SpellFilter, DecalInput, DecalNet, DecalFilters
  - Decal.Core, DecalControls, DecalRender, D3DService
Phase 3: C++ shims for Inject.DLL (D3D9 hooking) and LauncherHook.DLL
Phase 4: DenAgent WinForms tray application
Phase 5: WiX installer and build script

25 C# projects building with 0 errors.
Native C++ projects require VS 2022 + Windows SDK (x86).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 18:27:56 +01:00

132 lines
2.8 KiB
C#

using System;
using System.ComponentModel;
using System.Drawing;
using System.Runtime.InteropServices;
using Decal.Adapter.Support;
using Decal.Interop.Core;
using Decal.Interop.Inject;
using Decal.Interop.Render;
namespace Decal.Adapter.Wrappers;
[CLSCompliant(true)]
public class RenderServiceWrapper : MarshalByRefObject, IDisposable
{
private RenderService internalRender;
private bool isDisposed;
private EventHandler myDeviceLost;
[EditorBrowsable(EditorBrowsableState.Never)]
public object UnsafeDevice => internalRender.Device;
internal event EventHandler DeviceLost
{
add
{
myDeviceLost = (EventHandler)Delegate.Combine(myDeviceLost, value);
}
remove
{
myDeviceLost = (EventHandler)Delegate.Combine(myDeviceLost, value);
}
}
internal RenderServiceWrapper(RenderService render)
{
internalRender = render;
internalRender.DeviceLost += internalRender_DeviceLost;
}
~RenderServiceWrapper()
{
Dispose(disposing: false);
}
private void internalRender_DeviceLost()
{
if (myDeviceLost != null)
{
myDeviceLost(this, new EventArgs());
}
}
private void myHUD_Disposing(object sender, EventArgs e)
{
if (sender is Hud hud)
{
RemoveHud(hud);
hud.Disposing -= myHUD_Disposing;
}
}
public Background CreateBackground(Rectangle region)
{
return UnsafeCreateBackground(Util.toTagRECT(region));
}
public Hud CreateHud(Rectangle region)
{
return UnsafeCreateHud(Util.toTagRECT(region));
}
public void RemoveHud(Hud hud)
{
if (hud == null)
{
throw new ArgumentNullException("hud");
}
internalRender.RemoveHUD(hud.Underlying);
}
[CLSCompliant(false)]
[EditorBrowsable(EditorBrowsableState.Never)]
public Background UnsafeCreateBackground(tagRECT pRegion)
{
return new Background(internalRender.CreateBackground(ref pRegion));
}
[CLSCompliant(false)]
[EditorBrowsable(EditorBrowsableState.Never)]
public Hud UnsafeCreateHud(tagRECT pRegion)
{
Hud hud = new Hud(internalRender.CreateHUD(ref pRegion));
hud.Disposing += myHUD_Disposing;
return hud;
}
[CLSCompliant(false)]
[EditorBrowsable(EditorBrowsableState.Never)]
public Background EncapsulateBackground(tagPOINT coordinates, object surface)
{
return new Background(internalRender.EncapsulateBackground(ref coordinates, surface));
}
[CLSCompliant(false)]
[EditorBrowsable(EditorBrowsableState.Never)]
public Hud EncapsulateHud(tagPOINT coordinates, object surface)
{
return new Hud(internalRender.EncapsulateHUD(ref coordinates, surface));
}
public void Dispose()
{
Dispose(disposing: true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!isDisposed && disposing)
{
internalRender.DeviceLost -= internalRender_DeviceLost;
}
if (internalRender != null)
{
Marshal.ReleaseComObject(internalRender);
}
internalRender = null;
isDisposed = true;
}
}