/////////////////////////////////////////////////////////////////////// #region INotify Members public override ReturnCode Notify( Interpreter interpreter, IScriptEventArgs eventArgs, IClientData clientData, ArgumentList arguments, ref Result result ) { if (eventArgs == null) { return(ReturnCode.Ok); } if (!Utility.HasFlags( eventArgs.NotifyTypes, NotifyType.Command, false)) { return(ReturnCode.Ok); } NotifyFlags notifyFlags = eventArgs.NotifyFlags; if (!Utility.HasFlags( notifyFlags, NotifyFlags.Executed, false)) { return(ReturnCode.Ok); } Thread.Sleep(500); /* TODO: Fine tune? */ return(ReturnCode.Ok); }
/////////////////////////////////////////////////////////////////////// /// <summary> /// This method is called by the core library when the plugin needs /// to receive a notification supported by it. /// </summary> /// /// <param name="interpreter"> /// The interpreter context we are executing in. This parameter may /// be null. /// </param> /// /// <param name="eventArgs"> /// The context data associated with this notification. This /// parameter may be null. /// </param> /// /// <param name="clientData"> /// The client data associated with this notification. This /// parameter may be null. /// </param> /// /// <param name="arguments"> /// The script arguments associated with this notification. This /// parameter may be null. /// </param> /// /// <param name="result"> /// The result associated with this notification. This parameter /// is used for input and output and may be null. /// </param> /// /// <returns> /// ReturnCode.Ok on success, ReturnCode.Error on failure. /// </returns> public virtual ReturnCode Notify( Interpreter interpreter, IScriptEventArgs eventArgs, IClientData clientData, ArgumentList arguments, ref Result result ) { return(ReturnCode.Ok); }
/////////////////////////////////////////////////////////////////////// public ReturnCode Notify( Interpreter interpreter, IScriptEventArgs eventArgs, IClientData clientData, ArgumentList arguments, ref Result result ) { if (plugin != null) { return(plugin.Notify( interpreter, eventArgs, clientData, arguments, ref result)); } else { return(ReturnCode.Error); } }
/////////////////////////////////////////////////////////////////////// #region INotify Members public override ReturnCode Notify( Interpreter interpreter, IScriptEventArgs eventArgs, IClientData clientData, ArgumentList arguments, ref Result result ) { if (eventArgs == null) { return(ReturnCode.Ok); } if (!FlagOps.HasFlags( eventArgs.NotifyTypes, NotifyType.CallFrame, false)) { return(ReturnCode.Ok); } NotifyFlags notifyFlags = eventArgs.NotifyFlags; if (!FlagOps.HasFlags(notifyFlags, NotifyFlags.Popped | NotifyFlags.Deleted, false)) { return(ReturnCode.Ok); } IClientData eventClientData = eventArgs.ClientData; if (eventClientData == null) { return(ReturnCode.Ok); } ICallFrame newFrame = eventClientData.Data as ICallFrame; if (newFrame == null) { return(ReturnCode.Ok); } // // NOTE: Make sure the variables in this frame actually BELONG // to this frame. Also, we do not handle the global call // frame. // if (!FlagOps.HasFlags(notifyFlags, NotifyFlags.Force, true) && !CallFrameOps.IsNonGlobalVariable(newFrame)) { return(ReturnCode.Ok); } // // NOTE: If this is a [scope] created call frame, we do NOT want // to change any reference counts unless the call frame is // being deleted, not simply popped. // if (!FlagOps.HasFlags(notifyFlags, NotifyFlags.Deleted, true) && CallFrameOps.IsScope(newFrame)) { return(ReturnCode.Ok); } // // NOTE: Grab the variables for this call frame. If there are // none, we are done. // VariableDictionary variables = newFrame.Variables; if (variables == null) { return(ReturnCode.Ok); } // // NOTE: Process each variable in the call frame to adjust all // all the reference counts. After this point, we need // the interpreter context for the event. // Interpreter eventInterpreter = eventArgs.Interpreter; if (eventInterpreter == null) { return(ReturnCode.Ok); } foreach (KeyValuePair <string, IVariable> pair in variables) { // // NOTE: Grab the variable and make sure the variable it is // valid. // IVariable variable = pair.Value; if (variable == null) { continue; } // // NOTE: For unset operations, ObjectTraceCallback uses only // the "traceInfo.Variable" and "traceInfo.oldValue" // members of the ITraceInfo object instance. If the // number of trace and/or watch levels exceeds one, // force creation of a new TraceInfo object here; // otherwise, we may interfere with the setting of an // unrelated variable value. // ITraceInfo traceInfo = ScriptOps.NewTraceInfo( interpreter, null, BreakpointType.BeforeVariableUnset, newFrame, variable, pair.Key, null, VariableFlags.None, variable.Value, null, null, null, null, interpreter.NeedNewTraceInfo(VariableFlags.None), false, !EntityOps.IsNoPostProcess(variable), ReturnCode.Ok); // // HACK: Manually invoke the Interpreter.ObjectTraceCallback // static (trace callback) method, in order to handle // contained object reference(s), if any. After this // method returns, the entire call frame will be going // away, along with any object references contained // within it. // ReturnCode code = Interpreter.ObjectTraceCallback( traceInfo.BreakpointType, eventInterpreter, traceInfo, ref result); if (code != ReturnCode.Ok) { return(code); } } return(ReturnCode.Ok); }
/////////////////////////////////////////////////////////////////////// #region INotify Members public override ReturnCode Notify( Interpreter interpreter, IScriptEventArgs eventArgs, IClientData clientData, ArgumentList arguments, ref Result result ) { ReturnCode code = ReturnCode.Ok; if (form != null) { if (eventArgs != null) { if (Utility.HasFlags(eventArgs.NotifyTypes, NotifyTypes, false) && Utility.HasFlags(eventArgs.NotifyFlags, NotifyFlags, false)) { Interpreter eventInterpreter = eventArgs.Interpreter; if ((eventInterpreter != null) && (eventArgs.ClientData != null) && (eventArgs.ClientData.Data != null)) { if (Utility.HasFlags(eventArgs.NotifyTypes, NotifyType.Interpreter, true) && Utility.HasFlags(eventArgs.NotifyFlags, NotifyFlags.Exit, true)) { bool?exit; try { exit = (bool)eventArgs.ClientData.Data; } catch { exit = null; } // // NOTE: If necessary, exit the application. // if ((exit != null) && ((bool)exit)) { form.AsyncDispose(); } } else if (Utility.HasFlags(eventArgs.NotifyTypes, NotifyType.Script, true) && Utility.HasFlags(eventArgs.NotifyFlags, NotifyFlags.Completed, true)) { if (!interpreter.Exit) { IList <object> list = eventArgs.ClientData.Data as IList <object>; if (list != null) { string text; try { text = list[2] as string; if (text != null) { text = text.Substring( (int)list[3], (int)list[4]); } } catch { text = null; } if (text != null) { form.AsyncScriptCompleted(text, result); } } } } else if (Utility.HasFlags(eventArgs.NotifyTypes, NotifyType.Script, true) && Utility.HasFlags(eventArgs.NotifyFlags, NotifyFlags.Canceled, true) && !Utility.HasFlags(eventArgs.NotifyFlags, NotifyFlags.Reset, true)) { if (!interpreter.Exit) { // // NOTE: The script engine does not currently provide any // meaningful context information here; however, it // should not be necessary because the test script is // the only script that is evaluated by this application // that can be canceled without resulting in the // application exiting. // form.AsyncScriptCanceled(); } } } } } } return(code); }
/////////////////////////////////////////////////////////////////////// #region INotify Members (Required) /// <summary> /// Receives notifications when an event occurs that the plugin has /// declared it wants to be notified about. /// </summary> /// <param name="interpreter"> /// The interpreter context we are executing in. /// </param> /// <param name="eventArgs"> /// Contains data related to the event. The exact data depends on the /// type of event being processed. /// </param> /// <param name="clientData"> /// The extra data supplied for this event, if any. /// </param> /// <param name="result"> /// Upon success, this may contain an informational message. /// Upon failure, this must contain an appropriate error message. /// </param> /// <returns> /// ReturnCode.Ok on success, ReturnCode.Error on failure. /// </returns> public override ReturnCode Notify( Interpreter interpreter, /* in */ IScriptEventArgs eventArgs, /* in */ IClientData clientData, /* in */ ArgumentList arguments, /* in */ ref Result result /* out */ ) { ReturnCode code = ReturnCode.Ok; // // NOTE: If there is no data associated with this event, just // return. We do not know how to handle these types of // events and nothing else should be done. The best advice // when implementing this interface is "when in doubt, just // do nothing". // if (eventArgs == null) { return(code); } // // NOTE: Make sure that notification matches the types and flags // that we care about. In theory, this should be handled // by the core library before we get called; however, it // cannot really hurt to double check. // if (!Utility.HasFlags( eventArgs.NotifyTypes, NotifyType.Script, true) || !Utility.HasFlags( eventArgs.NotifyFlags, NotifyFlags.Completed, true)) { return(code); } #if false // // NOTE: This is the interpreter involved in the event, which may // be different from the interpreter context we are executing // in. This example does not make use of this interpreter; // therefore, this code block is commented out. // /* NOT USED */ Interpreter eventInterpreter = eventArgs.Interpreter; if (eventInterpreter == null) { return(code); } #endif // // NOTE: Grab the extra data associated with this "event" now. The // exact contents will vary depending on the event type being // serviced. The source code associated with the event type // in question should be consulted to determine the necessary // type conversion(s). // IClientData eventClientData = eventArgs.ClientData; if (eventClientData == null) { return(code); } // // NOTE: In this case, the data associated with the event is an // "object list". If the data does not conform to that type, // bail out now. // IList <object> list = eventClientData.Data as IList <object>; if (list == null) { return(code); } // // NOTE: Attempt to fetch the text of the script that was just // completed. // string text; try { // // NOTE: The third element should contain the full text of the // completed script. // text = list[2] as string; if (text != null) { // // NOTE: The third and fourth elements should contain the // offset and number of characters for the completed // script, respectively. // text = text.Substring((int)list[3], (int)list[4]); } } catch { // // NOTE: Somehow, the data does not conform to expectations for // this event type. Gracefully ignore it. // text = null; } // // NOTE: To display the text of the completed script, both the // interpreter and the text itself is required. // if ((interpreter != null) && (text != null)) { // // NOTE: Grab the host from the interpreter context we are // executing in. // IInteractiveHost interactiveHost = interpreter.Host; if (interactiveHost != null) { // // NOTE: Emit a message to the interpreter host that // includes the full text of the completed script. // interactiveHost.WriteLine(String.Format( "{0}: script completed{1}{2}", GetType().FullName, Environment.NewLine, text)); } } return(code); }
/////////////////////////////////////////////////////////////////////// #region INotify Members public override ReturnCode Notify( Interpreter interpreter, IScriptEventArgs eventArgs, IClientData clientData, ArgumentList arguments, ref Result result ) { // // NOTE: If we are disabled -OR- there are no event arguments -OR- // this event does not match the kind we are interested in // then just return "success" now. // if (disabled || (eventArgs == null) || !FlagOps.HasFlags( eventArgs.NotifyTypes, NotifyType.Engine, false) || !FlagOps.HasFlags( eventArgs.NotifyFlags, NotifyFlags.Executed, false)) { return(ReturnCode.Ok); } // // NOTE: In "direct" mode, skip [almost] all the tracing ceremony // and just call into Trace.WriteLine(). Otherwise, use the // TraceOps class and all its special handling. Either way, // figure out the String.Format() arguments ahead of time, // based on our current "normalize" and "ellipsis" settings. // try { string arg0 = FormatOps.WrapTraceOrNull( normalizeArguments, ellipsisArguments, quoteArguments, displayArguments, eventArgs.Arguments); string arg1 = FormatOps.WrapTraceOrNull( normalizeResult, ellipsisResult, quoteResult, displayResult, eventArgs.Result); if (direct) { // // NOTE: This is just an extremely thin wrapper around // the Trace.WriteLine method. // DebugOps.TraceWriteLine(String.Format( directFormat, arg0, arg1), directCategory); } else { // // NOTE: Use the tracing subsystem. // TraceOps.DebugTrace(String.Format( normalFormat, arg0, arg1), normalCategory, TracePriority.EngineDebug); } return(ReturnCode.Ok); } catch (Exception e) { TraceOps.DebugTrace( e, typeof(Trace).Name, TracePriority.EngineError); result = e; return(ReturnCode.Error); } }