Files
MicrosoftIris/UIX/Microsoft/Iris/Session/UISession.cs
T

419 lines
14 KiB
C#
Raw Normal View History

2022-03-03 08:14:05 -06:00
// Decompiled with JetBrains decompiler
// Type: Microsoft.Iris.Session.UISession
// Assembly: UIX, Version=4.8.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217
// MVID: A56C6C9D-B7F6-46A9-8BDE-B3D9B8D60B11
// Assembly location: C:\Program Files\Zune\UIX.dll
using Microsoft.Iris.Animations;
using Microsoft.Iris.Audio;
using Microsoft.Iris.Drawing;
using Microsoft.Iris.Input;
using Microsoft.Iris.Library;
using Microsoft.Iris.OS;
using Microsoft.Iris.Queues;
using Microsoft.Iris.Render;
using Microsoft.Iris.RenderAPI.Audio;
using Microsoft.Iris.UI;
using System;
using Microsoft.Iris.Render.OpenGL;
2022-03-03 08:14:05 -06:00
namespace Microsoft.Iris.Session
{
2022-10-07 10:29:09 -05:00
public class UISession
2022-03-03 08:14:05 -06:00
{
private bool _rtl;
private static UISession s_theOnlySession;
private UIDispatcher _dispatcher;
private InputManager _inputManager;
private IRenderEngine _engine;
private IRenderSession _session;
private EffectManager _effectManager;
private bool _syncWindowPending;
private readonly SimpleCallback _syncWindowHandler;
private bool _initRequestedFlag;
private readonly SimpleCallback _processInitialization;
private bool _layoutRequestedFlag;
private readonly SimpleCallback _processLayout;
private bool _applyLayoutRequestedFlag;
private readonly SimpleCallback _applyLayout;
private bool _paintRequestedFlag;
private readonly SimpleCallback _processPaint;
private bool _layingOut;
private SimpleQueue _queueSyncLayoutComplete;
private AnimationManager _animationManager;
private SoundManager _soundManager;
private Form _form;
private static readonly DeferredHandler s_deferredPlaySound = new DeferredHandler(DeferredPlaySound);
private static readonly DeferredHandler s_deferredPlaySystemSound = new DeferredHandler(DeferredPlaySystemSound);
public UISession()
: this(null, null, 0U)
{
}
public UISession(
EventHandler rendererConnectedCallback,
TimeoutHandler handlerTimeout,
uint timeoutSecValue)
{
_syncWindowHandler = new SimpleCallback(SyncWindowHandler);
_queueSyncLayoutComplete = new SimpleQueue();
_processInitialization = new SimpleCallback(ProcessInitialization);
_processLayout = new SimpleCallback(ProcessLayout);
_applyLayout = new SimpleCallback(ApplyLayout);
_processPaint = new SimpleCallback(ProcessPaint);
_inputManager = new InputManager(this);
s_theOnlySession = this;
_dispatcher = new UIDispatcher(this, handlerTimeout, timeoutSecValue, true);
2026-07-21 21:40:02 -05:00
#if WINDOWS
int pdwDefaultLayout = 0;
2022-03-03 08:14:05 -06:00
Win32Api.IFWIN32(Win32Api.GetProcessDefaultLayout(out pdwDefaultLayout));
_rtl = pdwDefaultLayout == 1;
_engine = RenderApi.CreateEngine(IrisEngineInfo.CreateLocal(), Dispatcher);
2026-07-21 21:40:02 -05:00
#else
_rtl = false;
_engine = OpenGLRenderApi.CreateEngine(IrisEngineInfo.CreateLocal(), Dispatcher);
2026-07-21 21:40:02 -05:00
#endif
2022-03-03 08:14:05 -06:00
_session = _engine.Session;
TextImageCache.Initialize(this);
ScavengeImageCache.Initialize(this);
}
internal void InitializeRenderingDevices(
GraphicsDeviceType graphicsType,
GraphicsRenderingQuality renderingQuality,
SoundDeviceType soundType)
{
_engine.Initialize(graphicsType, renderingQuality, soundType);
_effectManager = new EffectManager(_session);
_soundManager = new SoundManager(this, _session);
_animationManager = new AnimationManager(_session);
_inputManager.ConnectToRenderer();
}
internal bool IsGraphicsDeviceRecommended(GraphicsDeviceType graphicsType) => _engine.IsGraphicsDeviceAvailable(graphicsType, true);
internal bool IsGraphicsDeviceAvailable(GraphicsDeviceType graphicsType) => _engine.IsGraphicsDeviceAvailable(graphicsType, false);
internal bool IsSoundDeviceAvailable(SoundDeviceType soundType) => _engine.IsSoundDeviceAvailable(soundType);
internal bool ProcessNativeEvents() => _engine.ProcessNativeEvents();
internal void WaitForWork(uint nTimeoutInMsecs) => _engine.WaitForWork(nTimeoutInMsecs);
internal void InterThreadWake() => _engine.InterThreadWake();
internal void FlushBatch() => _engine.FlushBatch();
internal IRenderSession RenderSession => _session;
internal AnimationManager AnimationManager => _animationManager;
public void Dispose()
{
if (TextImageCache.Instance != null)
TextImageCache.Instance.PrepareToShutdown();
if (ScavengeImageCache.Instance != null)
ScavengeImageCache.Instance.PrepareToShutdown();
if (_soundManager != null)
{
_soundManager.Dispose();
_soundManager = null;
}
if (_animationManager != null)
{
_animationManager.Dispose();
_animationManager = null;
}
if (_form != null)
_form.Visible = false;
_inputManager.PrepareToShutDown();
_queueSyncLayoutComplete = null;
_form = null;
_dispatcher.ShutDown(true);
s_theOnlySession = null;
_effectManager.Dispose();
_effectManager = null;
if (_engine != null)
{
_engine.Dispose();
_engine = null;
_session = null;
}
TextImageCache.Uninitialize(this);
ScavengeImageCache.Uninitialize(this);
_dispatcher.Dispose();
if (RenderApi.DebugModule == null)
return;
RenderApi.DebugModule.Dispose();
RenderApi.DebugModule = null;
}
internal bool IsValid => s_theOnlySession == this;
public static void Validate(UISession session)
{
}
public static UISession Default => s_theOnlySession;
public bool IsRtl
{
get => _rtl;
set => _rtl = value;
}
public UIDispatcher Dispatcher => _dispatcher;
public InputManager InputManager => _inputManager;
public EffectManager EffectManager => _effectManager;
internal UIZone RootZone
{
get
{
UIZone uiZone = null;
if (_form != null)
uiZone = _form.Zone;
return uiZone;
}
}
public bool InLayout => _layingOut;
internal void ScheduleUiTask(UiTask task)
{
switch (task)
{
case UiTask.Initialization:
ScheduleInitialization();
break;
case UiTask.LayoutComputation:
ScheduleLayout();
break;
case UiTask.LayoutApplication:
ScheduleApplyLayout();
break;
case UiTask.Painting:
SchedulePaint();
break;
}
}
private void ScheduleLayout()
{
if (_layoutRequestedFlag)
return;
DeferredCall.Post(DispatchPriority.Layout, _processLayout);
_layoutRequestedFlag = true;
}
private void ScheduleApplyLayout()
{
if (_applyLayoutRequestedFlag)
return;
DeferredCall.Post(DispatchPriority.LayoutApply, _applyLayout);
_applyLayoutRequestedFlag = true;
}
private void SchedulePaint()
{
if (_paintRequestedFlag)
return;
DeferredCall.Post(DispatchPriority.Render, _processPaint);
_paintRequestedFlag = true;
}
private void ScheduleInitialization()
{
if (_initRequestedFlag)
return;
DeferredCall.Post(DispatchPriority.High, _processInitialization);
_initRequestedFlag = true;
}
public void RequestUpdateView(bool syncWindow)
{
InputManager.SuspendInputUntil(DispatchPriority.Idle);
Dispatcher.TemporarilyBlockRPCs();
if (!syncWindow || _syncWindowPending)
return;
_syncWindowPending = true;
DeferredCall.Post(DispatchPriority.RenderSync, _syncWindowHandler);
}
private void SyncWindowHandler()
{
_syncWindowPending = false;
_session.GraphicsDevice.RenderNowIfPossible();
}
internal void EnqueueSyncLayoutCompleteHandler(object snd, EventHandler eh) => _queueSyncLayoutComplete.PostItem(DeferredCall.Create(eh, snd, EventArgs.Empty));
private void ProcessInitialization()
{
using (TaskReentrancyDetection.Enter("Initialization"))
{
if (!IsValid || !_initRequestedFlag)
return;
_initRequestedFlag = false;
RootZone?.ProcessUiTask(UiTask.Initialization, null);
}
}
private void ProcessLayout()
{
using (TaskReentrancyDetection.Enter("Layout"))
{
if (!IsValid || !_layoutRequestedFlag)
return;
_layoutRequestedFlag = false;
UIZone rootZone = RootZone;
if (rootZone == null)
return;
_layingOut = true;
rootZone.ProcessUiTask(UiTask.LayoutComputation, null);
QueueItem nextItem;
while ((nextItem = _queueSyncLayoutComplete.GetNextItem()) != null)
nextItem.Dispatch();
_layingOut = false;
}
}
private void ApplyLayout()
{
using (TaskReentrancyDetection.Enter(nameof(ApplyLayout)))
{
if (!IsValid || !_applyLayoutRequestedFlag)
return;
_applyLayoutRequestedFlag = false;
RootZone?.ProcessUiTask(UiTask.LayoutApplication, null);
}
}
private void ProcessPaint()
{
using (TaskReentrancyDetection.Enter("Paint"))
{
if (!IsValid || !_paintRequestedFlag)
return;
_paintRequestedFlag = false;
RootZone?.ProcessUiTask(UiTask.Painting, null);
}
}
internal void FireOnUnhandledException(object sender, Exception e)
{
UISession.UnhandledExceptionHandler unhandledException = OnUnhandledException;
if (unhandledException == null)
return;
UISession.UnhandledExceptionArgs args = new UISession.UnhandledExceptionArgs(e);
unhandledException(sender, args);
}
public event UISession.UnhandledExceptionHandler OnUnhandledException;
public Form Form => _form;
internal IRenderWindow GetRenderWindow() => _engine.Window;
public SoundManager SoundManager => _soundManager;
public void PlaySound(string stSoundSource)
{
UISession.PlaySoundArgs playSoundArgs = new UISession.PlaySoundArgs(this, stSoundSource);
if (!UIDispatcher.IsUIThread)
DeferredCall.Post(DispatchPriority.High, s_deferredPlaySound, playSoundArgs);
else
DeferredPlaySound(playSoundArgs);
}
private static void DeferredPlaySound(object argsObject)
{
UISession.PlaySoundArgs playSoundArgs = argsObject as UISession.PlaySoundArgs;
if (!playSoundArgs.uiSession.IsValid || playSoundArgs.stSoundSource == null)
return;
new Sound() { Source = playSoundArgs.stSoundSource }.Play();
}
public void PlaySystemSound(SystemSoundEvent systemSoundEvent)
{
UISession.PlaySystemSoundArgs playSystemSoundArgs = new UISession.PlaySystemSoundArgs(this, systemSoundEvent);
if (!UIDispatcher.IsUIThread)
DeferredCall.Post(DispatchPriority.High, s_deferredPlaySystemSound, playSystemSoundArgs);
else
DeferredPlaySystemSound(playSystemSoundArgs);
}
private static void DeferredPlaySystemSound(object argsObject)
{
UISession.PlaySystemSoundArgs playSystemSoundArgs = argsObject as UISession.PlaySystemSoundArgs;
if (!playSystemSoundArgs.uiSession.IsValid || playSystemSoundArgs.systemSoundEvent == SystemSoundEvent.None)
return;
new Sound()
{
SystemSoundEvent = playSystemSoundArgs.systemSoundEvent
}.Play();
}
internal void RegisterHost(Form form) => _form = form;
public class UnhandledExceptionArgs : EventArgs
{
private Exception _e;
public UnhandledExceptionArgs(Exception e) => _e = e;
public Exception Error => _e;
}
public delegate void UnhandledExceptionHandler(
object sender,
UISession.UnhandledExceptionArgs args);
private class TaskReentrancyDetection : IDisposable
{
private static string s_currentTask;
private static UISession.TaskReentrancyDetection s_currentTaskClearer = new UISession.TaskReentrancyDetection();
public static IDisposable Enter(string task)
{
if (s_currentTask != null)
InvariantString.Format("REENTRANCY DETECTED! Attempt to process task '{0}' while already processing '{1}'.", s_currentTask, task);
s_currentTask = task;
return s_currentTaskClearer;
}
void IDisposable.Dispose() => s_currentTask = null;
}
private class PlaySoundArgs
{
public UISession uiSession;
public string stSoundSource;
public PlaySoundArgs(UISession session, string source)
{
uiSession = session;
stSoundSource = source;
}
}
private class PlaySystemSoundArgs
{
public UISession uiSession;
public SystemSoundEvent systemSoundEvent;
public PlaySystemSoundArgs(UISession session, SystemSoundEvent soundEventId)
{
uiSession = session;
systemSoundEvent = soundEventId;
}
}
}
}