@node VObjectClass, VObjectSubclass, VSemaphore, Top
@comment  node-name,  next,  previous,  up
@chapter VObjectクラス

この章では，各種GUI部品を管理するクラスの基底クラスである，@code{VOject}クラスについて説明する。
@code{VObject}クラスはオブジェクトのツリー管理機能など，機種非依存な部分を管理している。
機種に依存する部分は，このクラスを継承するサブクラスで実装する。

このクラスの動作の概略は，別ドキュメント“@code{VObject}クラス群の概略”を参照。

@menu
* Etc::                         その他の機能                         
* ProtectedMethod::             VObjectクラス群のみで使用できるprotectedメソッド         
* Subclass::                    サブクラスでオーバーライドすべきメソッド         
@end menu

@node Etc, ProtectedMethod, VObjectClass, VObjectClass
@comment  node-name,  next,  previous,  up
@section その他の機能

別ドキュメント“概略”で説明しなかった，いくつかのVObjectの機能を説明する。

@deftypemethod VObject {virtual VObject*} get_child_by_id (unsigned id) const;
指定されたIDを持つ子オブジェクトを捜す。
 ※実装を変える可能性あり
@end deftypemethod

@deftypemethod VObject {const char *}  describe_self ()
オブジェクトのタイプとIDを記述した，"push 1000"のようなテキストを返す。
デバグ用。
@end deftypemethod

@node ProtectedMethod, Subclass, Etc, VObjectClass
@comment  node-name,  next,  previous,  up
@section VObjectクラス群のみで使用できるprotectedメソッド

いくつかのメソッドは，@code{VObject}のサブクラス内でのみ，各種機能の実装のために使用できる。

@deftypemethod VObject VError set_parent (VObject* parent)
自分の親を設定する。また，自分を親オブジェクトの子リストに追加させる。
@end deftypemethod

@deftypemethod VObject void detach ()
自分と親を切り離し（親の子リストから抹消し），また子オブジェクト全てのdestroyメソッドを呼び出す。
@end deftypemethod

@deftypemethod VObject VError accept_child (long type, VObject* obj = 0, VObjectList** last_item = 0) const
自分が指定された種類（type）のオブジェクトを子として追加できるかを返す。
objがNULL以外の場合，そのオブジェクト自体が追加可能かも検査できる。
追加できる場合はV_ER_NO_ERR，そうでなければ他のエラー値を返す。
last_itemがNULL以外だと，そこに子リストの最後のオブジェクトがセットされる。
@end deftypemethod

@deftypemethod VObject {static VError} check_parent (VObject* parent, long type)
指定された親オブジェクト（parent）に指定された種類（type）の子オブジェクトが追加可能かを問い合わせる。内部でparentのaccept_childメソッドを呼び出す。
@end deftypemethod

@deftypemethod VObject VError add_child (VObject* child, VInfo* info)
指定したオブジェクトを子として追加する。子のinfoを渡す必要がある。
@end deftypemethod

@deftypemethod VObject VError remove_child (VObject* child, VInfo* info)
指定したオブジェクトを子から除去する。子のinfoを渡す必要がある。
@end deftypemethod

@deftypemethod VObject {static VInfo*} get_info (VObject* obj)
指定したオブジェクトの機種依存データinfoを取得する。内部でobjのget_info_exメソッドを呼び出す。
@end deftypemethod

@node Subclass,  , ProtectedMethod, VObjectClass
@comment  node-name,  next,  previous,  up
@section サブクラスでオーバーライドすべきメソッド

サブクラスでは，以下のクラスメソッドを必要に応じてオーバーライドする必要がある。別ドキュメント“概略”も参照のこと。

@deftypemethod VObject {virtual unsigned} get_type ()
抽象クラス以外では必ずオーバーライドする。各サブクラスには

@example
enum @{ object_type = 'vobj' @};
@end example

のように，オブジェクトにタイプを表す定数を定義する必要がある。
（VPushButton::object_typeなどとすればサブクラスのタイプを取得できる。）
obj->get_type()を呼び出すと，このobjのタイプを返す。
@end deftypemethod

@deftypemethod VObject {virtual unsigned} max_children ()
子オブジェクトを持つことができるクラスではオーバーライドが必要。
そのクラスのオブジェクトが持てる子オブジェクトの数を返す。特に制限がないときはMAX_CHILDREN_NO_LIMITを返すようにする。
（オーバーライドしなければ0が返る。）
@end deftypemethod

@deftypemethod VObject {virtual VError} get_status (VObjectStatus *s, int flags) const;
そのオブジェクトのステータスを取得する。取得したいステータスをflagsに渡すと，sに該当するものが書き込まれる。
取得したステータスは，使用後，free_vobject_status関数で内容を解放すること。
@end deftypemethod

@deftypemethod VObject {virtual VError} set_status (const VObjectStatus *, int flags);
そのオブジェクトのステータスを設定する。設定したいステータスをflagsに渡すとともに，sに該当するものを格納しておく。
@end deftypemethod

@deftypemethod VObjectSubClass {static VObjectSubClass*} create (const VObjectStatus *, int flags, int *err = 0)
サブクラスのオブジェクトを作成する。抽象クラス以外では必ず宣言・定義が必要。
通常はcreate_tmp<VObjectSubClass>を呼べばよい。

上記の引数の取り方は一般的な例であり、必ずしもこのとおりに従わなくてもよい。サブクラスによって，必要に応じてこの例よりも多くの引数を用意する。
その場合、大抵はcreate_doのargに，渡されたデータを構造体にしたものを渡すことになるだろう。
@end deftypemethod

@deftypemethod VObject {Virtual void} create_do (const VObjectStatus *, int flags, void* arg)
protectedな純粋仮想関数。抽象クラス以外では必ずオーバーライドが必要。
VObjectStatusとflagsに渡されたデータをもとに，OS / ツールキットのGUI部品を生成し，そのポインタをprotectedなメンバ変数infoにセットする。
argは、任意のポインタで、サブクラスによって意味が異なる。
@end deftypemethod

@deftypemethod VObject {virtual void} destroy_do ()
protectedな純粋仮想関数。抽象クラス以外では必ずオーバーライドが必要。
OS / ツールキットのGUI部品を削除する。
@end deftypemethod

@deftypemethod VObjectb {virtual VError} accept_child_ex (long type, VObject* obj) const
protectedメソッド。check_parent -> accept_childから呼ばれる。
typeに指定された種類のオブジェクトが自分の子オブジェクトになれるかを返す。
objがNULLでない場合は，必要であればそれも検査する。
追加できる場合はV_ER_NO_ERRを返し，できない場合はそれ以外のエラー値を返す。
オーバーライドしなければ常にV_ER_NO_ERRを返す。
@end deftypemethod

@deftypemethod VObject {virtual void} add_child_do (VObject* child, VInfo* info)
protectedメソッド。add_childから呼ばれる。子を持てるサブクラスでは必ずオーバーライドする。
自分の管理するGUI部品に指定された子オブジェクトを追加する。
子オブジェクトのinfoも渡される。
@end deftypemethod

@deftypemethod VObject {virtual void} remove_child_do (VObject* child, VInfo* info)
protectedメソッド。remove_childから呼ばれる。子を持てるサブクラスでは必ずオーバーライドする。
自分の管理するGUI部品から指定された子オブジェクトを除去する。
子オブジェクトのinfoも渡される。
@end deftypemethod

@deftypemethod VObject {virtual VInfo*} get_info_ex () const
protectedメソッド。get_infoから呼ばれる。
get_infoは基本的にオブジェクトのinfoを返すが，特殊な値を返したい場合はこれをオーバーライドする。
@end deftypemethod

@deftypemethod VObject {virtual void} value_changed ()
ユーザ操作でvalueが変化したときにOS / ツールキットから呼び出される。
(*sts.value_event_handler)(this)を実行する（ステータスに指定されているときのみ）。
@end deftypemethod

@deftypemethod VObject {virtual void} descriptor_changed ()
ユーザ操作でvalueが変化したときにOS / ツールキットから呼び出される。
(*sts.descriptor_event_handler)(this)を実行する（ステータスに指定されているときのみ）。
@end deftypemethod

@deftypemethod VObject {virtual void} child_status_changed (VObject *child, VInfo *info)
子オブジェクトのset_statusなどから，親に影響のあるステータス変更が行われたことを通知するために呼び出される。主にレイアウトの変更などを想定しているが，どのステータスの変更を通知するかは機種依存。オーバーライドしなければ何もしない。
@end deftypemethod


@example
※get_info, check_parentについて
これらのメソッドは，基底クラスVObjectのメソッドを内部で呼び出すことにより，他のVObjectのサブクラスのprotectedメンバ関数を呼び出せるようにしている。
@end example


@c 例；
@c ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
@c   オブジェクトＡ　　　　｜　　　　　オブジェクトＢ
@c ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
@c VObject::get_info ------｜---> （virtual VObject::get_info_ex）
@c  　　　↑　　　　　　　｜　　　　　　　　　↓
@c VPushButton::create_do　｜　　　virtual VWindow::get_info_ex
@c ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

@tex
$$\vbox{\offinterlineskip
        \halign{\strut
        \vrule\vrule\quad\gt#\hfill\quad &  \vrule\quad\gt#\hfill\quad\vrule\vrule\cr
        \noalign{\hrule\hrule}
        オブジェクトA & オブジェクトB\cr
        \noalign{\hrule} 
        VObject：：get＿info --------→&--→ （virtual VObject：：get＿info＿ex） \cr
        ↑  &    ↓ \cr 
        VPushButton：：create＿do &  virtual VWindow：：get＿info＿ex \cr
        \noalign{\hrule\hrule} 
        }}$$

@end tex


@html
<table border>
<tr><td>オブジェクトA</td><td>オブジェクトB</td></tr>
<tr><td>VObject::get_info --------<br>　　　↑<br>VPushButton::create_do</td><td>------> (virtual VObject::get_info_ex)<br>　　　↓<br>virtual VWindow::get_info_ex</td></tr>
</table>

@end html

