雑記帳

ブログを使わずにArrangeNoteで作っている公開雑記帳

Jun 06, 2008 - IronPython2.0B2のScriptDomainManager.SetCommandDispatcherを復活させる (2)

前回の記事のパッチでは、コンソールで入力したスクリプトで例外が発生するとipy.exeが異常終了してしまうので、try-catchするように修正してみました。

diff -r -c -P PythonCommandLine.cs.orig PythonCommandLine.cs
*** PythonCommandLine.cs.orig	Fri Apr 25 12:04:24 2008
--- PythonCommandLine.cs	Thu Jun 05 09:04:11 2008
***************
*** 13,18 ****
--- 13,20 ----
   *
   * ***************************************************************************/
  
+ #define COMMANDDISPATCHER_PATCH
+ 
  using System;
  using System.IO;
  using System.Reflection;
***************
*** 331,337 ****
--- 333,360 ----
              PythonCompilerOptions pco = (PythonCompilerOptions)Language.GetCompilerOptions(Scope);
              pco.Module |= ModuleOptions.ExecOrEvalCode;
  
+ #if COMMANDDISPATCHER_PATCH
+             ScriptDomainManager domainManager = PythonContext.DomainManager;
+             if ( domainManager.GetCommandDispatcher() != null ) {
+                 Exception excep = null;
+                 CallTarget0 run_code = delegate() {
+                     try {
+                         su.Compile(pco, ErrorSink).Run(Scope);
+                     } catch( Exception excep_ ) {
+                         excep = excep_;
+                     }
+                     return null;
+                 };
+                 domainManager.DispatchCommand( run_code );
+                 if ( excep != null ) {
+                     throw excep;
+                 }
+             } else {
+                 su.Compile(pco, ErrorSink).Run(Scope);
+             }
+ #else
              su.Compile(pco, ErrorSink).Run(Scope);
+ #endif
              return null;
          }

まだ2.0B3出てないなあ...

Jun 05, 2008 - IronPython2.0B2のScriptDomainManager.SetCommandDispatcherを復活させる

スクリプト言語を使うメリットの一つに、コンソールからスクリプトを入力して対話操作できるということが挙げられると思います。 Tcl/TkやJythonを使っていた頃は、この機能のおかげでwidgetやAWTの使い方を色々試すことができて、とても助かりました。

IronPython2.0A6の頃までは、Tutorialディレクトリの中にあるavalon.pyを使って.NET Framework 3.0のWPFを対話操作で動かすことができていて、WPFのクラスライブラリを学ぶのに大助かりだったのですが、それより後のバージョンではWPFの対話操作ができなくなってしまいました。 これでは非常に不便です。

そこで、IronPython2.0B2のソースから原因を探ってみたところ、ScriptDomainManager.SetCommandDispatcher(dispatcher)でセットしたCommandDispatcherは、コンソールで入力したコマンドの実行には全く使われていないことが解りました。

そこで、とりあえずWPFを対話操作できるように、IronPython2.0A6のソースと比較して作ったのが次のパッチ:

diff -r -c -P PythonCommandLine.cs.orig PythonCommandLine.cs
*** PythonCommandLine.cs.orig	Fri Apr 25 12:04:24 2008
--- PythonCommandLine.cs	Wed Jun 04 08:24:26 2008
***************
*** 13,18 ****
--- 13,20 ----
   *
   * ***************************************************************************/
  
+ #define	COMMANDDISPATCHER_PATCH
+ 
  using System;
  using System.IO;
  using System.Reflection;
***************
*** 331,337 ****
--- 333,352 ----
              PythonCompilerOptions pco = (PythonCompilerOptions)Language.GetCompilerOptions(Scope);
              pco.Module |= ModuleOptions.ExecOrEvalCode;
  
+ #if COMMANDDISPATCHER_PATCH
+             ScriptDomainManager domainManager = PythonContext.DomainManager;
+             if ( domainManager.GetCommandDispatcher() != null ) {
+ 				CallTarget0 run_code = delegate() {
+             	    su.Compile(pco, ErrorSink).Run(Scope);
+ 				    return null;
+ 				};
+ 				domainManager.DispatchCommand( run_code );
+ 			} else {
+             	su.Compile(pco, ErrorSink).Run(Scope);
+ 			}
+ #else
              su.Compile(pco, ErrorSink).Run(Scope);
+ #endif
              return null;
          }

このパッチを適用すると、IronPython2.0B2に付属のTutorial/avalon.pyを使ってWPFを対話操作で動かすことができるようになります。

IronPython 2.0 Beta (2.0.0.2000) on .NET 2.0.50727.3031
Copyright (c) Microsoft Corporation. All rights reserved.
>>> from avalon import *
>>> win = Window( Title='ボタンを回す', Width=300, Height=300 )
>>> win.Show()
>>> win.Content = Canvas()
>>> btn = Button( Content='回るよ' )
>>> win.Content.Children.Add( btn )
0
>>> Canvas.SetLeft( btn, 100 )
>>> Canvas.SetTop( btn, 100 )
>>> btn.RenderTransform = RotateTransform()
>>> animation = DoubleAnimation( From=0.0, To=360.0, Duration=Duration( TimeSpan( 0, 0, 5 ) ) )
>>> def clicked( sender, e ):
...     btn.RenderTransform.BeginAnimation( RotateTransform.AngleProperty, animation )
...
>>> btn.Click += clicked
>>>

一応、これで、WPFを対話操作で動かせるようになりました。

さて、Silverlight 2 Beta 2が発表されましたから、IronPython2.0B3もまもなく公開でしょうか。

記事の一覧

Copyright © 2008 Koichi Yamamoto