A class of resource which may be used by a single concurrent process
        public void BasicResourceResolution()
        {
            DependencyGraph g = new DependencyGraph();

            Resource res = new Resource(g, "resource");

            OrderedProcess a = new OrderedProcess(g, "A");
            OrderedProcess b = new OrderedProcess(g, "B");
            OrderedProcess c = new OrderedProcess(g, "C");

            a.Before(b);
            a.Before(c);

            b.Requires(res);
            c.Requires(res);

            IEnumerable<IEnumerable<OrderedProcess>> s = g.CalculateSort();

            Assert.AreEqual(3, s.Count());

            Assert.AreEqual(1, s.Skip(0).First().Count());
            Assert.AreEqual(a, s.Skip(0).First().First());

            Assert.AreEqual(1, s.Skip(1).First().Count());
            Assert.IsTrue(s.Skip(1).First().First() == b || s.Skip(1).First().First() == c);

            Assert.AreEqual(1, s.Skip(0).First().Count());
            Assert.IsTrue(s.Skip(2).First().First() == b || s.Skip(2).First().First() == c);

            Assert.AreNotEqual(s.Skip(1).First().First(), s.Skip(2).First().First());
        }
        public void BranchingResourceResolution()
        {
            DependencyGraph g = new DependencyGraph();

            OrderedProcess a = new OrderedProcess(g, "A");
            OrderedProcess b1 = new OrderedProcess(g, "B1");
            OrderedProcess b2 = new OrderedProcess(g, "B2");
            OrderedProcess c1 = new OrderedProcess(g, "C1");
            OrderedProcess c2 = new OrderedProcess(g, "C2");
            OrderedProcess c3 = new OrderedProcess(g, "C3");
            OrderedProcess c4 = new OrderedProcess(g, "C4");
            OrderedProcess d = new OrderedProcess(g, "D");

            a.Before(b1, b2).Before(c1, c2, c3, c4).Before(d);

            Resource resource = new Resource(g, "Resource");
            resource.UsedBy(c1, c3);

            IEnumerable<IEnumerable<OrderedProcess>> s = g.CalculateSort();

            //check that A comes first
            Assert.AreEqual(1, s.Skip(0).First().Count());
            Assert.AreEqual(a, s.Skip(0).First().First());

            //check that D comes last
            Assert.AreEqual(1, s.Skip(4).First().Count());
            Assert.AreEqual(d, s.Skip(4).First().First());

            //check that no set contains both c1 and c3
            Assert.AreEqual(0, s.Where(set => set.Contains(c1) && set.Contains(c3)).Count());
        }
 internal bool Add(Resource resourceClass)
 {
     return _resources.Add(resourceClass);
 }
 internal static void CheckGraph(Resource a, OrderedProcess b)
 {
     if (a.Graph != b.Graph)
         throw new ArgumentException(string.Format("Resource {0} is not associated with the same graph as process {1}", a, b));
 }
        /// <summary>
        /// Indicates that this process requires the specified resource.
        /// </summary>
        /// <param name="resource">The resource.</param>
        /// <returns>returns this process</returns>
        public void Requires(Resource resource)
        {
            DependencyGraph.CheckGraph(resource, this);

            if (resources.Add(resource))
                resource.UsedBy(this);
        }