GetCoroutineCount Method

Syntax

Returns

The total number of coroutines running on this script.

Remarks

Includes currently active and waiting coroutines, but not killed coroutines. A new list is created every time it is called with the coroutines at the time of the call. It is possible for coroutines to finish while iterating on the list which will not remove them from the list. Any finished coroutines still in the list will have IsAlive == false.

Returns

Exceptions

Remarks

Use with using to create a critical section. If a lock is already held on Token by a different coroutine then this coroutine will wait for the lock to be released before entering the critical section. Lock is conceptually similar to the lock keyword.

Parameters

Exceptions

Remarks

It is highly recommended to use ScriptBase.Lock(object) instead. This is for advanced use only and can easily create deadlocks that stop scripts from working. Can not be used to release a lock not currently held by this coroutine.

Remarks

The following three scripts acccomplish the same goal using event subscriptions and coroutines. Each script will listen for new agents to join the scene and keep track of the agents name and the time it joined. When the agent leaves, its name and the duration of its visit will be reported.

Event handlers are useful when there is a well contained bit of code which can get most or all of its state from the Sansar.Script.EventData it receives. In this example, a separate data structure is needed to keep track of the name and join time for each agent since there could be multiple agents in the scene.

C# Example

/* This content is licensed under the terms of the Creative Commons Attribution 4.0 International License.
* When using this content, you must:
* � Acknowledge that the content is from the Sansar Knowledge Base.
* � Include our copyright notice: "� 2017 Linden Research, Inc."
* � Indicate that the content is licensed under the Creative Commons Attribution-Share Alike 4.0 International License.
* � Include the URL for, or link to, the license summary at https://creativecommons.org/licenses/by-sa/4.0/deed.hi (and, if possible, to the complete license terms at https://creativecommons.org/licenses/by-sa/4.0/legalcode.
* For example:
* "This work uses content from the Sansar Knowledge Base. � 2017 Linden Research, Inc. Licensed under the Creative Commons Attribution 4.0 International License (license summary available at https://creativecommons.org/licenses/by/4.0/ and complete license terms available at https://creativecommons.org/licenses/by/4.0/legalcode)."
*/
/* Use a coroutine to wait for event callbacks to track visitors to a scene.
* For every visitor start a new coroutine to track that visitor's time.
*/
using System;
using Sansar.Script;
using Sansar.Simulation;
using System.Diagnostics;
// This example shows how to use coroutines to track agents entering and leaving the scene
public class CoroutineExample : SceneObjectScript
{
public override void Init()
{
StartCoroutine(TrackNewUsers);
}
// Wait for new users and start a new coroutine to time them.
private void TrackNewUsers()
{
// This coroutine will run for the lifetime of the script.
while (true)
{
// Block until an add user event happens
UserData data = (UserData)WaitFor(ScenePrivate.User.Subscribe, User.AddUser, SessionId.Invalid);
// Start a new coroutine to track the new user
// Each coroutine will run cooperatively with the others, this script, and other scripts in the system
StartCoroutine(TrackUser, data.User);
}
}
// There will be one instance of this coroutine per active user in the scene
private void TrackUser(SessionId userId)
{
// Track joined time
long joined = Stopwatch.GetTimestamp();
// Lookup the name of the agent. This is looked up now since the agent cannot be retrieved after they
// leave the scene.
string name = ScenePrivate.FindAgent(userId).AgentInfo.Name;
// Block until the agent leaves the scene
WaitFor(ScenePrivate.User.Subscribe, User.RemoveUser, userId);
// Calculate elapsed time and report.
TimeSpan elapsed = TimeSpan.FromTicks(Stopwatch.GetTimestamp()-joined);
ScenePrivate.Chat.MessageAllUsers(string.Format("{0} was present for {0} seconds", name, elapsed.TotalSeconds));
}
}

While the amount of code is approximately the same for each, the coroutine version does not require access to any member data, simplifying the tracking by moving all the required information to stack variables.

C# Example

/* This content is licensed under the terms of the Creative Commons Attribution 4.0 International License.
* When using this content, you must:
* � Acknowledge that the content is from the Sansar Knowledge Base.
* � Include our copyright notice: "� 2017 Linden Research, Inc."
* � Indicate that the content is licensed under the Creative Commons Attribution-Share Alike 4.0 International License.
* � Include the URL for, or link to, the license summary at https://creativecommons.org/licenses/by-sa/4.0/deed.hi (and, if possible, to the complete license terms at https://creativecommons.org/licenses/by-sa/4.0/legalcode.
* For example:
* "This work uses content from the Sansar Knowledge Base. � 2017 Linden Research, Inc. Licensed under the Creative Commons Attribution 4.0 International License (license summary available at https://creativecommons.org/licenses/by/4.0/ and complete license terms available at https://creativecommons.org/licenses/by/4.0/legalcode)."
*/
/* Use a coroutine as an event callback to easily track visitors to a scene.
* Every visitor triggers an AddUser event which will start a coroutine for that visitor.
*/
using System;
using Sansar.Script;
using Sansar.Simulation;
using System.Diagnostics;
// This example shows how to use coroutines and events to track agents entering and leaving the scene
public class CoroutineEventExample : SceneObjectScript
{
public override void Init()
{
// Subscribe to Add User events
// Events can be handled by anonymous methods
ScenePrivate.User.Subscribe(User.AddUser, (UserData data) => StartCoroutine(TrackUser, data.User), true);
}
// There will be one instance of this coroutine per active user in the scene
private void TrackUser(SessionId userId)
{
// Track joined time
long joined = Stopwatch.GetTimestamp();
// Lookup the name of the agent. This is looked up now since the agent cannot be retrieved after they
// leave the scene.
string name = ScenePrivate.FindAgent(userId).AgentInfo.Name;
// Block until the agent leaves the scene
WaitFor(ScenePrivate.User.Subscribe, User.RemoveUser, userId);
// Calculate elapsed time and report.
TimeSpan elapsed = TimeSpan.FromTicks(Stopwatch.GetTimestamp()-joined);
ScenePrivate.Chat.MessageAllUsers(string.Format("{0} was present for {0} seconds", name, elapsed.TotalSeconds));
}
}

Coroutines can be mixed with event handlers. This example uses an event handler for the new user events to start a coroutine to watch for the remove user events.

Parameters

Exceptions

Remarks

It is highly recommended to use ScriptBase.Lock(object) instead. This is for advanced use only and can easily create deadlocks that stop scripts from working. If not paired with ScriptBase.ReleaseLock(object) will create a deadlock preventing this code from being entered.