Beispiel #1
0
        ///////////////////////////////////////////////////////////////////////

        /// <summary>
        /// Attempts to wrap the Tcl manager host with one that captures the
        /// output from the internal DebugOps class.
        /// </summary>
        /// <param name="tclManager">
        /// The Tcl manager object containing the host to wrap.
        /// </param>
        /// <param name="setup">
        /// Non-zero if the Tcl manager host is being wrapped -OR- zero if it
        /// is being unwrapped.
        /// </param>
        private static void SetupManagerHost(
            ITclManager tclManager, /* in */
            bool setup              /* in */
            )
        {
            if (tclManager != null)
            {
                Interpreter interpreter = tclManager as Interpreter;

                if (interpreter != null)
                {
                    ReturnCode hostCode;
                    Result     hostError = null;

                    if (setup)
                    {
                        IHost host = null;

                        hostCode = Utility.CopyAndWrapHost(
                            interpreter, typeof(Class10), ref host,
                            ref hostError);

                        if (hostCode == ReturnCode.Ok)
                        {
                            interpreter.Host = host;
                            return;
                        }
                    }
                    else
                    {
                        hostCode = Utility.UnwrapAndDisposeHost(
                            interpreter, ref hostError);

                        if (hostCode == ReturnCode.Ok)
                        {
                            return;
                        }
                    }

                    ShowResult(hostCode, hostError);
                }
            }
        }
Beispiel #2
0
        ///////////////////////////////////////////////////////////////////////

        /// <summary>
        /// Disposes the Tcl manager object and then sets the value of its
        /// parameter to null.  This method may only be called on the primary
        /// thread associated with the specified Tcl manager.
        /// </summary>
        /// <param name="manager">
        /// The Tcl manager object to dispose and then set to null.
        /// </param>
        private static void DisposeManager(
            ref ITclManager tclManager /* in, out */
            )
        {
            if (tclManager != null)
            {
                //
                // NOTE: See if the Tcl manager supports IDisposable (it
                //       should).  If so, dispose it.
                //
                IDisposable disposable = tclManager as IDisposable;

                if (disposable != null)
                {
                    disposable.Dispose();
                    disposable = null;
                }

                tclManager = null;
            }
        }
Beispiel #3
0
        ///////////////////////////////////////////////////////////////////////

        /// <summary>
        /// Attempts to cancel the Tcl script in progress in the all Tcl
        /// interpreters managed by the specified Tcl manager object.  This
        /// method may be called from any thread.
        /// </summary>
        /// <param name="strict">
        /// Non-zero to return an error if the script in progress cannot be
        /// canceled for any of the Tcl interpreters.
        /// </param>
        /// <param name="error">
        /// Upon failure, this parameter will be modified to contain an error
        /// message.
        /// </param>
        /// <returns>
        /// A standard Tcl return code.
        /// </returns>
        private static ReturnCode CancelAll(
            bool strict,     /* in */
            ref Result error /* out */
            )
        {
            lock (syncRoot)
            {
                if (forms != null)
                {
                    try
                    {
                        foreach (TclForm form in forms.Keys)
                        {
                            if (form == null) // NOTE: Redundant?
                            {
                                continue;
                            }

                            //
                            // NOTE: Grab the Eagle interpreter for this
                            //       form.
                            //
                            ITclManager tclManager = form.tclManager;

                            if (tclManager == null)
                            {
                                continue;
                            }

                            //
                            // NOTE: Grab the Tcl interpreter name for
                            //       this form.
                            //
                            string interpName = form.interpName;

                            //
                            // NOTE: Cancel the script being evaluated
                            //       for this form instance, if any.
                            //
                            ReturnCode cancelCode;
                            Result     cancelError = null;

                            cancelCode = tclManager.CancelTclEvaluate(
                                interpName, null, ref cancelError);

                            if (cancelCode != ReturnCode.Ok)
                            {
                                if (strict)
                                {
                                    //
                                    // NOTE: Strict mode means that we
                                    //       stop upon encountering an
                                    //       error and return that error
                                    //       to the caller.
                                    //
                                    error = cancelError;
                                    return(cancelCode);
                                }
                                else
                                {
                                    //
                                    // NOTE: Otherwise, just keep going
                                    //       (after showing the error to
                                    //       the user).
                                    //
                                    ShowResult(cancelCode, cancelError);
                                }
                            }
                        }

                        return(ReturnCode.Ok);
                    }
                    catch (Exception e)
                    {
                        error = e;
                    }
                }
                else
                {
                    error = "invalid forms collection";
                }
            }

            return(ReturnCode.Error);
        }
Beispiel #4
0
        ///////////////////////////////////////////////////////////////////////

        #region Static "Factory" Members
        public static TclForm Create(
            IEnumerable <string> args /* in */
            )
        {
            TclForm     form       = null;
            ITclManager tclManager = null;
            ReturnCode  code       = ReturnCode.Ok;
            Result      result     = null;

            try
            {
                form = new TclForm();

                //
                // NOTE: Save the passed in command line arguments for
                //       later.
                //
                form.args = args;

                //
                // NOTE: Create a new Eagle interpreter; currently, this
                //       is necessary to use the Tcl integration features
                //       of Eagle.
                //
                tclManager = Interpreter.Create(args, DefaultCreateFlags,
                                                ref result);

                if (tclManager != null)
                {
                    //
                    // NOTE: Attempt to use our custom Tcl manager host
                    //       implementation, if applicable.
                    //
                    SetupManagerHost(tclManager, true);

                    //
                    // NOTE: Automatically locate and select the "best"
                    //       available build of Tcl, if any.
                    //
                    code = tclManager.LoadTcl(
                        DefaultFindFlags, DefaultLoadFlags, null,
                        DefaultMinimumVersion, DefaultMaximumVersion,
                        DefaultUnknownVersion, null, ref result);

                    if (code == ReturnCode.Ok)
                    {
                        //
                        // NOTE: Grab the name for the newly created
                        //       Tcl interpreter.
                        //
                        string interpName = result;

                        //
                        // NOTE: Create a new command object.  This will
                        //       be used to demonstrate implementing a
                        //       Tcl command in managed code.
                        //
                        ICommand command = Class6.NewCommand("class6",
                                                             new ClientData(form), DefaultCommandFlags);

                        //
                        // NOTE: Create a Tcl command bridging object.
                        //       This is used to translate inbound
                        //       native calls for a particular command
                        //       to a managed method call.
                        //
                        ITclEntityManager tclEntityManager = tclManager
                                                             as ITclEntityManager;

                        if (tclEntityManager != null)
                        {
                            code = tclEntityManager.AddTclBridge(
                                command, interpName, command.Name,
                                command.ClientData, false, false,
                                ref result);
                        }
                        else
                        {
                            result = "invalid Tcl entity manager";
                            code   = ReturnCode.Error;
                        }

                        //
                        // NOTE: Did we successfully create the bridged
                        //       command?
                        //
                        if (code == ReturnCode.Ok)
                        {
                            //
                            // NOTE: Save the created Eagle interpreter.
                            //
                            form.tclManager = tclManager;

                            //
                            // NOTE: Save the name of the created Tcl
                            //       interpreter.
                            //
                            form.interpName = interpName;

                            //
                            // NOTE: Keep track of this form in the
                            //       master collection.  This collection
                            //       is primarily used when script
                            //       cancellation needs to be performed
                            //       for every Tcl interpreter we have
                            //       created.
                            //
                            lock (syncRoot)
                            {
                                if (forms != null)
                                {
                                    forms.Add(form, null);
                                }
                            }
                        }
                    }
                }
                else
                {
                    code = ReturnCode.Error;
                }
            }
            catch (Exception e)
            {
                result = e;
                code   = ReturnCode.Error;
            }
            finally
            {
                if (code != ReturnCode.Ok)
                {
                    //
                    // NOTE: We failed to fully create the form.  All
                    //       the resources we managed to successfully
                    //       create must be cleaned up now.
                    //
                    // NOTE: Dispose of the Eagle interpreter now
                    //       just in case the form does not have
                    //       the private variable set correctly.
                    //
                    DisposeManager(ref tclManager); /* throw */

                    if (form != null)
                    {
                        //
                        // NOTE: If the form had an Eagle interpreter,
                        //       it should have already been disposed
                        //       (above) because we use the local
                        //       variable prior to setting the form
                        //       variable.  To be sure that the now
                        //       disposed Eagle interpreter is not
                        //       used during form disposal, we need to
                        //       null out the form variable now.
                        //
                        form.tclManager = null;

                        //
                        // NOTE: Now, dispose any other resources held
                        //       by the form.
                        //
                        form.Dispose();
                        form = null;
                    }
                }
            }

            if (code != ReturnCode.Ok)
            {
                ShowResult(code, result);
            }

            return(form);
        }