Reflective

Reflective Class

Base class which provides for simple reflection of methods through a given interface.

Syntax

public class Reflective

Remarks

If the object already implements the interface it will return the object directly. Otherwise an facade class is created to map between public methods and properties. Two scripts which use a Reflective object to communicate via script events are below:
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)."
 */
using Sansar.Simulation;
using Sansar.Script;
using System;
using System.Diagnostics;

// This class is a simple stopwatch that can respond to requests for the current elapsed time
// and resets. The elapsed time is also broadcast periodically.
public class SharedStopwatchExample : SceneObjectScript
{
    #region ResetTime
    // This is the event object. Setting the base class to Reflective allows access to the public 
    // properties and methods without needing a reference to this script
    public class ResetTime : Reflective
    {
        // The id of the script which made the last reset request.
        // The setter is made internal so that our script can call
        // it but other scripts cannot.
        public ScriptId SourceScriptId { get; internal set; }
        
        // The current start time.
        // The setter is made internal so that our script can call
        // it but other scripts cannot.
        public long StartTime { get; internal set; }

        // The calculated elapsed time
        public TimeSpan Elapsed
        {
            get
            {
                return TimeSpan.FromTicks(Stopwatch.GetTimestamp() - StartTime);
            }
        }
        // The count of times the timer has been reset
        // The setter is made internal so that our script can call
        // it but other scripts cannot.
        public int ResetCount { get; internal set; }
    }
    #endregion ResetTime

    #region EditorProperties
    [DefaultValue("request")]
    public readonly string requestCommand = "request";

    [DefaultValue("elapsed")]
    public readonly string elapsedCommand = "elapsed";

    [DefaultValue("reset")]
    public readonly string resetCommand = "reset";

    [DefaultValue(1)]
    public readonly double broadcastMinutes = .15;
    #endregion EditorProperties

    #region EventHandlers
    // Handler for the requestCommand, sends the current information back to the requesting script
    private void requestElapsed(ScriptEventData uptime)
    {
        sendElapsed(uptime.SourceScriptId);
    }

    // Handler for the resetCommand, resets the start time
    private void resetElapsed(ScriptEventData uptime)
    {
        resetElapsed(uptime.SourceScriptId);
    }
    #endregion EventHandlers

    #region Implementation

    // Object which tracks all the info we need
    private ResetTime resetTime = new ResetTime();

    // Posts the current time information to the given script id
    // targetScriptId will be AllScripts for the broadcast
    private void sendElapsed(ScriptId targetScriptId)
    {
        PostScriptEvent(targetScriptId, elapsedCommand, resetTime);
    }

    // Resets the elapsed time and tracks the id of the script making the request
    private void resetElapsed(ScriptId id)
    {
        Log.Write(LogLevel.Info, Script.ID.ToString(), $"reset requested by script {id}");
        resetTime.SourceScriptId = id;
        resetTime.StartTime = Stopwatch.GetTimestamp();
        resetTime.ResetCount++;
    }
    #endregion Implementation

    #region Overrides
    public override void Init()
    {
        // write this script id to the log to track messages
        Log.Write(LogLevel.Info, Script.ID.ToString(), nameof(SharedStopwatchExample));

        // sets the initial timer and script id to this script
        resetElapsed(Script.ID);

        // listen for direct requests for the elapsed time
        SubscribeToScriptEvent(requestCommand, requestElapsed);

        // listen for requests to reset the time
        SubscribeToScriptEvent(resetCommand, resetElapsed);

        // set up a timer that broadcasts the elapsed time
        Timer.Create(TimeSpan.FromMinutes(broadcastMinutes), 
            TimeSpan.FromMinutes(broadcastMinutes), 
            () => sendElapsed(ScriptId.AllScripts));
    }
    #endregion Overrides

}
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)."
 */
using Sansar.Simulation;
using Sansar.Script;
using System;

public class ScriptEventSourceExample : SceneObjectScript
{
    #region ResetTime
    // This is the event interface that this script will use. Only the public methods and properties
    // that will be referenced are used.
    public interface ResetTime 
    {
        // The current start time.
        // The setter is not public so this script will only ask for the getter
        DateTime StartTime { get; }

        // The calculated elapsed time
        TimeSpan Elapsed { get; }
    }
    #endregion ResetTime

    #region EditorProperties
    [DefaultValue("request")]
    public readonly string requestCommand = "request";

    [DefaultValue("elapsed")]
    public readonly string elapsedCommand = "elapsed";

    [DefaultValue("reset")]
    public readonly string resetCommand = "reset";

    [DefaultValue(3)]
    public readonly double resetMinutes = .2;
    #endregion EditorProperties

    #region EventHandlers

    private void elapsed(ScriptEventData elapsed)
    {
        if(elapsed.Data == null)
        {
            Log.Write(LogLevel.Warning, Script.ID.ToString(), "Expected non-null event data");
            return;
        }
        ResetTime resetTime = elapsed.Data.AsInterface<ResetTime>();

        if(resetTime == null)
        {
            Log.Write(LogLevel.Error, Script.ID.ToString(), "Unable to create interface, check logs for missing member(s)");
            return;
        }

        Log.Write(LogLevel.Info, Script.ID.ToString(), $"Elapsed time = {resetTime.Elapsed} since {resetTime.StartTime}");
    }

    #endregion EventHandlers

    public override void Init()
    {
        // write this script id to the log to track messages
        Log.Write(LogLevel.Info, Script.ID.ToString(), nameof(ScriptEventSourceExample));

        // Subscribe to elapsed messages
        SubscribeToScriptEvent(elapsedCommand, elapsed);

        // set up a timer to periodically reset the elapsed time
        Timer.Create(TimeSpan.FromMinutes(resetMinutes),
            TimeSpan.FromMinutes(resetMinutes),
            () => PostScriptEvent(resetCommand));
        
    }


}

Requirements

Namespace: Sansar.Script
Assembly: Sansar.Script (in Sansar.Script.dll)
Assembly Versions: 1.0.0.0

Members

See Also: Inherited members from object.

Protected Constructors

 
Default constructor.

Protected Properties

[read-only]
 
AllowedContexts Reflective.Context . Internal Use Only. Overridden by subclasses to return only those contexts requested which are allowed for that type of script.
[read-only]
 
ReflectiveContexts Reflective.Context . Override ReflectiveContexts to limit which contexts this Reflective interface is available in when registered with.
[read-only]
 
ReflectiveName string . Override ReflectiveName to change which name this class will be registered as in the Reflective system.

Public Methods

 
AsInterface<TInterface> () : TInterface
Returns a TInterface object if one can be created, null otherwise
 
FullInterface (string) : string
Generates a string which shows all the members which can be reflected.
 
Register ()
Register this object to be found with Sansar.Simulation.ScenePrivate.FindReflective(string)
 
Unregister ()
Unregister this object so it will not be found with Sansar.Simulation.ScenePrivate.FindReflective(string)

Member Details

Reflective Constructor

Default constructor.

Syntax

protected Reflective ()

Remarks

 

Requirements

Namespace: Sansar.Script
Assembly: Sansar.Script (in Sansar.Script.dll)
Assembly Versions: 1.0.0.0

AllowedContexts Property

Internal Use Only. Overridden by subclasses to return only those contexts requested which are allowed for that type of script.

Syntax

protected virtual Reflective.Context AllowedContexts { get; }

Value

Documentation for this section has not yet been entered.

Remarks

Used internally to prevent visiting guest scripts from registering as 'scene level' APIs.

Requirements

Namespace: Sansar.Script
Assembly: Sansar.Script (in Sansar.Script.dll)
Assembly Versions: 1.0.0.0

AsInterface<TInterface> Generic Method

Returns a TInterface object if one can be created, null otherwise

Syntax

[Sansar.Script.NonReflective]
public TInterface AsInterface<TInterface> ()
where TInterface : class

Type Parameters

TInterface
The interface describing the methods and properties desired.

Returns

A TInterface instance if this object is compatible. An object is compatible if it implements the interface or has public methods and properties which match TInterface.

Remarks

 

Requirements

Namespace: Sansar.Script
Assembly: Sansar.Script (in Sansar.Script.dll)
Assembly Versions: 1.0.0.0

FullInterface Method

Generates a string which shows all the members which can be reflected.

Syntax

[Sansar.Script.NonReflective]
public string FullInterface (string interfaceName)

Parameters

interfaceName
The name to give the generated interface class in the output.

Returns

The generated string. If no members can be reflected, returns the empty string

Remarks

Documentation for this section has not yet been entered.

Requirements

Namespace: Sansar.Script
Assembly: Sansar.Script (in Sansar.Script.dll)
Assembly Versions: 1.0.0.0

ReflectiveContexts Property

Override ReflectiveContexts to limit which contexts this Reflective interface is available in when registered with.

Syntax

[Sansar.Script.NonReflective]
protected virtual Reflective.Context ReflectiveContexts { get; }

Value

Documentation for this section has not yet been entered.

Remarks

This can be used to further restrict which contexts an interface is available in. It can not be used to register for a context not allowed by the running script type. SceneObjectScript allows ScenePrivate, ScenePublic, ObjectPrivate. ObjectScript allows ObjectPrivate. Overriding this will automatically register this Reflective

Requirements

Namespace: Sansar.Script
Assembly: Sansar.Script (in Sansar.Script.dll)
Assembly Versions: 1.0.0.0

ReflectiveName Property

Override ReflectiveName to change which name this class will be registered as in the Reflective system.

Syntax

[Sansar.Script.NonReflective]
protected virtual string ReflectiveName { get; }

Value

Documentation for this section has not yet been entered.

Remarks

Defaults to GetType().FullName

Requirements

Namespace: Sansar.Script
Assembly: Sansar.Script (in Sansar.Script.dll)
Assembly Versions: 1.0.0.0

Register Method

Register this object to be found with Sansar.Simulation.ScenePrivate.FindReflective(string)

Syntax

[Sansar.Script.NonReflective]
public void Register ()

Remarks

Will register this reflective object with Reflective.AllowedContexts if overridden, otherwise with ScenePrivate and ObjectPrivate.

Requirements

Namespace: Sansar.Script
Assembly: Sansar.Script (in Sansar.Script.dll)
Assembly Versions: 1.0.0.0

Unregister Method

Unregister this object so it will not be found with Sansar.Simulation.ScenePrivate.FindReflective(string)

Syntax

[Sansar.Script.NonReflective]
public void Unregister ()

Remarks

If the Reflective object has not previously been registered nothing happens.

Requirements

Namespace: Sansar.Script
Assembly: Sansar.Script (in Sansar.Script.dll)
Assembly Versions: 1.0.0.0


Was this article helpful?
0 out of 1 found this helpful
Have more questions? Submit a request

0 Comments

Article is closed for comments.