Exemplo n.º 1
0
 public GetIdentityAndDrawObject(DeathWatch deathWatch, SharePack sharePack, Func <Stream, T> stripFile)
 {
     mDeathWatch = deathWatch;
     SharePack   = sharePack;
     mStripFile  = stripFile;
 }
Exemplo n.º 2
0
        public static OfResourceBank.DResourceSourceDefinition <T> GetFileResource <T>(string originalPath, Func <Stream, T> stripFile, DWithFileWatcherToDispose withFileWatcherToDispose)
        {
            // weakref - don't hard link the recipient - he goes we don't have it
            // should only ever get 1 element
            var listenersForChange = new List <WeakReference <Action <Func <OfResourceBank.IdentityAndDraw <T> > > > >();

            var sharePack = new SharePack(originalPath);
            //var getIdentityAndDrawObject = new GetIdentityAndDrawObject<T>(new DeathWatch(watcher.Dispose), originalPath, stripFile);

            var theLock = sharePack.mTheLock;

            WeakReference <GetIdentityAndDrawObject <T> > weakGetIdentity = null;

            Action <Option <string> > thereWasAChangeToSetPath =
                possibleSuccessorPath =>
            {
                WeakReference <Action <Func <OfResourceBank.IdentityAndDraw <T> > > >[] relevantListenersForChange = null;
                lock (theLock)
                {
                    possibleSuccessorPath.ForEach(successorPath => sharePack.MutablePath = successorPath);
                    sharePack.MutableIdentity  = Guid.NewGuid().ToString();
                    relevantListenersForChange = listenersForChange.ToArray();
                    //getIdentityAndDrawObject.UnderReplacement = true;
                }

                // Never, ever call back in lock we are the downsteram lock
                foreach (var listener in relevantListenersForChange)
                {
                    Action <Func <OfResourceBank.IdentityAndDraw <T> > > func = null;
                    if (listener.TryGetTarget(out func))
                    {
                        GetIdentityAndDrawObject <T> getIdentity = null;
                        if (weakGetIdentity.TryGetTarget(out getIdentity))
                        {
                            func(getIdentity.GetIdentityAndDraw);
                        }
                    }
                }

                lock (theLock)
                {
                    // getIdentityAndDrawObject.UnderReplacement = false;
                    System.Threading.Monitor.PulseAll(theLock);      // wake up any waiting get operation
                }

                // don't capture watcher indirectly in here, or it'll be a circular and never dispose.
            };


            return
                (With(
                     withFileWatcherToDispose(
                         thereWasAChangeToSetPath,
                         originalPath),
                     watcherDispose =>
            {
                var getIdentityAndDrawObject = new GetIdentityAndDrawObject <T>(new DeathWatch(watcherDispose), sharePack, stripFile);
                weakGetIdentity = new WeakReference <GetIdentityAndDrawObject <T> >(getIdentityAndDrawObject);

                return new OfResourceBank.DResourceSourceDefinition <T>(
                    sinkReplacementOnChange =>         // the guy accepting the sink.
                {
                    lock (theLock)
                    {
                        listenersForChange.Add(new WeakReference <Action <Func <OfResourceBank.IdentityAndDraw <T> > > >(sinkReplacementOnChange));
                        return getIdentityAndDrawObject.GetIdentityAndDraw;             // deliberately capturing the deathwatch in its contents - anyone keeping the ability to read keeps the watcher alive
                    }
                });
            }));
        }