Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
07/04/19 12:55:52 (5 years ago)
Author:
abeham
Message:

#2975: merged to stable

Location:
stable
Files:
3 edited
1 copied
1 moved

Legend:

Unmodified
Added
Removed
  • stable

  • stable/HeuristicLab.ExtLibs

  • stable/HeuristicLab.ExtLibs/HeuristicLab.SimSharp/3.1.1/SimSharp-3.1.1/Core/Resources/Resource.cs

    r15972 r17053  
    11#region License Information
    22/* SimSharp - A .NET port of SimPy, discrete event simulation framework
    3 Copyright (C) 2016  Heuristic and Evolutionary Algorithms Laboratory (HEAL)
     3Copyright (C) 2019  Heuristic and Evolutionary Algorithms Laboratory (HEAL)
    44
    55This program is free software: you can redistribute it and/or modify
     
    2121
    2222namespace SimSharp {
     23  /// <summary>
     24  /// A resource holds a fixed number of anonymous entities.
     25  ///
     26  /// Requests are processed in FIFO order.
     27  /// Releases are processed in FIFO order (usually no simulation time passes for a Release).
     28  /// </summary>
    2329  public class Resource {
    2430
     
    2935    public int Remaining { get { return Capacity - InUse; } }
    3036
    31     protected Environment Environment { get; private set; }
     37    protected Simulation Environment { get; private set; }
    3238
    3339    protected LinkedList<Request> RequestQueue { get; private set; }
    3440    protected Queue<Release> ReleaseQueue { get; private set; }
    3541    protected HashSet<Request> Users { get; private set; }
     42    protected List<Event> WhenAnyQueue { get; private set; }
     43    protected List<Event> WhenFullQueue { get; private set; }
     44    protected List<Event> WhenEmptyQueue { get; private set; }
     45    protected List<Event> WhenChangeQueue { get; private set; }
    3646
    37     public Resource(Environment environment, int capacity = 1) {
     47    public Resource(Simulation environment, int capacity = 1) {
    3848      if (capacity <= 0) throw new ArgumentException("Capacity must > 0.", "capacity");
    3949      Environment = environment;
     
    4252      ReleaseQueue = new Queue<Release>();
    4353      Users = new HashSet<Request>();
     54      WhenAnyQueue = new List<Event>();
     55      WhenFullQueue = new List<Event>();
     56      WhenEmptyQueue = new List<Event>();
     57      WhenChangeQueue = new List<Event>();
    4458    }
    4559
     
    5670      TriggerRelease();
    5771      return release;
     72    }
     73
     74    public virtual Event WhenAny() {
     75      var whenAny = new Event(Environment);
     76      WhenAnyQueue.Add(whenAny);
     77      TriggerWhenAny();
     78      return whenAny;
     79    }
     80
     81    public virtual Event WhenFull() {
     82      var whenFull = new Event(Environment);
     83      WhenFullQueue.Add(whenFull);
     84      TriggerWhenFull();
     85      return whenFull;
     86    }
     87
     88    public virtual Event WhenEmpty() {
     89      var whenEmpty = new Event(Environment);
     90      WhenEmptyQueue.Add(whenEmpty);
     91      TriggerWhenEmpty();
     92      return whenEmpty;
     93    }
     94
     95    public virtual Event WhenChange() {
     96      var whenChange = new Event(Environment);
     97      WhenChangeQueue.Add(whenChange);
     98      return whenChange;
    5899    }
    59100
     
    73114
    74115    protected virtual void DoRelease(Release release) {
    75       if (!Users.Remove(release.Request)) {
    76         var current = RequestQueue.First;
    77         while (current != null && current.Value != release.Request)
    78           current = current.Next;
    79         if (current != null) RequestQueue.Remove(current);
    80       }
     116      if (!Users.Remove(release.Request))
     117        throw new InvalidOperationException("Released request does not have a user.");
    81118      release.Succeed();
    82119    }
     
    88125        if (request.IsTriggered) {
    89126          RequestQueue.RemoveFirst();
     127          TriggerWhenEmpty();
     128          TriggerWhenChange();
    90129        } else break;
    91130      }
     
    95134      while (ReleaseQueue.Count > 0) {
    96135        var release = ReleaseQueue.Peek();
    97         DoRelease(release);
    98         if (release.IsTriggered) {
     136        if (release.Request.IsAlive) {
     137          if (!RequestQueue.Remove(release.Request))
     138            throw new InvalidOperationException("Failed to cancel a request.");
     139          release.Succeed();
    99140          ReleaseQueue.Dequeue();
    100         } else break;
     141        } else {
     142          DoRelease(release);
     143          if (release.IsTriggered) {
     144            ReleaseQueue.Dequeue();
     145            TriggerWhenAny();
     146            TriggerWhenFull();
     147            TriggerWhenChange();
     148          } else break;
     149        }
    101150      }
     151    }
     152
     153    protected virtual void TriggerWhenAny() {
     154      if (Remaining > 0) {
     155        if (WhenAnyQueue.Count == 0) return;
     156        foreach (var evt in WhenAnyQueue)
     157          evt.Succeed();
     158        WhenAnyQueue.Clear();
     159      }
     160    }
     161
     162    protected virtual void TriggerWhenFull() {
     163      if (InUse == 0) {
     164        if (WhenFullQueue.Count == 0) return;
     165        foreach (var evt in WhenFullQueue)
     166          evt.Succeed();
     167        WhenFullQueue.Clear();
     168      }
     169    }
     170
     171    protected virtual void TriggerWhenEmpty() {
     172      if (Remaining == 0) {
     173        if (WhenEmptyQueue.Count == 0) return;
     174        foreach (var evt in WhenEmptyQueue)
     175          evt.Succeed();
     176        WhenEmptyQueue.Clear();
     177      }
     178    }
     179
     180    protected virtual void TriggerWhenChange() {
     181      if (WhenChangeQueue.Count == 0) return;
     182      foreach (var evt in WhenChangeQueue)
     183        evt.Succeed();
     184      WhenChangeQueue.Clear();
    102185    }
    103186  }
Note: See TracChangeset for help on using the changeset viewer.