Example #1
0
        ///////////////////////////////////////////////////////////////////////

        /// <summary>
        /// This method is the starting point for threads created to manage a
        /// new Tcl form and interpreter.
        /// </summary>
        /// <param name="obj">
        /// The Tcl client data to pass to the new Tcl form upon creation.
        /// </param>
        private static void CreateFormThreadStart(
            object obj /* in */
            )
        {
            try
            {
                //
                // NOTE: The data passed to this thread start routine
                //       must be a string array or null.
                //
                IEnumerable <string> args = obj as IEnumerable <string>;
                TclForm form = null;

                try
                {
                    //
                    // NOTE: Create a new instance of the Tcl form, passing
                    //       the arguments we received from the other thread.
                    //
                    form = Create(args);

                    //
                    // NOTE: Upon success, show the form modally.
                    //
                    if (form != null)
                    {
                        Application.Run(form);
                    }
                }
                finally
                {
                    //
                    // NOTE: Upon completion, successful or otherwise, dispose
                    //       of the form and its contained resources (including
                    //       the Tcl interpreter).
                    //
                    if (form != null)
                    {
                        form.Dispose();
                        form = null;
                    }
                }
            }
            catch (Exception e)
            {
                ShowResult(ReturnCode.Error, e);
            }
        }
Example #2
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);
        }