Mercurial > hg > Document > Growi
diff Gears/introduction/interface.md @ 2:b6c284fd5ae4
backup 2020-12-16
author | autobackup |
---|---|
date | Wed, 16 Dec 2020 15:11:16 +0900 |
parents | e12992dca4a0 |
children |
line wrap: on
line diff
--- a/Gears/introduction/interface.md Wed Dec 16 15:04:03 2020 +0900 +++ b/Gears/introduction/interface.md Wed Dec 16 15:11:16 2020 +0900 @@ -4,4 +4,102 @@ - JavaやgolangのInterface, Haskellの型クラスに相当する構文です ## Interfaceで定義するもの -- golangのInterfaceでは、関数の集合、及び関数の引数と返り値がinterfaceとして定義されていました \ No newline at end of file +- golangのInterfaceでは、関数の集合、及び関数の引数と返り値がinterfaceとして定義されていました +- GearsOSのItnerfaceでも同様に、使用するデータ構造と、関数を記述します +- 使用するデータ(DataGear)はPerlスクリプト側の改良により、`__code`の中に定義しておけば問題ないようになった + +## 書き方(~2019/02/03) + +``` +typedef struct InterfaceName<Type, Impl>{ + //入出力で使用するデータ構造を記述する + union Data* stack; + union Data* data; + union Data* data1; + + // APIとして使用するCodeGearを列挙する + //ここで利用する引数|出力は必ず上で列挙する必要がある + __code whenEmpty(...); + __code clear(Impl* stack,__code next(...)); + __code get2(Impl* stack, __code next(Type* data, Type* data1, ...)); + + //継続先のCodeGear + __code next(...); +} InterfaceName; +``` +- Type + - 自分自身の型 +- Impl + - 自分自身の実装の型 + - Stackの場合はSingleLinkedStackなど... + +## 書き方(2019/02/03~) + +- Perl側を改良したので引数を別で定義する必要がなくなった + +``` +typedef struct InterfaceName<Type, Impl>{ + // APIとして使用するCodeGearを列挙する + __code whenEmpty(...); + __code clear(Impl* stack,__code next(...)); + __code get2(Impl* stack, __code next(Type* data, Type* data1, ...)); + + //継続先のCodeGear + __code next(...); +} InterfaceName; +``` +## 仕様QA +`__code`の記述が始まる前に引数を宣言していた場合、宣言された引数のみが使われる。 + +(`__code`の中の引数はキャプチャされない) + +## Interfaceのファイルを利用するスクリプト +- interfaceのファイルは次のPerlスクリプトで利用され、CbCレベルでは実は参照されません +- `trans_impl.pl` + - cbcファイルの雛形を生成する際に、実装しているファイルから動的に呼び出されます +- ` generate_stub.pl` +- ` generate_context.pl` + - 入出力の引数チェックで行われます + - `generate_context`では、 `context.h`を生成する際に読み込まれます + +## CbCレベルでのInterface +- CbCレベルでは、 stub 及び, `context.h` の `union Data` の定義内で定義されています + - その為 `context.h` を `include`することで、これらの型を利用できます + +## Interfaceの具体例 +- [Stack](/Gears/introduction/interface/Stack) + +## Interfaceの実装の具体例 +- [SingleLinkedStack](/Gears/introduction/interface/impl/SingleLinkedStack) + +## Q&A + +### Q.「Interefaceに書いたDataGearはどうやって実装側から使うの?」 + +**A.「引数で与える」** + +### Q.「引数で使ってないけどContextにDataGearを登録したい」 + +**A.「専用の構文があります」** +- `// data_gear "WantStruct.h"` と書いておくと `generate_context.pl`時に解決される + +#### 例 + +- 例えば `"DataGearExample`をcontextに加えたい場合 + - まず最初に対象のヘッダファイルをどこかに作っておく + - `struct DataGearExample`を使いたいCbCファイルに以下の記述を書いておく + +```c +#include "hoge.h" +//data_gear "DataGearExample.h" +``` + +- `#interface "hoge.h"`構文もあるが、 `generate_stub`の時点でこの文が消えるので、コメントで追加している + +### Q.Intefaceに値持たせたいんだけど + +**A. 値は実装側に持たせるのでInterfaceには書いちゃだめ!!** + +- interfaceはあくまでもCodeGearの入出力だけのDataしかない +- 細かなDataはすべて実装に持たせる + - 同じfieldを持つ実装が複数存在する \ No newline at end of file