@@ -112,7 +112,7 @@ of the target platforms. It is expected that platform differentiation is done by
112112` net8.0-ios ` , etc) but this could include runtime identifier based differentiation in the future. The Silk.NET team
113113reserves all rights to determine implementation details such as this.
114114
115- Silk.NET 3.0 aims to support Windows, Linux (X/11 and Wayland), macOS, iOS, and macOS . The goal of this proposal is to
115+ Silk.NET 3.0 aims to support Windows, Linux (X/11 and Wayland), macOS, iOS, and Android . The goal of this proposal is to
116116do so in a way that requires no _ modification_ of user code. It is highly likely that _ additional_ boilerplate code will
117117be needed on some platforms (e.g. ` MainActivity ` ) but this should not be variant based on the user's specific
118118application i.e. it should work as is when copied and pasted into the user's application.
@@ -1548,6 +1548,87 @@ public abstract partial class Surface
15481548Implementations are expected to be aware of the resource sharing/validity requirements set forth at numerous points
15491549throughout this document - search for occurrences of ISurfaceChildren.
15501550
1551+ # Detached Surfaces
1552+
1553+ When reviewing this proposal, we noticed that we hadn't accounted for the use case wherein users may want to take
1554+ advantage of desktop features (e.g. the ability to run one's own timing/game loop logic) if they are available. Up until
1555+ now, ` ISurfaceApplication.Run ` (or an alternative implementation's equivalent) is the only way to obtain a ` Surface `
1556+ which involves taking control of the entire application and only giving the user control through the exposed callbacks.
1557+ For most use cases, this is fine as we've exposed fundamentals like calling into user code as fast as possible (` Tick ` )
1558+ or on regular intervals (` Render ` /` Update ` ). However, there will be some power users that will want to retain the
1559+ ability to control their own timing if possible, for which we propose the concept of "detached surfaces".
1560+
1561+ "Detached surfaces" have a lifetime that is detached from that of the ` ISurfaceApplication ` they're associated with.
1562+ That is, the implementation's usual handling of an ` ISurfaceApplication ` and its lifecycle is instead user controlled.
1563+ This is notable as creation and destruction of a ` Surface ` is usually controlled by the implementation, whereas with
1564+ this API the destruction shall be delegated to the user. This is exposed as follows:
1565+
1566+ ``` cs
1567+ namespace Silk .NET .Windowing ;
1568+
1569+ /// <summary >
1570+ /// Represents a surface with a user-controlled lifecycle.
1571+ /// </summary >
1572+ /// <remarks >
1573+ /// This API is <b >not guaranteed to be supported</b > on all platforms and you should only use it if you know what
1574+ /// you're doing and know you need the granular control this API provides! Please use
1575+ /// <see cref =" ISurfaceApplication.Run{T}" /> instead where possible. If you insist on using this API, please fall back
1576+ /// to <see cref =" ISurfaceApplication.Run{T}" /> if <see cref =" TryCreate{T}" /> returns <c >false</c > indicating a lack
1577+ /// of support.
1578+ /// </remarks >
1579+ public interface IDetachedSurfaceLifecycle : IDisposable
1580+ {
1581+ /// <summary >
1582+ /// Gets the surface with which this lifecycle is associated. The destruction of this surface is handled by
1583+ /// the <see cref =" IDisposable.Dispose" /> method of this <see cref =" IDetachedSurfaceLifecycle" /> implementation.
1584+ /// </summary >
1585+ Surface Surface { get ; }
1586+
1587+ /// <summary >
1588+ /// Gets a value indicating whether the surface is indicating that its lifecycle should conclude as a result of
1589+ /// its current configuration e.g. an entire tick passing with <see cref =" ISurfaceWindow.IsCloseRequested" /> being
1590+ /// <c >true</c >.
1591+ /// </summary >
1592+ /// <remarks >
1593+ /// It is expected that <see cref =" Tick" /> shall not be called if this property is <c >true</c >.
1594+ /// <remarks >
1595+ bool ShouldTerminate { get ; }
1596+
1597+ /// <summary >
1598+ /// Steps the underlying implementation's surface lifecycle (i.e. event loop), running a single tick on the
1599+ /// <see cref =" Surface" />.
1600+ /// </summary >
1601+ /// <remarks >
1602+ /// It is expected that implementations shall return after doing as little work as possible. For instance, if the
1603+ /// underlying implementation exposes one-by-one event retrieval or otherwise allows customisation of the extent to
1604+ /// which the event pump is run, it is expected that a single event shall be pumped in this case. Note that this is
1605+ /// just an example and the exact details of this is implementation-defined.
1606+ /// </remarks >
1607+ void Tick ();
1608+
1609+ /// <summary >
1610+ /// Attempts to create a <see cref =" IDetachedSurfaceLifecycle" /> using the reference implementation.
1611+ /// </summary >
1612+ /// <param name =" lifecycle" >The created surface lifecycle on success, <c >null</c > otherwise.</param >
1613+ /// <typeparam name =" T" >
1614+ /// The application that shall be associated with the surface. Note that even with this API,
1615+ /// <see cref =" ISurfaceApplication.Initialize{T}" > shall still be called for consistency and portability. However,
1616+ /// unlike <see cref =" ISurfaceApplication.Run{T}" />, this method shall not block and will instead return an
1617+ /// <see cref =" IDetachedSurfaceLifecycle" /> on which <see cref =" Tick" /> is expected to be continuously called to
1618+ /// enact the same behaviour on the surface. The associated application is also used for any additional global
1619+ /// configuration, such as <see cref =" ISurfaceApplication.WindowClass" />.
1620+ /// </typeparam >
1621+ /// <returns >
1622+ /// <c >true</c > if <paramref name =" lifecycle" /> has been populated with an <see cref =" IDetachedSurfaceLifecycle" />
1623+ /// object containing a valid <see cref =" Surface" />, <c >false</c > otherwise.
1624+ /// </returns >
1625+ /// <remarks >
1626+ /// This is the same reference implementation that <see cref =" ISurfaceApplication.Run{T}" /> would otherwise use.
1627+ /// </remarks >
1628+ sealed static bool TryCreate <T >([NotNullWhen (true )] out IDetachedSurfaceLifecycle ? lifecycle ) where T : ISurfaceApplication ;
1629+ }
1630+ ```
1631+
15511632# Meeting Notes
15521633
15531634## 25/02/2022
0 commit comments