IronPythonは何に使えばいいんだろう
なぜか急にIronPythonでYaneSDKを使ってみたくなったのでいろいろ突っ込んで試してみる.IronPythonについては以下の記事参照.要するにPythonの.net版である.
【ハウツー】IronPythonを飼いならす - IronPythonの紹介とバージョン1.1の特徴 (1) IronPythonとは? | パソコン | マイナビニュース
IronPythonをIDEから使うには2種類の方法があって,Visual Studio 2005 Professionalに統合するか,最近新しく出たIronPython Studioというのを使えば良い.それぞれ以下の記事参照.
[ python / VS2005 ] VS2005 に IronPython を統合する方法: Fomalhaut of Piscis Australis
[ IronPython / VS2008 ] IronPython Studio 登場: Fomalhaut of Piscis Australis
IronPython Studioの方はまだ未完成で,GUIからプロジェクトにファイルを追加できるけど削除できない,参照は追加すらできない.しかも,VS2005に統合した方では動いたIronPythonのコードが動かず,現状では実用には向かないだろう.IronPython自体が開発途上だからしょうがないが,ちょっと試してみた感じで思ったことは
Pythonのメリットを全然感じられない
.netで作られたものもCで書かれたものも両方使えるPythonという意味ではメリットはあるのだろうが,スクリプトを書いてから,コンパイルして,起動時に.netランタイムをロードして,と動かすまでの時間が極めて長く感じる.しかも,動的型付けの言語なのでIDEを使っていてもそれほどインテリセンスのメリットを感じることができない.
使う理由がなくなってしまった.
ちなみにYaneSDKを動かす時にちょっと困ったところ.C#でenumを受け取るようなコードを書いているときにPythonで何を渡してやれば使えるかがさっぱりわからなくて,試行錯誤した結果下のコードで動いた.
長いので
C#でこう書くところ.
using System; using System.Collections.Generic; using System.Text; using Yanesdk.Ytl; using Yanesdk.System; namespace ほげ { enum Scenes { Startmenu, Game, } class SceneFactory : TaskFactoryBase<Scenes> { private GameSystem system; public SceneFactory(GameSystem system) { this.system = system; } public override TaskBase CreateTask(Scenes name) { switch (name) { case Scenes.Startmenu: return new StartmenuScene(system); case Scenes.Game: return new GameScene(system); } return null; } } }
Pythonだとこう書く.
# -*- coding: shift_jis -*- from Yanesdk.Ytl import * from Yanesdk.System import * from StartMenuScene import StartMenuScene from GameScene import GameScene class Scenes(object): pass Scenes.Startmenu = object() Scenes.Game = object() class SceneFactory(TaskFactoryBase[Scenes]): def __init__(self, system): self.system = system def CreateTask(self, scene_name): if scene_name == Scenes.Startmenu: return StartMenuScene(self.system) elif scene_name == Scenes.Game: return GameScene(self.system) return None
列挙型をPythonで使いたいという質問が出るとたいてい,下のように整数を入れて使っておけばいいじゃないという答えが返ってくるが,これをやると整数じゃなくてオブジェクトを渡しやがれ!とエラーが出てきたのでオブジェクトを渡せる形が上の通り.
class Enum: Hoge = 0 Foo = 1
ちなみに,C#のジェネリックをPythonで使う場合の書き方も迷ったので一応メモっとく.
# -*- coding: shift_jis -*- from Yanesdk.Draw import * from Yanesdk.Ytl import * from Yanesdk.Timer import * from Yanesdk.Math import * from Yanesdk.Sound import * from Yanesdk.Input import * from Yanesdk.System import * from SceneFactory import * from SystemTask import * from System import * class GameSystem: DEFAULT_FPS = 60 def __init__(self): print "GameSystem.__init__() called" self.window = SDLWindow2DGl() self.screen = self.window.Screen self.fpsTimer = FpsTimer() self.fpsTimer.Fps = GameSystem.DEFAULT_FPS self.gameTimer = GameTimer() self.taskController = TaskController() # ジェネリックは『作りたいクラス名[渡したい型名]()』として使う self.sceneController = SceneController[Scenes]() self.bQuit = False; self.mouse = MouseInput() self.keyboard = KeyBoardInput() self.smartTextureLoader = SmartTextureLoader() self.smartSoundLoader = SmartSoundLoader() self.smartFontLoader = SmartFontLoader() self.fontLoader = FontLoader() def __tex_func(): return GlTexture() self.fontRepository = FontRepository(__tex_func) self.rand = Rand() self.rand.Randomize() self.window.TestVideoMode(800, 600, 0) self.window.SetCaption("ほげほげアプリ") self.sceneController.TaskFactory = SceneFactory(self) system_task = SystemTask() controller = self.sceneController self.taskController.AddTask(system_task, 0) self.taskController.AddTask(self.sceneController, 1) def Run(self): self.sceneController.JumpScene(Scenes.Startmenu) while not self.bQuit and not self.sceneController.End: if SDLFrame.PollEvent() == YanesdkResult.ShouldBeQuit: self.bQuit = True else: self.bQuit = False self.taskController.CallTask(self)