public NewResourceChain <Rm <T> > SimpleRootCaseMinor <T>(OfResourceBank.DResourceSourceDefinition <T> getIdentityAndDraw) => SimpleRootCase(getIdentityAndDraw, true).Let( r => new NewResourceChain <Rm <T> >(Rm <T> .FromContents(new ContentsMinor <T>(r.Value)), r.Wipe));
// Ultimately need a different opener for providing R<T> vs Rm<T> private NewResourceChain <DW <Node> > SimpleRootCase <T>(OfResourceBank.DResourceSourceDefinition <T> resourceSourceDefinition, bool isForMinor) { object lockThisChain = new string[] { "" }; // var calculatedObjectSlots = new LifetimeBase<ObjectSlot>(); var objectSlot = new ObjectSlot(); Func <OfResourceBank.IdentityAndDraw <T> > currentGetIdentityAndGetDraw_thisMutatesAndIsClosedOver = null; OfResourceBank.IdentityAndDraw <T> currentIdentityAndGetDraw_thisMutatesAndIsClosedOver = null; Dictionary <Guid, ObjectSlot> perSurvivor = new Dictionary <Guid, ObjectSlot>(); var resourceChainID = AllocateResourceChainIDTakingMasterLock(); Func <ObjectSlot, Action> addAndGetKillAssumesLock = value => { // current implementation capturing *this* var insertID = Guid.NewGuid(); // lock (theLock) { perSurvivor.Add(insertID, value); return (() => // this is the returned 'kill' funciton - it takes its own lock. { bool removeWholeChain = false; // okay to fill this in lock because once true, it's all over anyway lock (lockThisChain) { perSurvivor.Remove(insertID); if (!perSurvivor.Any()) { removeWholeChain = true; } } if (removeWholeChain) { lock (MasterLock) { ChainIDToPerChain.Remove(resourceChainID); } } }); } }; Action wipeAssumingHaveChainLock = () => { foreach (var e in perSurvivor.Values) { e.PossibleObjectAndChildRefsStillOwedValue = None <ObjectPresent>(); } }; currentGetIdentityAndGetDraw_thisMutatesAndIsClosedOver = resourceSourceDefinition( replacement => { lock (lockThisChain) { currentGetIdentityAndGetDraw_thisMutatesAndIsClosedOver = replacement; currentIdentityAndGetDraw_thisMutatesAndIsClosedOver = currentGetIdentityAndGetDraw_thisMutatesAndIsClosedOver(); wipeAssumingHaveChainLock(); } }); // give it an initial value currentIdentityAndGetDraw_thisMutatesAndIsClosedOver = currentGetIdentityAndGetDraw_thisMutatesAndIsClosedOver(); var rootNode = new DW <Node>( new Node( new NodeCommon( lockThisChain, addAndGetKillAssumesLock, () => // in chain lock { var newIdentityAndDraw = currentGetIdentityAndGetDraw_thisMutatesAndIsClosedOver(); if (currentIdentityAndGetDraw_thisMutatesAndIsClosedOver.Identity.Equals(newIdentityAndDraw.Identity)) { // no identity change - don't wipe } else { currentIdentityAndGetDraw_thisMutatesAndIsClosedOver = newIdentityAndDraw; // wipe them all wipeAssumingHaveChainLock(); } }), objectSlot, () => currentIdentityAndGetDraw_thisMutatesAndIsClosedOver.Draw(), isForMinor, None <DAlterTotalMajorCountToParent>()), addAndGetKillAssumesLock(objectSlot)); lock (MasterLock) // never take locks in reverse { ChainIDToPerChain.Add( resourceChainID, new PerResourceChain( () => { lock (lockThisChain) { foreach (var e in perSurvivor.Values) { e.PossibleObjectAndChildRefsStillOwedValue = None <ObjectPresent>(); } } })); } return (new NewResourceChain <DW <Node> >( rootNode, () => { lock (lockThisChain) { wipeAssumingHaveChainLock(); } })); }