FreeTrainの進化系を目指す
Custom attribute to specifies class which requires initialization on assembly loaded.
| @@ -5,8 +5,11 @@ | ||
| 5 | 5 | using nft.util; |
| 6 | 6 | using nft.ui.mainframe; |
| 7 | 7 | using System.Threading; |
| 8 | +using System.Linq; | |
| 9 | +using nft.core; | |
| 10 | +using nft.framework; | |
| 8 | 11 | |
| 9 | -namespace Starter | |
| 12 | +namespace nft.starter | |
| 10 | 13 | { |
| 11 | 14 | public class Starter |
| 12 | 15 | { |
| @@ -35,6 +38,8 @@ | ||
| 35 | 38 | Application.Run(new MainFrame(args)); |
| 36 | 39 | } |
| 37 | 40 | |
| 41 | + | |
| 42 | + | |
| 38 | 43 | static void Application_ThreadException(object sender, ThreadExceptionEventArgs e) { |
| 39 | 44 | if(UIUtil.ShowException(e.Exception.Message, e.Exception, UIInformLevel.severe)) |
| 40 | 45 | throw e.Exception; |
| @@ -1,5 +1,6 @@ | ||
| 1 | 1 | using System.Reflection; |
| 2 | 2 | using System.Runtime.CompilerServices; |
| 3 | +using nft.framework; | |
| 3 | 4 | |
| 4 | 5 | // |
| 5 | 6 | // アセンブリに関する一般情報は以下の |
| @@ -13,7 +14,8 @@ | ||
| 13 | 14 | [assembly: AssemblyProduct("NeoFT")] |
| 14 | 15 | [assembly: AssemblyCopyright("(C)Copyright by c477 & K.Kawaguchi, 2004")] |
| 15 | 16 | [assembly: AssemblyTrademark("")] |
| 16 | -[assembly: AssemblyCulture("")] | |
| 17 | +[assembly: AssemblyCulture("")] | |
| 18 | +[assembly: InitializeOnLoad(typeof(nft.core.Core))] | |
| 17 | 19 | |
| 18 | 20 | // |
| 19 | 21 | // アセンブリのバージョン情報は、以下の 4 つの属性で構成されます : |
| @@ -31,7 +31,7 @@ | ||
| 31 | 31 | } |
| 32 | 32 | |
| 33 | 33 | public GameImpl(ITerrainMap map, Calendar cal) |
| 34 | - : this(I18n.T("GameManager","NewGame"), map, cal) { | |
| 34 | + : this(I18n.T("GameManager", "NewGame"), map, cal) { | |
| 35 | 35 | } |
| 36 | 36 | |
| 37 | 37 | public TerrainMapImpl TerrainMap { |
| @@ -13,7 +13,7 @@ | ||
| 13 | 13 | /// <summary> Main resources. </summary> |
| 14 | 14 | //public static readonly NftProperties resources = NftProperties.LoadFromFile(Directories.AppBaseDir + "nftcore.resource.xml", false); |
| 15 | 15 | |
| 16 | - static Core() | |
| 16 | + static Core() | |
| 17 | 17 | { |
| 18 | 18 | I18n.LoadFile(Directories.AppBaseDir + "nftcore.resource.xml"); |
| 19 | 19 | ConfigureService.RegisterAssembly(Assembly.GetAssembly(Type.GetType("nft.core.Core"))); |
| @@ -2,74 +2,74 @@ | ||
| 2 | 2 | <!--エラーメッセージは、改行やタブがそのまま使用されるので、ご注意ください。--> |
| 3 | 3 | <properties name="framework"> |
| 4 | 4 | <properties name="Directories"> |
| 5 | - <property name="Directory '{0}' is not exist. Do you want to create?">{0}は存在しません。 | |
| 5 | + <property type="string" name="Directory '{0}' is not exist. Do you want to create?">{0}は存在しません。 | |
| 6 | 6 | 作成しますか?</property> |
| 7 | - <property name="Failed to create a directory '{0}'. Use default path instead.">{0}は作成できませんでした。 | |
| 7 | + <property type="string" name="Failed to create a directory '{0}'. Use default path instead.">{0}は作成できませんでした。 | |
| 8 | 8 | 標準の設定を使用します。</property> |
| 9 | 9 | </properties> |
| 10 | 10 | <properties name="PluginListDialog"> |
| 11 | - <property name="Uncheck to forbid cpu using this plug-in.">コンピューターに使わせたくないプラグインは、 | |
| 11 | + <property type="string" name="Uncheck to forbid cpu using this plug-in.">コンピューターに使わせたくないプラグインは、 | |
| 12 | 12 | チェックを外して下さい。</property> |
| 13 | - <property name="This contribution cannot invalidate.">このコントリビューションは無効化できません。</property> | |
| 13 | + <property type="string" name="This contribution cannot invalidate.">このコントリビューションは無効化できません。</property> | |
| 14 | 14 | </properties> |
| 15 | 15 | <properties name="nft.framework.plugin"> |
| 16 | - <property name="Too many plug-in load errors! Check out remaining errors in the 'Plug-in List'."> | |
| 16 | + <property type="string" name="Too many plug-in load errors! Check out remaining errors in the 'Plug-in List'."> | |
| 17 | 17 | プラグインロードエラーが多すぎます。以降のエラーは省略します。 |
| 18 | 18 | エラーの発生したプラグインを確認するには、プラグイン一覧をご覧下さい。 |
| 19 | 19 | </property> |
| 20 | - <property name="Dependent plug-in:{1} (required for the plug-in:{0}) is not found."> | |
| 20 | + <property type="string" name="Dependent plug-in:{1} (required for the plug-in:{0}) is not found."> | |
| 21 | 21 | プラグイン{0}に必要な |
| 22 | 22 | プラグイン{1}が見つかりません。 |
| 23 | 23 | </property> |
| 24 | - <property name="Failed to load contribution[{1}] (ID={2}) from the file '{0}'."> | |
| 24 | + <property type="string" name="Failed to load contribution[{1}] (ID={2}) from the file '{0}'."> | |
| 25 | 25 | ファイル{0} |
| 26 | 26 | からのコントリビューション[{1}]のロードに失敗しました。 |
| 27 | 27 | ID={2} |
| 28 | 28 | </property> |
| 29 | - <property name="Failed to load plug-in:{0}.">プラグイン{0}がロードできませんでした。</property> | |
| 30 | - <property name="Failed to initialize contribution[{1}] in the plug-in:{0}."> | |
| 29 | + <property type="string" name="Failed to load plug-in:{0}.">プラグイン{0}がロードできませんでした。</property> | |
| 30 | + <property type="string" name="Failed to initialize contribution[{1}] in the plug-in:{0}."> | |
| 31 | 31 | プラグイン{0}内のコントリビューション[{1}]が初期化できませんでした。 |
| 32 | 32 | ID={2} |
| 33 | 33 | </property> |
| 34 | - <property name="Failed to create CommandEntity[type={0}, class={1}, method={2}]."> | |
| 34 | + <property type="string" name="Failed to create CommandEntity[type={0}, class={1}, method={2}]."> | |
| 35 | 35 | コマンドコントリビューションを初期化できません。 |
| 36 | 36 | Type={0} |
| 37 | 37 | Class={1} |
| 38 | 38 | Method={2} |
| 39 | 39 | </property> |
| 40 | - <property name="An attribute '{1}' is required for the node '{0}'.">XMLノード[{0}]には[{1}]属性が必要です。 | |
| 40 | + <property type="string" name="An attribute '{1}' is required for the node '{0}'.">XMLノード[{0}]には[{1}]属性が必要です。 | |
| 41 | 41 | ソース:{2}</property> |
| 42 | - <property name="Failed to create an instance of the class '{0}'.">指定されたクラス[{0}]のインスタンス作成に失敗しました。 | |
| 42 | + <property type="string" name="Failed to create an instance of the class '{0}'.">指定されたクラス[{0}]のインスタンス作成に失敗しました。 | |
| 43 | 43 | ソース:{1}</property> |
| 44 | - <property name="Cannot cast the class'{0}' to the class'{1}'.">クラス[{0}]を[{1}]にキャストできません。 | |
| 44 | + <property type="string" name="Cannot cast the class'{0}' to the class'{1}'.">クラス[{0}]を[{1}]にキャストできません。 | |
| 45 | 45 | ソース:{2}</property> |
| 46 | 46 | </properties> |
| 47 | 47 | <properties name="GlobalModules"> |
| 48 | - <property name="ERROR while loading a core module.">コア・モジュール読み込みエラー</property> | |
| 48 | + <property type="string" name="ERROR while loading a core module.">コア・モジュール読み込みエラー</property> | |
| 49 | 49 | </properties> |
| 50 | 50 | <properties name="WebLoader"> |
| 51 | - <property name="Web Exception: {0}(state={1}, url={2} ).">ファイルのダウンロードに失敗しました。 | |
| 51 | + <property type="string" name="Web Exception: {0}(state={1}, url={2} ).">ファイルのダウンロードに失敗しました。 | |
| 52 | 52 | URL:{0} |
| 53 | 53 | {1} state={2}</property> |
| 54 | - <property name="Exception raised while downloading url={0} .">ダウンロード中に例外が発生しました。 | |
| 54 | + <property type="string" name="Exception raised while downloading url={0} .">ダウンロード中に例外が発生しました。 | |
| 55 | 55 | URL:{0}</property> |
| 56 | 56 | </properties> |
| 57 | 57 | <properties name="nft.ui.command"> |
| 58 | - <property name="Exception raised while executing the command[ID={0}].">コマンド[ID={0}]の実行中に例外が発生しました。</property> | |
| 58 | + <property type="string" name="Exception raised while executing the command[ID={0}].">コマンド[ID={0}]の実行中に例外が発生しました。</property> | |
| 59 | 59 | </properties> |
| 60 | 60 | <properties name="ImageUtil"> |
| 61 | - <property name="{0}bit RGB">{0}bit RGB</property> | |
| 62 | - <property name="{0}bit ARGB">{0}bit ARGB</property> | |
| 63 | - <property name="Indexed {1} Colors">{1}色パレット</property> | |
| 64 | - <property name="Indexed {1} Gray scales">{1}色グレー</property> | |
| 65 | - <property name="{0}bit Gray scales">{0}bit グレー</property> | |
| 61 | + <property type="string" name="{0}bit RGB">{0}bit RGB</property> | |
| 62 | + <property type="string" name="{0}bit ARGB">{0}bit ARGB</property> | |
| 63 | + <property type="string" name="Indexed {1} Colors">{1}色パレット</property> | |
| 64 | + <property type="string" name="Indexed {1} Gray scales">{1}色グレー</property> | |
| 65 | + <property type="string" name="{0}bit Gray scales">{0}bit グレー</property> | |
| 66 | 66 | </properties> |
| 67 | 67 | <properties name="UiUtil"> |
| 68 | - <property name="Are you sure to exit 'NeoFT'?">NeoFTを終了してよろしいですか?</property> | |
| 68 | + <property type="string" name="Are you sure to exit 'NeoFT'?">NeoFTを終了してよろしいですか?</property> | |
| 69 | 69 | </properties> |
| 70 | 70 | <properties name="MainFrame"> |
| 71 | - <property name="long_title">Neo Free Train</property> | |
| 72 | - <property name="short_title">NeoFT</property> | |
| 71 | + <property type="string" name="long_title">Neo Free Train</property> | |
| 72 | + <property type="string" name="short_title">NeoFT</property> | |
| 73 | 73 | </properties> |
| 74 | 74 | |
| 75 | 75 | </properties> |
| \ No newline at end of file |
| @@ -0,0 +1,20 @@ | ||
| 1 | +using System; | |
| 2 | +using System.Collections.Generic; | |
| 3 | +using System.Text; | |
| 4 | + | |
| 5 | +namespace nft.framework { | |
| 6 | + [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] | |
| 7 | + public class InitializeOnLoadAttribute : Attribute { | |
| 8 | + Type type; | |
| 9 | + | |
| 10 | + public InitializeOnLoadAttribute(Type type) { | |
| 11 | + this.type = type; | |
| 12 | + } | |
| 13 | + | |
| 14 | + public Type Type { | |
| 15 | + get { | |
| 16 | + return type; | |
| 17 | + } | |
| 18 | + } | |
| 19 | + } | |
| 20 | +} |
| @@ -12,6 +12,7 @@ | ||
| 12 | 12 | using System.Drawing; |
| 13 | 13 | using System.Runtime; |
| 14 | 14 | using nft.framework.drawing; |
| 15 | +using System.Reflection; | |
| 15 | 16 | |
| 16 | 17 | namespace nft.framework |
| 17 | 18 | { |
| @@ -71,7 +72,8 @@ | ||
| 71 | 72 | { |
| 72 | 73 | I18n.LoadFile(Directories.AppBaseDir + "nftfw.resource.xml"); |
| 73 | 74 | Hashtable h_args = paresArgs(args); |
| 74 | - Directories.Initialize(h_args); | |
| 75 | + InitializeAssemblies(); | |
| 76 | + Directories.Initialize(h_args); | |
| 75 | 77 | |
| 76 | 78 | //InformationService service = new InformationService(); |
| 77 | 79 | theFrame = frame; |
| @@ -112,6 +114,25 @@ | ||
| 112 | 114 | } |
| 113 | 115 | return table; |
| 114 | 116 | } |
| 115 | - | |
| 117 | + | |
| 118 | + private static void InitializeAssemblies() { | |
| 119 | + AppDomain.CurrentDomain.AssemblyLoad += new AssemblyLoadEventHandler(AssemblyInitializer); | |
| 120 | + Assembly[] asms = AppDomain.CurrentDomain.GetAssemblies(); | |
| 121 | + foreach (Assembly asm in asms) { | |
| 122 | + AssemblyInitializer(null, new AssemblyLoadEventArgs(asm)); | |
| 123 | + } | |
| 124 | + } | |
| 125 | + | |
| 126 | + private static void AssemblyInitializer(object sender, AssemblyLoadEventArgs args) { | |
| 127 | + Assembly asm = args.LoadedAssembly; | |
| 128 | + if (asm.GlobalAssemblyCache) | |
| 129 | + return; | |
| 130 | + // force static constructors in types specified by InitializeOnLoad | |
| 131 | + object[] attributes = asm.GetCustomAttributes(typeof(InitializeOnLoadAttribute), false); | |
| 132 | + foreach (InitializeOnLoadAttribute attr in attributes) { | |
| 133 | + System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(attr.Type.TypeHandle); | |
| 134 | + Debug.WriteLine("Init class on load assembly: class="+attr.Type.FullName+ ", module="+ Path.GetFileName(asm.CodeBase)); | |
| 135 | + } | |
| 136 | + } | |
| 116 | 137 | } |
| 117 | 138 | } |