How-tos Overview
Here are some how-tos that, due to the current lack of a more complete manual, will hopefully provide help building React.NET simulations.
Simulation
Tasks & Processes
- Start a task running
- Immediately cancel a running task
- Schedule a task cancellation at some future time
- Have one task block (wait) on another task
- Re-activate one blocked task
- Re-activate all blocked tasks
- Create a process using delegation
- Create a process using derivation
Resources & Consumables
- Create an anonymous resource
- Create a tracked resource
- Obtain the number of free and in-use items
- Change the capacity of a resource
- Acquire a resource item from a resource pool
- Release a resource item back into its resource pool
- Obtain the tracked resource item acquired (allocated)
- Create a consumable
- Add items/units to a consumable
Random Numbers
- Create a uniformly distributed random number generator
- Configure a non-uniform variate to use a user-supplied uniform generator
Developer
Simulation
 1. Create a Simulation
1. Create a Simulation
		Creating a simulation involves two steps: (1) first you must instantiate a Simulation instance; and (2) you must supply the newly created Simulation with one or more generator tasks. Instantiating the simulation is simple...
Simulation sim = new Simulation();
			Creating the generator tasks may be somewhat more involved as you need
			to write some code to get the generators tasks to actually do something
			when they're executed by the simulation.  Once you have such a task,
			it may be activated prior to calling the Simulation.Run
			method or it may be passed to the Run method.
		
Method 1
			Activate a single generator task of type MyTask
			prior to calling the Simulation.Run() method.
		
Task task = new MyTask(sim); task.Activate(); sim.Run();
Method 2
			Pass a single generator task of type MyTask
			to the Simulation.Run(Task) method.
		
Task task = new MyTask(sim); sim.Run(task);
Method 3
			Pass a multiple generator tasks of type MyTaskA
			and MyTaskB to the Simulation.Run(Task[])
			method.
		
Task [] tasks = new Task [2]; tasks[0] = MyTaskA(sim); tasks[1] = MyTaskB(sim); sim.Run(tasks);
Note that Method 1 may be used in conjunction with Method 2 or Method 3. Method 2 and Method 3 cannot be used to run the same simulation.
 2. Stop a Simulation
2. Stop a Simulation
		There are a few different ways to stop a running simulation. It mainly depends upon whether: you want to stop the simulation immediately; or want to have to option to cancel the stoppage if it's scheduled to occur at some time in the future.
			If you don't need to be able to cancel the stoppage, the easiest way
			to stop the simulation is to use one of the Stop methods
			of the Simulation class.
		
public void Stop(); public virtual void Stop(long absTime);
			The first version, Stop() simply stops the simulation
			immediately.  The second version stops the simulation at some
			absolute simulation time.  The first version simply calls
			the second version with an argument of Now (the current
			simulation time).
		
			Once a stop time is set by calling Stop is possible to
			issue a different stop time, but not to recind the stoppage alltogether.
			If you need to be able to cancel a stoppage, you can use a
			StopSimulation task.
		
Simulation sim = /* get the running Simulation instance. */ long stopTime = sim.Now + 1000L; Task stopTask = new React.Tasking.StopSimulation(sim); stopTask.Activate(stopTime);
			To cancel stopTask simply invoke its Cancel()
			method prior to its execution.
		
stopTask.Cancel();
Tasks & Processes
IMPORTANT: Always bear in mind that a Process is a Task. Most of the tips below that apply to Task instances apply equally to Process instances.
 1. Start a task running
1. Start a task running
	
		To start a task running, it must be activated. The Task class contains a number of methods to activate an instance.
public void Activate(object activator); public void Activate(object activator, long relTime); public void Activate(object activator, long relTime, int priority); public void Activate(object activator, long relTime, object data); public virtual void Activate(object activator, long relTime, object data, int priority);
			The meaning of the parameters are identical for each version of
			the Activate method.  All versions delegate to the
			final version (the one marked virtual).
		
- activator
- 
				The object that is activating the Task.  This
				may be nullin which case the activation is said to be anonymous.
- relTime
- The time, relative to the current simulation time, when the Task should be activated.
- data
- 
				Client data to pass to the Task when it is
				activated.  This object is available to Process
				instances as the ActivationDataproperty. It is available to Task instances by querying the triggering ActivationEvent.
- priority
- The priority of the Task. This value is used to order task execution when two or more tasks occur at the exact same time. Higher values indicate higher priority. The default task priority is zero (0).
 2. Immediately cancel a running task
2. Immediately cancel a running task
		
			If a Task is scheduled, that is, it has been
			activated using one of the methods described previously, it may
			be cancelled by invoking its Cancel() method.
		
task.Cancel();
 3. Schedule a task cancellation at some future time
3. Schedule a task cancellation at some future time
		A Task can be cancelled at some future time in the running Simulation by using a CancellationTask.
Task target = /* get the Task to cancel */ Task cancelTask = new React.Tasking.CancellationTask(sim, target); cancelTask.Activate(null, 5000L);
			The above would cancel target in 5000 time units from the
			current simulation time.
		
Cancellation in this manner is one way to implement reneging; however using an interrupt is probably a better approach.
 4. Have one task block (wait) on another task
4. Have one task block (wait) on another task
		One Task can be made to block on another using one of two techniques (Process instance offer one addition method). The technique to choose depends upon whether or not you want to immediately activate the blocking task.
In the following examples, let blocker be the blocking Task and waiting be the Task being blocked (i.e. that task that's waiting on blocker).
Block with immediate activation of blocker
			If you want to activate blocker immediately, call
			waiting's WaitOnTask method.
		
waiting.WaitOnTask(blocker);
The task, waiting will block on blocker and blocker will be activated.
Block with deferred activation of blocker
			If you want to defer activation of blocker use the
			Block(Task) method of blocker.
		
blocker.Activate(null, 500); blocker.Block(waiting);
In the above example, blocker will activate 500 time units from the current time. It also is blocking the task, waiting.
Have a process block on a task
			Process instances provide another means of blocking
			on other Tasks.  They simply need to return the
			blocking Task from the GetProcessSteps
			method.  Remember, GetProcessSteps is an iterator method so
			you must to a yield return.
		
// Block on the task 'blocker' yield return blocker;
Note that blocker is activated immediately.
 5. Re-activate one blocked task
5. Re-activate one blocked task
		
			A Task that is blocking one or more
			Tasks can re-activate one of the
			blocked Tasks by invoking the
			ResumeNext method.  There are three versions
			of ResumeNext available.
		
// Resume the next blocked task. The blocked task is re-activated with the // blocking task as its activator. ResumeNext(); // Resume the next blocked task specifying some activation data. The blocked // task is re-activated with the blocking task as its activator. ResumeNext(thing); // Resume the next blocked task specifiying both the activator and activation // data. ResumeNext(activator, thing);
 6. Re-activate all blocked tasks
6. Re-activate all blocked tasks
		
			A Task that is blocking one or more
			Tasks can re-activate all of the
			blocked Tasks by invoking the
			ResumeAll method.  There are three versions
			of ResumeAll available.  The arguments to
			ResumeAll are used identically to those of
			ResumeNext (see previous how-to).
		
 7. Create a process using delegation
7. Create a process using delegation
		
			A Process can be created using a
			ProcessSteps delegate defined as follows
		
public delegate IEnumerator<Task> ProcessSteps(Process process, object data);
			To create a Process in this manner, you must
			first write the method to be used by the ProcessSteps
			delegate.  Then pass the delegate to the appropriate constructor.
		
// The method usable as a ProcessSteps delegate.
private IEnumerator<Task> DoProcess(Process process, object data)
{
    // ... do your processing ...
    // Doesn't hurt to always include this at the end.
    yield break;
}
public static void Main(string [] args)
{
	Thing thing = new Thing();
    Simulation sim = new Simulation();
    
    // Create a new Process using the delegate method.
    Process p1 = new Process(sim, DoProcess);
    
    // Create a new Process using the delegate method and passing it
    // some initial data.
    Process p2 = new Process(sim, DoProcess, thing);
    
    // Run the simulation. p1 and p2 are the generator tasks.
    sim.Run(new Task[] {p1, p2});
}
 8. Create a process using derivation
8. Create a process using derivation
		
			To create a Process using derivation,
			you must override the GetProcessSteps method.
		
public class MyProcess : Process
{
    public MyProcess(Simulation sim) : base(sim) {}
    protected override IEnumerator<Task>GetProcessSteps()
    {
        .
        .
        .
        yield break;
    }
}
		When creating a new class this way, you do not need to invoke
		the base class version of GetProcessSteps.
	
Resources & Consumables
 1. Create an anonymous resource
1. Create an anonymous resource
		An anonymous resource, implemented by the AnonymousResource class, can be created by directly instantiating an AnonymousResource instance or by using a Resource factory method. Using direct instantiation allows you to supply a name for the resource at the time of its creation.
Direct Instantiation
Create a new AnonymousResource instance by using one of the three available constructors.
// Create with an capacity of one (1).
IResource r1 = new AnonymousResource();
// Create with the specified capacity (e.g. 5).
IResource r2 = new AnonymousResource(5);
// Create with specified name and capacity.
IResource r3 = new AnonymousResource("Printers", 4);
Factory Method
			Create a new AnonymousResource instance by
			using the Resource.Create(int) or
			Resource.Create(int,int) factory methods.
		
// Create an AnonymousResource with a capacity of 10. IResource r4 = Resource.Create(10); // Create an AnonymousResource with a capacity of 10, 4 of which are // out of service. IResource r5 = Resource.Create(6, 4);
			In the first Create call, all ten resource items
			are in-service.  In the second Create
			call, six items are in-service and four items are out-of-service.
			Both result in an AnonymousResource with
			a capacity of ten (e.g. the resource's Count property
			equals 10).
		
 2. Create a tracked resource
2. Create a tracked resource
		A tracked resource, implemented by the TrackedResource class, can be created by directly instantiating an TrackedResource instance or by using a Resource factory method. Using direct instantiation allows you to supply a name for the resource at the time of its creation.
Direct Instantiation
Create a new TrackedResource instance by using one of the two available constructors.
// Load an IEnumerable with the objects the TrackedResource will contain.
// In this example a simple array is used.
object [] things = new object [5];
things[0] = new Thing();
things[1] = new Thing();
    .
    .
    .
    
// Create an unnamed TrackedResource.
IResource r1 = new TrackedResource(things);
// Create an named TrackedResource.
IResource r2 = new TrackedResource("Stuff", things);
			Note that while the above example shows the objects in the things
			array being placed into two different TrackedResource
			instance, this is not a good idea and should be avoided. An object
			should never be contained by more than one TrackedResource.
		
Factory Method
			Create a new TrackedResource instance by
			using the Resource.Create(IEnumerable) factory method.
		
// Create and load an IEnumerable... IList list = new ArrayList(); list.add(new Thing()); list.add(new Thing()); // Create an TrackedResource containing the elements of 'list'. IResource r3 = Resource.Create(list);
All the resource items in a newly created TrackedResource are in-service.
 3. Obtain the number of free and in-use items
3. Obtain the number of free and in-use items
		
			To query an IResource for the number
			of items that are free and the number of items that are
			in-use, query the Free and InUse
			properties.
		
// Get the number of free (available) items in resource 'res'. int nFree = res.Free; // Get the number of in-use items in resource 'res'. int nUsed = res.InUse;
 4. Change the capacity of a resource
4. Change the capacity of a resource
		
			Once created, it's actually not possible to change the capacity
			of a resource.  That is, the Count property
			remains fixed.  It is, however, possible to alter the number of
			resource items are are out-of-service.  An item that is
			out-of-service is considered unusable and therefore cannot be made
			available by the IResource.
		
			To change the number of out-of-service items simply change the
			OutOfService property.
		
// Decrease the number of in-service items in the resource 'res' by two. res.OutOfService += 2;
One major implication of the above is that you must remember to create your resources with a capacity that will accomodate the maximum desired in-service count.
 5. Acquire a resource item from a resource pool
5. Acquire a resource item from a resource pool
		
			A Process can acquire a resource item
			from a IResource using the Acquire
			method.
		
IResource res = /* get the resource you want to acquire from */ yield return res.Acquire(this); // When the process resumes, we have the resource item.
			Note that this example applies only to Process
			instances.  The above code is only valid in an overridden
			GetProcessSteps method or a ProcessSteps
			delegate method.
		
 6. Release a resource item back into its resource pool
6. Release a resource item back into its resource pool
		
			A Process can release a previously acquired resource
			item to a IResource using the Release
			method.
		
IResource res = /* get the resource you want to release to */ yield return res.Release(this); // When the process resumes, we will have released the resource item.
			Note that this example applies only to Process
			instances.  The above code is only valid in an overridden
			GetProcessSteps method or a ProcessSteps
			delegate method.
		
 7. Obtain the tracked resource item acquired (allocated)
7. Obtain the tracked resource item acquired (allocated)
		
			When using a TrackedResource the
			acquiring Task is passed the allocated
			resource item as the data parameter of the
			ExecuteTask method.
		
			For Process instances, obtaining the
			allocated resource item is a bit different because normally,
			you are not overriding ExecuteTask.  In this case,
			the resource item is available in the ActivationData
			property.
		
 8. Create a consumable
8. Create a consumable
		Create a new Consumable instance using one of four constructors. Two of the constructor create an empty consumable, while the other two create a consumable with a specified initial quantity of consumable items (units).
Create an empty consumable
The following two constructors create empty Consumable instances.
// Create an unnamed, empty consumable.
IConsumable c1 = new Consumable();
// Create a named, empty consumable.
IConsumable c2 = new Consumable("Fuel Tank");
Create a consumable with an initial quantity
The following two constructors create Consumable instances having the specified initial quantity of consumable items or units.
// Create an unnamed consumable with initial quantity of 2500 items/units.
IConsumable c3 = new Consumable(2500);
// Create an named consumable with initial quantity of 500 items/units.
IConsumable c4 = new Consumable("Water Tank", 500);
 9. Add items/units to a consumable
9. Add items/units to a consumable
		
			Adding items or units to a IConsumable
			is called re-supplying.  After it's initial creation
			a consumable can only be re-supplied during the simulation run.
			Re-supplying is accomplished by the Task
			returned by the Resupply(Task task, int quantity)
			blocking method of IConsumable.
		
The example code shown below illustrates performing a re-supply from a Process.
protected override IEnumerator<Task> GetProcessSteps()
{
	// ... perform some processing ...
	
	// Get ahold of an IConsumable instance
	IConsumable c = GetWaterTank();
	
	// Now resupply it with 1000 items/units.
	yield return c.Resupply(this, 1000);
	
	// ... perform some more processing ...
}
Random Numbers
 1. Create a uniformly distributed random number generator
1. Create a uniformly distributed random number generator
		The React.Distribution.Uniform class includes two static methods that return a new Uniform instance.
public static Uniform Create(); public static Uniform Create(long seed);
In the first case, the resulting Uniform is seeded using the current system time. In the second case, the seed must be specified.
			Both of the above Create methods, return a
			Uniform derivitive that uses
			System.Random to do the actual random number
			generation.
		
 2. Configure a non-uniform variate to use a user-supplied uniform generator
2. Configure a non-uniform variate to use a user-supplied uniform generator
		Non-uniform random number generators or non-uniform variates can be created to use a uniform generator from the system-wide set of uniform random number streams or they can use a user-supplied random number generator.
All the React.NET non-uniform variates have constructors that take a IUniformSource interface. To specify the IUniformSource for non-uniform variate use one of the constructors that accept a IUniformSource parameter. For example, to create a Weibull instance that uses its own uniform generator, you can do the following.
// Create a new IUniformSource instance seeded from the system time. IUniformSource rngSource = Uniform.Create(); // Create a new Weibull instance that obtains a uniform generator from rngSource. Weibull weibull = new Weibull(rngSource);
			Note that in the example above, weibull will use the
			Weibull class's default shape and scale.
		
Developer
 1. Check out the latest sources
1. Check out the latest sources
		React.NET is currently developed using the Subversion version control system. SourceForge began supporting Subversion in February 2006. It is possible to check out the React.NET source code as follows (if you're using the Subversion command-line client).
svn co https://svn.sourceforge.net/svnroot/reactnet/trunk reactnet
The above will check out the main development line (the trunk) into a directory named reactnet.
For more infomation on using Subversion with SourceForge, see the documents