Skip to content

Commit 1e55843

Browse files
committed
Adjust link establishment
1 parent 72e85f6 commit 1e55843

File tree

2 files changed

+55
-38
lines changed

2 files changed

+55
-38
lines changed

MonkeyLoader/Sync/MonkeySyncObject.cs

Lines changed: 46 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ public interface IMonkeySyncObject : INotifyPropertyChanged, IDisposable
4747
/// <summary>
4848
/// Gets whether this sync object has a valid link.
4949
/// </summary>
50+
[MemberNotNullWhen(true, nameof(LinkObject))]
5051
public bool IsLinkValid { get; }
5152

5253
/// <summary>
@@ -106,6 +107,7 @@ public abstract class MonkeySyncObject<TSyncObject, TSyncValue, TLink> : IUnlink
106107
public bool HasLinkObject => LinkObject is not null;
107108

108109
/// <inheritdoc/>
110+
[MemberNotNullWhen(true, nameof(LinkObject))]
109111
public abstract bool IsLinkValid { get; }
110112

111113
/// <inheritdoc/>
@@ -165,37 +167,14 @@ public bool LinkWith(TLink linkObject, bool fromRemote = false)
165167

166168
LinkObject = linkObject;
167169

168-
return EstablishLinkWith(linkObject, fromRemote);
170+
return EstablishLink(fromRemote);
169171
}
170172

171-
/// <summary>
172-
/// Creates a link for the given sync value of the given name.
173-
/// </summary>
174-
/// <remarks>
175-
/// <i>By default:</i> Calls
176-
/// <c><paramref name="syncValue"/>.<see cref="IUnlinkedMonkeySyncValue{TLink}.EstablishLinkFor">EstablishLinkFor</see>()</c>.
177-
/// </remarks>
178-
/// <param name="propertyName">The name of the sync value to link.</param>
179-
/// <param name="syncValue">The sync value to link.</param>
180-
/// <param name="fromRemote">Whether the link is being established from the remote side.</param>
181-
/// <returns><c>true</c> if the link was successfully created; otherwise, <c>false</c>.</returns>
182-
protected virtual bool EstablishLinkFor(string propertyName, TSyncValue syncValue, bool fromRemote)
183-
=> syncValue.EstablishLinkFor(this, propertyName, fromRemote);
184-
185-
/// <summary>
186-
/// Creates a link for the given sync method of the given name.
187-
/// </summary>
188-
/// <param name="methodName">The name of the sync method to link.</param>
189-
/// <param name="syncMethod">The sync method to link.</param>
190-
/// <param name="fromRemote">Whether the link is being established from the remote side.</param>
191-
/// <returns><c>true</c> if the link was successfully created; otherwise, <c>false</c>.</returns>
192-
protected abstract bool EstablishLinkFor(string methodName, Action<TSyncObject> syncMethod, bool fromRemote);
193-
194173
/// <remarks><para>
195174
/// <i>By default:</i> Sets up the <see cref="INotifyValueChanged.Changed"/> event handlers
196-
/// and calls <see cref="EstablishLinkFor(string, TSyncValue, bool)">EstablishLinkFor</see>
175+
/// and calls <see cref="EstablishLinkFor(TSyncValue, string, bool)">EstablishLinkFor</see>
197176
/// for every readable <typeparamref name="TSyncValue"/> instance property and
198-
/// <see cref="EstablishLinkFor(string, TSyncValue, bool)">its overload</see> for every
177+
/// <see cref="EstablishLinkFor(TSyncValue, string, bool)">its overload</see> for every
199178
/// <see cref="MonkeySyncMethodAttribute">MonkeySync method</see> on <typeparamref name="TSyncObject"/>.<br/>
200179
/// If the link is successfully created, this linked sync object will be
201180
/// <see cref="MonkeySyncRegistry.RegisterLinkedSyncObject{TLink}">added</see>
@@ -211,7 +190,7 @@ protected virtual bool EstablishLinkFor(string propertyName, TSyncValue syncValu
211190
/// </para>
212191
/// </remarks>
213192
/// <inheritdoc cref="LinkWith"/>
214-
protected virtual bool EstablishLinkWith(TLink linkObject, bool fromRemote)
193+
protected virtual bool EstablishLink(bool fromRemote)
215194
{
216195
var success = true;
217196

@@ -222,18 +201,41 @@ protected virtual bool EstablishLinkWith(TLink linkObject, bool fromRemote)
222201
syncValue.Changed += (sender, changedArgs)
223202
=> OnPropertyChanged(syncValueProperty.Key);
224203

225-
success &= EstablishLinkFor(syncValueProperty.Key, syncValue, fromRemote);
204+
success &= EstablishLinkFor(syncValue, syncValueProperty.Key, fromRemote);
226205
}
227206

228207
foreach (var syncMethod in methodsByName)
229-
success &= EstablishLinkFor(syncMethod.Key, syncMethod.Value, fromRemote);
208+
success &= EstablishLinkFor(syncMethod.Value, syncMethod.Key, fromRemote);
230209

231210
if (success)
232211
MonkeySyncRegistry.RegisterLinkedSyncObject(this);
233212

234213
return success;
235214
}
236215

216+
/// <summary>
217+
/// Creates a link for the given sync value of the given name.
218+
/// </summary>
219+
/// <remarks>
220+
/// <i>By default:</i> Calls
221+
/// <c><paramref name="syncValue"/>.<see cref="IUnlinkedMonkeySyncValue{TLink}.EstablishLinkFor">EstablishLinkFor</see>()</c>.
222+
/// </remarks>
223+
/// <param name="syncValue">The sync value to link.</param>
224+
/// <param name="propertyName">The name of the sync value to link.</param>
225+
/// <param name="fromRemote">Whether the link is being established from the remote side.</param>
226+
/// <returns><c>true</c> if the link was successfully created; otherwise, <c>false</c>.</returns>
227+
protected virtual bool EstablishLinkFor(TSyncValue syncValue, string propertyName, bool fromRemote)
228+
=> syncValue.EstablishLinkFor(this, propertyName, fromRemote);
229+
230+
/// <summary>
231+
/// Creates a link for the given sync method of the given name.
232+
/// </summary>
233+
/// <param name="syncMethod">The sync method to link.</param>
234+
/// <param name="methodName">The name of the sync method to link.</param>
235+
/// <param name="fromRemote">Whether the link is being established from the remote side.</param>
236+
/// <returns><c>true</c> if the link was successfully created; otherwise, <c>false</c>.</returns>
237+
protected abstract bool EstablishLinkFor(Action<TSyncObject> syncMethod, string methodName, bool fromRemote);
238+
237239
/// <summary>
238240
/// Cleans up any managed resources as part of <see cref="Dispose()">disposing</see>.
239241
/// </summary>
@@ -267,7 +269,11 @@ protected void OnLinkInvalidated()
267269
if (!IsLinkValid && TryRestoreLink() && IsLinkValid)
268270
return;
269271

270-
Invalidated.TryInvokeAll();
272+
try
273+
{
274+
Invalidated.TryInvokeAll();
275+
}
276+
catch { }
271277

272278
Dispose();
273279
}
@@ -288,9 +294,9 @@ protected void OnPropertyChanged(string propertyName)
288294
}
289295

290296
/// <remarks><para>
291-
/// <i>By default:</i> Calls <see cref="TryRestoreLinkFor(string, TSyncValue)">TryRestoreLinkFor</see>
297+
/// <i>By default:</i> Calls <see cref="TryRestoreLinkFor(TSyncValue, string)">TryRestoreLinkFor</see>
292298
/// for every readable <typeparamref name="TSyncValue"/> instance property and
293-
/// <see cref="TryRestoreLinkFor(string, TSyncValue)">its overload</see> for every
299+
/// <see cref="TryRestoreLinkFor(TSyncValue, string)">its overload</see> for every
294300
/// <see cref="MonkeySyncMethodAttribute">MonkeySync method</see> on <typeparamref name="TSyncObject"/>.<br/>
295301
/// The detected properties are stored in <see cref="propertyAccessorsByName">propertyAccessorsByName</see>,
296302
/// while the detected methods are stored in <see cref="methodsByName">methodsByName</see>.
@@ -307,29 +313,31 @@ protected virtual bool TryRestoreLink()
307313
var success = true;
308314

309315
foreach (var syncValueProperty in propertyAccessorsByName)
310-
success &= TryRestoreLinkFor(syncValueProperty.Key, syncValueProperty.Value((TSyncObject)this));
316+
success &= TryRestoreLinkFor(syncValueProperty.Value((TSyncObject)this), syncValueProperty.Key);
311317

312318
foreach (var syncMethod in methodsByName)
313-
success &= TryRestoreLinkFor(syncMethod.Key, syncMethod.Value);
319+
success &= TryRestoreLinkFor(syncMethod.Value, syncMethod.Key);
314320

315321
return success;
316322
}
317323

324+
// Implement the sync value one through a method on sync values
325+
318326
/// <summary>
319327
/// Tries to restore the link for the given sync value of the given name.
320328
/// </summary>
321-
/// <param name="propertyName">The name of the sync value to link.</param>
322329
/// <param name="syncValue">The sync value to link.</param>
330+
/// <param name="propertyName">The name of the sync value to link.</param>
323331
/// <returns><c>true</c> if the link was successfully restored; otherwise, <c>false</c>.</returns>
324-
protected abstract bool TryRestoreLinkFor(string propertyName, TSyncValue syncValue);
332+
protected abstract bool TryRestoreLinkFor(TSyncValue syncValue, string propertyName);
325333

326334
/// <summary>
327335
/// Tries to restore the link for the given sync method of the given name.
328336
/// </summary>
329-
/// <param name="methodName">The name of the sync method to link.</param>
330337
/// <param name="syncMethod">The sync method to link.</param>
338+
/// <param name="methodName">The name of the sync method to link.</param>
331339
/// <returns><c>true</c> if the link was successfully restored; otherwise, <c>false</c>.</returns>
332-
protected abstract bool TryRestoreLinkFor(string methodName, Action<TSyncObject> syncMethod);
340+
protected abstract bool TryRestoreLinkFor(Action<TSyncObject> syncMethod, string methodName);
333341

334342
private void Dispose(bool disposing)
335343
{

MonkeyLoader/Sync/MonkeySyncValue.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,12 @@ public interface ILinkedMonkeySyncValue<out TLink> : INotifyValueChanged
4545
public interface ILinkedMonkeySyncValue<out TLink, T> : INotifyValueChanged<T>,
4646
IReadOnlyMonkeySyncValue<TLink, T>, IWriteOnlyMonkeySyncValue<TLink, T>
4747
{
48+
/// <summary>
49+
/// Gets the <see cref="MonkeySyncObject{TSyncObject, TSyncValue, TLink}.LinkObject">LinkObject</see>
50+
/// of the <see cref="ILinkedMonkeySyncValue{TLink}.SyncObject">SyncObject</see> that this value belongs to.
51+
/// </summary>
52+
public TLink LinkObject { get; }
53+
4854
/// <inheritdoc cref="ILinkedMonkeySyncValue{TLink}.Value"/>
4955
public new T Value { get; set; }
5056
}
@@ -106,6 +112,9 @@ public abstract class MonkeySyncValue<TLink, T> : IUnlinkedMonkeySyncValue<TLink
106112
private ValueChangedEventHandler? _untypedChanged;
107113
private T _value;
108114

115+
/// <inheritdoc/>
116+
public TLink LinkObject => SyncObject.LinkObject;
117+
109118
/// <inheritdoc/>
110119
public string Name { get; private set; } = null!;
111120

0 commit comments

Comments
 (0)