KL スタイルガイド¶
Fabric Engine version 2.4.0
Copyright (c) 2010-2017 Fabric Software Inc. All rights reserved.
以下の用例を KLコードのスタイル標準手引としてご利用ください。
- 中括弧を行末尾に開きます
- コンマの後ろにスペースを入れる, ただし括弧の前後には入れない.
- メンバや関数のプライバシーの説明のためにアンダースコアを用いては いけない. かわりに doxygen 修飾子を使用しましょう. ドキュメンテーションやコード補間など全てのシステムは
internal
修飾子を尊重します。古い KLエクステンションには、頭にアンダースコアを入れたものが存在するかもしれませんが、そのようなものはinternal
修飾子を使用するようにアップグレードするようにします。- doxygen記法を使用し、ドキュメンテーションをKL中に埋め込みます
- メンバのドキュメンテーションはそのメンバの 前 に記します
- 関数のパラメータのドキュメンテーションは、関数ドキュメンテーションに param修飾子を用い記載します。
- 用法を example と endexample 修飾子を使いコードに埋め込むことができます。
- カスタム restructured テキストのブロックを rst, endrst 修飾子を使いドキュメンテーション中に記載可能です。
注釈
ドキュメンテーションに使用する3連続スラッシュ(///)は、Fabricのドキュメンテーションシステム ――バージョン 1.13 から含まれる― に準じます。また、将来のリリースにはドキュメンテーションシステムをどのように活用し、独自のKLベースのドキュメントページを生成するかについてのガイドが含まれる予定です。/*
** Example: StyleGuide
*/
require Math;
/**
A datastructure to be used in the Style Guide. MyDataStructure inherits from Vec3.
\brief Some data structure
\seealso MyObject
\note This data structure has internal members which aren't shown here.
*/
struct MyDataStructure : Vec3 {
/// The name of the struct
String name;
/// An internal version counter.
/// \internal
Integer version;
};
/// Standard constructor taking a name
/// \param name The initial of the struct
function MyDataStructure(String name) {
this.name = name;
this.incrementVersion();
}
/// setter for the name of the MyDataStructure
/// \param name The new name of the struct
function MyDataStructure.setName!(String name) {
this.name = name;
this.incrementVersion();
}
/** getter for the name of the MyDataStructure
\example
MyDataStructure m('test');
report(m.getName());
\endexample
*/
function String MyDataStructure.getName() {
return this.name;
}
/// A internal method to increment the version everytime something changes.
/// \internal
function MyDataStructure.incrementVersion!() {
this.version++;
}
/// A getter for the internal version of the MyDataStructure
function Integer MyDataStructure.getVersion() {
return this.version;
}
/// An operator to test the data structures in this example
operator entry() {
MyDataStructure m('test');
report(m);
m.setName('another test');
report(m);
}
/*
** Output:
{x:+0.0,y:+0.0,z:+0.0,name:"test",version:1}
{x:+0.0,y:+0.0,z:+0.0,name:"another test",version:2}
*/
バージョン 1.13.0 のKLから継承が導入されました。これからはカプセル化ではなくコンポジションのために継承を使用しましょう。多重継承が必要な場面ではKLのインターフェイスを活用できます。
KL での Doxygen サポート¶
KL AST(抽象構文木, abstract syntax tree)埋め込みドキュメントの作成は以下のdoxygen記法に従います。頭を /// もしくは /** で始めます。標準的な doxygen 修飾子と、いくつかの特別な修飾子を付け加えます。
- brief : 簡単な説明
- param : 単一パラメータの説明
- category : メソッド, 関数のカテゴリ
- internal : この関数, メソッド, 型を internal としてマークします。Internal な要素はドキュメントに表示されません。
- versionadded : sphinx のversionadded ディレクティブを生成します。
- note : 以下のテキストから sphinx の適切な noteディレクティブを作成します。
- seealso : コンマ区切りされた値それぞれから sphinx の適切な see-also ディレクティブを作成します。
- example, endexample : KLの用例を含める2対の修飾子。ここにはオペレータのエントリーコードを含める必要はありません。また、エクステンションの require 文も自動的に追加されます。
- rst, endrst : 追加のカスタム rstコードを含む2対の修飾子。
require Math;
/// The maximum number of characters for a name.
/// The MyStruct type will obey this length for its name.
/** \example
String s;
if(s.length() > MAX_NAME_LENGTH)
setError("Invalid String Length");
report(MAX_NAME_LENGTH);
\endexample
*/
const Integer MAX_NAME_LENGTH = 256;
/**
Converts radian angles to degree angles.
\param rad The radian value to convert.
\example
report(PI);
report(radToDeg(PI));
\endexample
*/
function Scalar radToDeg(Scalar rad) {
return rad * 180.0 / PI;
}
/** An internal struct, it won't show up in the doc
\internal
*/
struct MyStructWorkData {
Integer numbers[];
};
/** \brief A custom data structure.
The MyStruct datastructure can be used to express a named structure. The name member stores the string data of that name.
*/
struct MyStruct : Vec3
{
/// The name of the struct
String name;
};
/// A constructor taking a preset value for the name.
/// \param name The initial name of the MyStruct
function MyStruct(String name)
{
/// The new value for the name.
this.name = name;
}
/// A comparison op, useful for checking strings
function Boolean == (MyStruct a, String b)
{
return a.name == b;
}
/// An assignment from string
function MyStruct.=(String other)
{
this.name = other;
}
/// A concentation op
function MyStruct + (MyStruct a, MyStruct b)
{
return MyStruct(a.name + '.' + b.name);
}
/// An interface ensuring the protocol required to get and set a MyStruct
interface MyInterface
{
/** \brief A getter for the MyStruct data
\category getter
*/
MyStruct getS();
/// The MyStruct setter
/// \category setter
/// \param s The new value for the MyStruct
/// \example
/// MyInterface i = MyObject();
/// i.setS(MyStruct("test"));
/// report(i);
/// \endexample
setS!(MyStruct s);
};
/// An object implementing the MyInterface interface
object MyObject : MyInterface
{
/// The current version of the MyObject
Integer version;
/**
The (private) MyStruct content.
\internal
*/
MyStruct s;
};
// The documentation of the method will be inherited from the interface
function MyStruct MyObject.getS()
{
return this.s;
}
// The documentation of the method will be inherited from the interface
function MyObject.setS!(MyStruct s)
{
this.s = s;
}
/// A specialized object of MyObject, which returns a MyStruct with the "dummy" content
object MySpecializedObject : MyObject
{
};
/** Overload of the getS method, which always returns "dummy" as the MyStruct's name.
\category getter
\rst
.. note::
This is just an example of how to overload a method.
\endrst
*/
function MyStruct MySpecializedObject.getS()
{
return MyStruct("dummy");
}