[前へ] [目次へ] [次へ]

グローバル定義空間


グローバル定義空間はFGESソースコードのうち、
他の定義空間以外の範囲に適用されます。
グローバル定義空間に記述できる内容は以下の通りです。

●グローバル変数の定義

   変数定義の構文については 変数 の項目を参照してください。

   グローバル変数はグローバル名前空間に登録され、
   スクリプトのどこからでも参照できるようになります。
   
   実体定義をした場合、グローバル変数はコンパイル中に直ちに実体化され、
   生成したクラスのイニシャライザが実行されます。
   そのため、実体定義をする場合は変数の型が
   不完全型、抽象クラス、インターフェイス、実体化不可型であってはいけません。
   
   また、初期化式が付随している場合、初期化式も直ちに実行されます。
   ここで実行されるイニシャライザおよび初期化式はコンパイルスレッドで実行され、
   一定時間以内に完了しない場合や、他のスレッドを待機するようなコードを実行すると
   例外が投入されます。(コンパイル中実行の制限)
   
   グローバル変数として実体化されたオブジェクトは
   グローバルメモリーホストに接続されます。
   グローバルメモリーホストはVMの実行中永続するメモリ管理オブジェクトであるため、
   グローバル変数は通常解放されず、VM終了時にもクリアラーは呼び出されません。
   (ただし、VM終了時にC++レベルのデストラクタは呼び出されます)

●グローバルメソッドの宣言、定義

   メソッド定義の構文については メソッド の項目を参照してください。

   グローバル定義空間に定義されたメソッドはグローバルメソッドと呼び、
   暗黙に static 属性となり、あらゆるメソッド内から呼び出すことができます。
   FGESでは全てのメソッドは何らかのクラスを対象にコンパイルされる必要があるため、
   グローバルメソッドは Global_Host というクラスを対象にコンパイルされます。
   ( Global_Host はこのためだけに存在し、実体化できず、メンバを一つも持っていません)

   メソッド名が #Setup の戻り値も引数もないグローバルメソッドは
   グローバルセットアップメソッドと解釈され、コンパイル後直ちに実行、その後破棄されます。
   ここで実行されるグローバルセットアップメソッドはコンパイルスレッドで実行され、
   一定時間以内に完了しない場合や、他のスレッドを待機するようなコードを実行すると
   例外が投入されます。(コンパイル中実行の制限)

   メソッドが宣言または定義されると、 FGESMethod 型の同名のグローバル変数として定義されます。
   ただし、グローバルセットアップメソッドはグローバル変数としては定義されません。

●メソッドの分割定義

   メソッド定義の構文については メソッド の項目を参照してください。

   クラス名を含む完全名をメソッド名として指定することにより、
   宣言のみ行われているグローバルメソッド、クラスメンバメソッドを定義することができます。
   なお定義時のメソッド宣言は事前に宣言されているものと完全に一致している必要があります。
   
   例:グローバルメソッド global_method の分割定義
<  1>
<  2>
   method int global_method();//グローバルメソッドの宣言
   
method int global_method(){retval 0;}//グローバルメソッドの定義 

   例:クラス C のクラスメンバメソッド member_method の分割定義
<  1>
<  2>
<  3>
<  4>
   class C{
      
method int member_method();//メンバメソッドの宣言
   }
   
method int C::member_method(){retval 0;}//メンバメソッドの定義 

●クラスの定義

   クラス定義の構文については クラス の項目を参照してください。

   グローバル定義空間に定義する場合、
   クラス名だけを記述することで不完全型としてクラスを宣言できます。
   不完全型として宣言されたクラスは同名のクラスを定義することで
   実体化および参照できるクラスになります。
   
   例:不完全型 incomplete_class を宣言する
      class incomplete_class;

   クラスが宣言または定義されると、 FGESClass 型の同名のグローバル変数として定義されます。

●インターフェイスの定義

   インターフェイス定義の構文については インターフェイス の項目を参照してください。

   グローバル定義空間に定義する場合、
   インターフェイス名だけを記述することで不完全型としてインターフェイスを宣言できます。
   不完全型として宣言されたインターフェイスは同名のインターフェイスを定義することで
   実装できるインターフェイスになります。
   
   例:不完全型 incomplete_interface を宣言する
      interface incomplete_interface;

   インターフェイスが宣言または定義されると、 FGESInterface 型の同名のグローバル変数として定義されます。

●既存クラスの対応インターフェイスの追加定義

   既に定義済みのクラスに新しいインターフェイス実装を追加することができます。
   対象のクラスが既に実装宣言をしているインターフェイスを再度追加することはできません。
   
   構文:(対象クラス名、および追加するインターフェイス名は 型名 解釈です)
   implements 対象クラス名 @@ 追加するインターフェイス名 {
      定義内容
   }


   「定義内容」にはメソッド宣言または定義を記述します。
   暗黙に追加するインターフェイスのメンバ実装となるので、
   クラス名、インターフェイス名の指定なしにメソッド名を記述します。
   ここで記述するメソッド宣言は追加するインターフェイスのメンバと外部インターフェイスが一致している必要があります。
   メソッド定義の構文については メソッド の項目を参照してください。

   例:クラス C に IInteger インターフェイス実装を追加する
<  1>
<  2>
<  3>
<  4>
<  5>
<  6>
<  7>
<  8>
   class C{ //クラスCを定義
      
var int n;
   }
   
implements C@@IInteger{
      
method void Get(editable IInteger val)const{val.Set(@n);} //IInteger@@Getを実装
      
method void Set(IInteger val); //IInteger@@Setを宣言
   }
   
method void C::IInteger@@Set(IInteger val){@n=val;} //C::IInteger@@Setを定義 

●エイリアス(別名)の定義

   グローバル名前空間に既にある参照を複製します。
   複製した参照と元になった参照は同じオブジェクトを共有し、
   オブジェクトに対して行われた結果も共有されます。
   
   また、この定義によって参照に関連付けられているオブジェクトの
   メモリ管理オブジェクトが変更されることはありません。
   
   構文:(複製元の名前、作成する名前ともに名前解決演算子を使用できません)
   alias 複製元の名前 作成する名前 ;

   例: Integer クラスを Number としても記述できるようにする(C/C++のtypedef的用法)
<  1>
<  2>
<  3>
<  4>
<  5>
<  6>
   alias Integer Number;
   
   
method bool test(){
      Number n; 
//型名として使えます
      
retval @@Integer#==@@Number; //true
   } 

●クラスメソッド(静的メソッド)のグローバル化

   既存クラスに所属するクラスメソッドをグローバルメソッド化します。
   ただしグローバルメソッド化されたクラスメソッドは引き続き元のクラスに所属しており、
   メンバ名前空間を通じてクラス共有メンバにアクセスできます。
   
   対象として使用できる名前はクラス名またはメソッド名で、
   名前解決演算子 :: を使用してクラス内のクラスまたはメソッドを指定できます。
   なお、対象の名前までのクラスパスは全てアクセス属性が public でなければいけません。
   
   対象としてクラス名を指定した場合はそのクラスが持つ、
   直属の public かつ static なメソッド全てをグローバルメソッド化します。

   対象としてメソッド名を指定した場合はそのメソッドが
   public かつ static である必要があります。

   対象としたメソッド名と同じ名前が既にグローバル名前空間に存在する場合はエラーになります。
   
   構文:
   using 対象の名前 ;

   例1: Math クラスのクラスメソッド全てをグローバルメソッド化する
<  1>
<  2>
<  3>
   using Math;
   
   
method Float DegSin(IFloat deg){retval Sin(Deg2Rad(deg));} 

   例2: Math クラスの Sin と Deg2Rad だけをグローバルメソッド化する
<  1>
<  2>
<  3>
<  4>
   using Math::Sin;
   
using Math::Deg2Rad;
   
   
method Float DegSin(IFloat deg){retval Sin(Deg2Rad(deg));} 

●他のFGESソースファイルのインストール

   他のFGESソースファイルを現在のFGES VMにインストールします。
   C/C++の #include に似ていますが、独立したコンパイル単位となる点が異なります。
   別のソースファイルのコンパイル中に required 宣言が行われた場合、
   そのソースファイル内で解決しなければいけません。
   
   対象の名前はインストールするFGESソースファイルを示す識別子であり、通常はファイル名です。
   ただしこの識別子をどう扱うかはFGESの実装に委ねられています。
   (複数のファイルをまとめたパッケージファイルから読み出す場合などのためです)
   
   また、既にインストールされている識別子が指定された場合は何もしません。
   
   コンソール版FGES Core1.00ではカレントディレクトリ基準の相対パスのファイル名として扱います。
   
   構文:(対象の名前は文字列定数でなければいけません)
   install 対象の名前 ;

   例: sub.fges を読み込む
   install "sub.fges";

[前へ] [目次へ] [次へ]

最終更新 2019/04/11