.. index:: 
	single: コード生成器; はじめに

==================================
C/C++ ライブラリ接続用コード生成器
==================================

コード生成器による Ring アプリケーションへの C/C++ ライブラリ接続方法です。

.. index:: 
	pair: コード生成器; ツールの用法

ツールの用法
============

コード生成プログラムは parsec.ring であり、
Ring で別の Ring コードを実行できます

URL : https://github.com/ring-lang/ring/tree/master/extensions/codegen

例えば、設定ファイル test.cf を読み込んでソースコードファイル test.c を生成するには、 parsec.ring を実行します。

.. code-block:: ring

	ring parsec.ring test.cf test.c

.. index:: 
	pair: コード生成器; 設定ファイル


設定ファイル
============

設定ファイル (\*.cf) は、コード生成器への入力ファイルです。
このファイルは C/C++ ライブラリから呼び出す関数プロトタイプを決定します。

設定ファイルの記述方法は次の規則に従います。

.. index:: 
	pair: コード生成器; 関数プロトタイプの用法

関数プロトタイプの用法
======================

* C 関数の接続用コードを生成するには、 C 関数プロトタイプを記述します。

用例:

.. code-block:: ring

	ALLEGRO_DISPLAY *al_create_display(int w, int h)
	void al_destroy_display(ALLEGRO_DISPLAY *display)
	int al_get_new_display_flags(void)
	void al_set_new_display_flags(int flags)
	int al_get_new_display_option(int option, int *importance)

前述の用例では al_create_display(), al_destroy_display(), al_get_new_display_flags(),
al_set_new_diplay_flas() および al_get_new_display_option()
関数の接続に五種の関数生成をコード生成器に指示します。

生成コードの一例は、

用例:

.. code-block:: ring

	RING_FUNC(ring_al_create_display)
	{
		if ( RING_API_PARACOUNT != 2 ) {
			RING_API_ERROR(RING_API_MISS2PARA);
			return ;
		}
		if ( ! RING_API_ISNUMBER(1) ) {
			RING_API_ERROR(RING_API_BADPARATYPE);
			return ;
		}
		if ( ! RING_API_ISNUMBER(2) ) {
			RING_API_ERROR(RING_API_BADPARATYPE);
			return ;
		}
		RING_API_RETCPOINTER(al_create_display( (int ) RING_API_GETNUMBER(1),
					 (int ) RING_API_GETNUMBER(2)),"ALLEGRO_DISPLAY");
	}


	RING_FUNC(ring_al_destroy_display)
	{
	  if ( RING_API_PARACOUNT != 1 ) {
		RING_API_ERROR(RING_API_MISS1PARA);
		return ;
	  }
	  if ( ! RING_API_ISPOINTER(1) ) {
		RING_API_ERROR(RING_API_BADPARATYPE);
		return ;
	  }
	  al_destroy_display((ALLEGRO_DISPLAY *) RING_API_GETCPOINTER(1,"ALLEGRO_DISPLAY"));
	}


	RING_FUNC(ring_al_get_new_display_flags)
	{
		if ( RING_API_PARACOUNT != 0 ) {
			RING_API_ERROR(RING_API_BADPARACOUNT);
			return ;
		}
		RING_API_RETNUMBER(al_get_new_display_flags());
	}


	RING_FUNC(ring_al_set_new_display_flags)
	{
		if ( RING_API_PARACOUNT != 1 ) {
			RING_API_ERROR(RING_API_MISS1PARA);
			return ;
		}
		if ( ! RING_API_ISNUMBER(1) ) {
			RING_API_ERROR(RING_API_BADPARATYPE);
			return ;
		}
		al_set_new_display_flags( (int ) RING_API_GETNUMBER(1));
	}


	RING_FUNC(ring_al_get_new_display_option)
	{
		if ( RING_API_PARACOUNT != 2 ) {
			RING_API_ERROR(RING_API_MISS2PARA);
			return ;
		}
		if ( ! RING_API_ISNUMBER(1) ) {
			RING_API_ERROR(RING_API_BADPARATYPE);
			return ;
		}
		if ( ! RING_API_ISSTRING(2) ) {
			RING_API_ERROR(RING_API_BADPARATYPE);
			return ;
		}
		RING_API_RETNUMBER(al_get_new_display_option( (int ) RING_API_GETNUMBER(1),
					RING_API_GETINTPOINTER(2)));
		RING_API_ACCEPTINTVALUE(2) ;
	}

前述の用例から、コード生成器は時間と手間の節約になることがわかります。

.. index:: 
	pair: コード生成器; コードの追加

コードの追加
============

* C コードを挿入するには <code> ～ </code> に追記します。

用例 :

.. code-block:: ring

	<code>
		/* こちらへ C コードを書いてください。 */
	</code>

この機能はコード生成器で処理を行わないコードの記述時に使用します。
例えば、ヘッダファイルやマクロによる定数の定義などです。

.. index:: 
	pair: コード生成器; 関数名の接頭辞

関数名の接頭辞
==============

* 全ての関数に付ける接頭辞を決定するには <funcstart> ～ </funcstart> に指定したい接頭辞を記述してください。
	例えば、 Allegro ゲームプログラミング・ライブラリを接続した後に全てのライブラリ関数名が
	“al” で始まるようにするためには、このコードを設定ファイルへ記述します。

.. code-block:: ring

	<funcstart>
	al
	</funcstart>

.. index:: 
	pair: コード生成器; 構造体を接続する関数の生成

構造体を接続する関数の生成
==========================

* 構造体の接続用関数を生成するには (構造体メンバの作成、削除、取得)
	<struct> ～ </struct> に指定したい構造体名を記述してください。
	なお、構造体名を記述してから { ～ } に構造体メンバをコンマで区切って記述します。

用例:

.. code-block:: ring

	<struct>
	ALLEGRO_COLOR
	ALLEGRO_EVENT { type , keyboard.keycode , mouse.x , mouse.y }
	</struct>

前述の用例では ALLEGRO_COLOR 構造体の作成と削除を行う関数を生成します。
また ALLEGRO_EVENT 構造体の作成と削除を行う関数、および
ALLEGRO_EVENT のメンバ (type, keyboard.keycode, mouse.x, mouse.y) を受け取る関数を生成します。

.. index:: 
	pair: コード生成器; 構造体メンバ型の決定

構造体メンバ型の決定
====================

構造体メンバ名の先頭にポインタの名前を決定できます。

用例:

.. code-block:: none

	SDL_Surface {flags,SDL_PixelFormat *format,w,h,pitch,void *pixels}

.. index:: 
	pair: コード生成器; 定数の定義

定数の定義
==========

<constant> ～ </constant> で定数を定義します。

生成器は定数の値を取得するのに必要な関数を生成します。

また、 Ring ヘッダファイル (\*.rh) から同一ファイル名の Ring コードで用いる定数の定義も生成します。

用例:

.. code-block:: ring

	<constant>
	MIX_DEFAULT_FORMAT
	SDL_QUIT
	SDL_BUTTON_LEFT
	SDL_BUTTON_MIDDLE
	SDL_BUTTON_RIGHT
	</constant>

.. note:: 生成されたソースファイルの後には必ず parsec.ring へ \*.rh ファイル名を渡してください。

用例:

.. code-block:: ring

	ring ..\codegen\parsec.ring libsdl.cf ring_libsdl.c ring_libsdl.rh

.. index:: 
	pair: コード生成器; 新しい関数の登録

新しい関数の登録
================

<register> ～ </register> に関数プロトタイプを記述することで、関数を登録できます。
このような関数のコードは、関数プロトタイプを記述しない場合に限り必要です。

用例:

.. code-block:: ring

	<register>
	void al_exit(void)
	</register>

	<code>
	RING_FUNC(ring_al_exit)
	{
		if ( RING_API_PARACOUNT != 0 ) {
			RING_API_ERROR(RING_API_BADPARACOUNT);
			return ;
	}
	exit(0);
	}
	</code>

前述の用例では al_exit() 関数を登録しました。この関数は Allegro ライブラリの一部ではありませんが、必要なので追加した関数です。この関数が <code> ～ </code> にある場合はコードとして扱われます。この関数は C 言語ライブラリから exit() 関数を呼び出します。

.. index:: 
	pair: コード生成器; 設定ファイルにコメントを書くには

設定ファイルにコメントを書くには
================================

* コメントは <comment> ～ </comment> に記述します。

用例:

.. code-block:: ring

	<comment>
	設定ファイル
	</comment>

.. index:: 
	pair: コード生成器; コードの生成時にコード実行するには

コードの生成時にコード実行するには
==================================

* コード生成器で設定ファイルを読み込むときに Ring コードの実行を要求するには
	<runcode> ～ </runcode> にコードを書きます。

用例:

.. code-block:: ring

	<runcode>
	aNumberTypes + "al_fixed"
	</runcode>

前述の行は文字列“al_fixed”をリスト NumberTypes へ追加するためのコードです。
このリストには、関数プロトタイプにおいてコード生成器が検出したときに数値としてみなせる型があります。

.. index:: 
	pair: コード生成器; 列挙型と数値

列挙型と数値
============

関数プロトタイプで使用する列挙型の追加用に aEnumTypes リストがあります。

用例:

.. code-block:: ring

	<runcode>
	aNumberTypes + "qreal"
	aNumberTypes + "qint64"
	aEnumTypes + "Qt::GestureType"
	aEnumTypes + "Qt::GestureFlag"
	</runcode>


.. index:: 
	pair: コード生成器; 条件式による篩い分け

条件式による篩い分け
====================

<filter> ～ </filter> は、
条件に基づいて設定ファイルの一部を包含または除外します。例えば、

.. code-block:: ring

		<filter> iswindows() 
			... functions related to windows
		</filter>

.. index:: 
	pair: コード生成器; 定数型

定数型
======

デフォルトの定数型は数値です。
しかし、定数は別の型でも良いです。例えば、 (ポインタ : void \*)

<constant> ～ </constant> の使用前に <runcode> ～ </runcode> を記述することで、
コード生成器で使われる二種類のグローバル変数を用いて定数の型を決定します。

最初の変数は $nDefaultConstantType であり、この定数を指定できます。

* C_CONSTANT_TYPE_NUMBER
* C_CONSTANT_TYPE_STRING
* C_CONSTANT_TYPE_POINTER

C_CONSTANT_TYPE_POINTER の使用時は、
$cDefaultConstantPointerType の二つ目にあるグローバル変数のポインタ型の決定が必要です。

用例 :

この用例では、この機能を FreeGLUT ライブラリーにおける定数の定義で使用しています。

.. code-block:: ring

	<runcode>
	$nDefaultConstantType = C_CONSTANT_TYPE_POINTER	
	$cDefaultConstantPointerType = "void"
	</runcode>
	<constant>
		GLUT_STROKE_ROMAN  
		GLUT_STROKE_MONO_ROMAN
		GLUT_BITMAP_9_BY_15   
		GLUT_BITMAP_8_BY_13   
		GLUT_BITMAP_TIMES_ROMAN_10
		GLUT_BITMAP_TIMES_ROMAN_24 
		GLUT_BITMAP_HELVETICA_10   
		GLUT_BITMAP_HELVETICA_12   
		GLUT_BITMAP_HELVETICA_18   
	</constant>

.. index:: 
	pair: コード生成器; Allegro ライブラリ用の設定ファイル

Allegro ライブラリ用の設定ファイル
==================================

この設定ファイル (1000行以下) は Allegro ライブラリの関数用です。
このファイルをコード生成器で処理したときに生成される C 言語コードは約 12000 行です！

この設定ファイルはコード生成器の完全な用例として参照できます。
また 2D ゲームの作成で実装済みの
RingAllegro 関数の確認にも使えます！

.. code-block:: ring

	<code>
	#define ALLEGRO_NO_MAGIC_MAIN

	#include <allegro5/allegro.h>
	#include "allegro5/allegro_image.h"
	#include <allegro5/allegro_font.h>
	#include <allegro5/allegro_ttf.h>
	#include <allegro5/allegro_audio.h>
	#include <allegro5/allegro_acodec.h>
	#include <allegro5/allegro_opengl.h>
	#include <allegro5/allegro_direct3d.h>
	#include <allegro5/allegro_color.h>
	#include <allegro5/allegro_memfile.h>
	#include "allegro5/allegro_native_dialog.h"
	#include <allegro5/allegro_physfs.h>
	#include <allegro5/allegro_primitives.h>
	</code>

	<funcstart>
	al
	</funcstart>

	<struct>
	ALLEGRO_EVENT { type , keyboard.keycode , mouse.x , mouse.y }
	ALLEGRO_TIMEOUT
	ALLEGRO_SAMPLE_ID
	ALLEGRO_COLOR
	</struct>

	<register>
	void al_exit(void)
	</register>

	<code>
	RING_FUNC(ring_al_exit)
	{
		if ( RING_API_PARACOUNT != 0 ) {
			RING_API_ERROR(RING_API_BADPARACOUNT);
			return ;
		}
		exit(0);
	}
	</code>

	int al_init(void)

	<comment>
	configuration files
	</comment>

	<runcode>
	aNumberTypes + "al_fixed"
	</runcode>

	ALLEGRO_CONFIG *al_create_config(void)
	void al_destroy_config(ALLEGRO_CONFIG *config)
	ALLEGRO_CONFIG *al_load_config_file(const char *filename)
	ALLEGRO_CONFIG *al_load_config_file_f(ALLEGRO_FILE *file)
	bool al_save_config_file(const char *filename, const ALLEGRO_CONFIG *config)
	bool al_save_config_file_f(ALLEGRO_FILE *file, const ALLEGRO_CONFIG *config)
	void al_add_config_section(ALLEGRO_CONFIG *config, const char *name)

.. note:: 
	これは設定ファイルの引用です。
	完全なコピーは Ring ソースコードの配布物を参照してください。

.. index:: 
	pair: コード生成器; スレッドへの対応

スレッドへの対応
================

この設定ファイルの別の部分は、スレッドライブラリで Ring アプリケーションへスレッドを
追加する方法について学ぶことができるため重要です。

考えかたとして Ring コードを実行するために ring_vm_mutexfunctions() および ring_vm_runcodefromthread() を使用します。

.. code-block:: ring

	<comment>
	Threads
	</comment>

	<code>
	void *al_func_thread(ALLEGRO_THREAD *thread, void *pPointer) 
	{  
		List *pList;
		VM *pVM;
		const char *cStr;
		pList = (List *) pPointer ;
		pVM = (VM *) ring_list_getpointer(pList,2);
		cStr = ring_list_getstring(pList,1);
		ring_vm_runcodefromthread(pVM,cStr);	
		ring_list_delete(pList);
		return NULL;
	}

	RING_FUNC(ring_al_create_thread)
	{
		ALLEGRO_THREAD *pThread;
		List *pList;
		if ( RING_API_PARACOUNT != 1 ) {
			RING_API_ERROR(RING_API_MISS1PARA);
			return ;
		}
		if ( ! RING_API_ISSTRING(1) ) {
			RING_API_ERROR(RING_API_BADPARATYPE);
			return ;
		}	
		pList = ring_list_new(0);
		ring_list_addstring(pList,RING_API_GETSTRING(1));
		ring_list_addpointer(pList,pPointer);
		ring_vm_mutexfunctions((VM *) pPointer,al_create_mutex,
			al_lock_mutex,al_unlock_mutex,al_destroy_mutex);
		pThread = al_create_thread(al_func_thread, pList);
		al_start_thread(pThread);
		RING_API_RETCPOINTER(pThread,"ALLEGRO_THREAD");	
	}

	RING_FUNC(ring_al_run_detached_thread)
	{
		List *pList;
		if ( RING_API_PARACOUNT != 1 ) {
			RING_API_ERROR(RING_API_MISS1PARA);
			return ;
		}
		if ( ! RING_API_ISSTRING(1) ) {
			RING_API_ERROR(RING_API_BADPARATYPE);
			return ;
		}	
		pList = ring_list_new(0);
		ring_list_addstring(pList,RING_API_GETSTRING(1));
		ring_list_addpointer(pList,pPointer);
		ring_vm_mutexfunctions((VM *) pPointer,al_create_mutex,
			al_lock_mutex,al_unlock_mutex,al_destroy_mutex);
		al_run_detached_thread(al_func_thread, pList);
	}
	</code>

	<register>
	ALLEGRO_THREAD *al_create_thread(void)
	void al_run_detached_thread(void)
	</register>

	void al_start_thread(ALLEGRO_THREAD *thread)
	void al_join_thread(ALLEGRO_THREAD *thread, void **ret_value)
	void al_set_thread_should_stop(ALLEGRO_THREAD *thread)
	bool al_get_thread_should_stop(ALLEGRO_THREAD *thread)
	void al_destroy_thread(ALLEGRO_THREAD *thread)
	ALLEGRO_MUTEX *al_create_mutex(void)
	ALLEGRO_MUTEX *al_create_mutex_recursive(void)
	void al_lock_mutex(ALLEGRO_MUTEX *mutex)
	void al_unlock_mutex(ALLEGRO_MUTEX *mutex)
	void al_destroy_mutex(ALLEGRO_MUTEX *mutex)
	ALLEGRO_COND *al_create_cond(void)
	void al_destroy_cond(ALLEGRO_COND *cond)
	void al_wait_cond(ALLEGRO_COND *cond, ALLEGRO_MUTEX *mutex)

.. index:: 
	pair: コード生成器; C++ クラスの接続に関するコード生成器の規則

C++ クラスの接続に関するコード生成器の規則
==========================================

* <class> ～ </class> にクラスを定義します。
* <class> ～ </class> に“name, nonew, para, parent, codename,
  passvmpointer, abstract および staticmethods”などの属性を設定できます。
* 値が不要な場合に限り、属性名:値 (attributename:value)、
  または属性名 (attributename) による記法で属性を設定します。
* “name” 属性は C++ コードのクラス名を決定します。
  また、この名前は Ring コードにおけるデフォルトの名前になります。
* nonew 命令はメソッドの新規作成または削除は不要であることを意味します。
* parent 属性は親クラス名を決定します。
* codename 属性は C++ コードで別のクラス名を決定します。
* passvmpointer 命令は新しいオブジェクトの作成時にクラスのコンストラクタへ
  Ring 仮想計算機のポインタを渡すことを意味します。これは codename 属性をクラス定義として設定するときに発生するため、
  このクラスでは仮想計算機のポインタが必要です
  (例えば C++ から Ring コードの実行のために使用)。
* abstract 命令は、このクラスでは“オブジェクトが作成されない”ため、新しいメソッドは不要であることを意味します。
* staticmethods 命令はメソッドを呼び出すためのオブジェ	クトを用意する必要はないことを意味します。
* <nodllstartup> により #include "ring.h" を回避できます。これはスタートアップコードを記述するために必要です。
* <libinitfunc> によりライブラリ関数へ登録する関数名を変更できます。
* <ignorecpointertype> はポインタ型の検査を無視します。
* aStringTypes リストは const char \* として扱われる新しい型を定義します。
* aBeforeReturn リストは関数から変数を返すときに変数名末尾に挿入される
  コードを定義できます。
* aNewMethodName リストは C++ のメソッドを呼び出すときに Ring のコードで使用されるメソッドの別名を定義できます。
  この機能は、 C++ メソッドで “load”, ”next”, ”end” および “done” など
  Ring のキーワードと同一名称であるため必要となるものです。
* メソッドのプロトタイプでは - メソッド名に @ を使うときは、
  同じメソッドで様々な仮引数 (C++ のように) があることを意味します。

.. index:: 
	pair: コード生成器; C++ ライブラリ接続用設定ファイルの用法

C++ ライブラリ接続用設定ファイルの用法
======================================

Ring アプリケーションから C++ ライブラリを使うにはコード生成器でコードを生成します。
C ライブラリで使うと、 \*.c ファイルではなく \*.cpp ファイルを生成します。
また、生成ファイルも決定します (\*.ring)。
このファイルには C++ のクラスとオブジェクトを使用する C++ 関数と接続するための Ring コードによるクラスがあります。

.. code-block:: ring

	ring parsec.ring generator\qt.cf ring_qt.cpp ring_qt.ring


.. index:: 
	pair: コード生成器; Qt フレームワーク用の設定ファイル

Qt フレームワーク用の設定ファイル
=================================

これは Qt クラスとの接続に用いる設定ファイルです。
設定ファイルは約 3500 行であり、生成されるコードは約 56000 行の C++ コード、
および約 9000 行の Ring コードとなります。

.. code-block:: ring

	<nodllstartup>

	<libinitfunc> ring_qt_start

	<ignorecpointertype>

	<code>

	extern "C" {
		#include "ring.h"
	}

	#include "ring_qt.h"
	#include "gpushbutton.h"
	#include "gaction.h"
	#include "glineedit.h"
	#include "gtextedit.h"
	#include "glistwidget.h"
	#include "gtreeview.h"
	#include "gtreewidget.h"
	#include "gcombobox.h"
	#include "gtabwidget.h"
	#include "gtablewidget.h"
	#include "gprogressbar.h"
	#include "gspinbox.h"
	#include "gslider.h"
	#include "gdial.h"
	#include "gwebview.h"
	#include "gcheckbox.h"
	#include "gradiobutton.h"
	#include "gbuttongroup.h"
	#include "gvideowidget.h"
	#include "gtimer.h"
	#include "gtcpserver.h"
	#include "giodevice.h"
	#include "gabstractsocket.h"
	#include "gtcpsocket.h"
	#include "gcolordialog.h"
	#include "gallevents.h"
	#include <QApplication>
	#include <QObject>
	#include <QWidget>
	#include <QLabel>
	#include <QPixmap>
	#include <QIcon>
	#include <QSize>
	#include <QPushButton>
	#include <QMainWindow>
	#include <QVBoxLayout>
	#include <QHBoxLayout>
	#include <QLineEdit>
	#include <QTextEdit>
	#include <QListWidget>
	#include <QTreeView>
	#include <QDir>
	#include <QFileSystemModel>
	#include <QTreeWidget>
	#include <QTreeWidgetItem>
	#include <QComboBox>
	#include <QVariant>
	#include <QMenuBar>
	#include <QMenu>
	#include <QToolBar>
	#include <QMainWindow>
	#include <QStatusBar>
	#include <QDockWidget>
	#include <QTabWidget>
	#include <QTableWidget>
	#include <QTableWidgetItem>
	#include <QSizePolicy>
	#include <QFrame>
	#include <QAbstractScrollArea>
	#include <QAbstractItemView>
	#include <QProgressBar>
	#include <QSpinBox>
	#include <QSlider>
	#include <QAbstractSlider>
	#include <QDateEdit>
	#include <QDateTimeEdit>
	#include <QAbstractSpinBox>
	#include <QDial>
	#include <QWebView>
	#include <QUrl>
	#include <QCheckBox>
	#include <QRadioButton>
	#include <QButtonGroup>
	#include <QMediaPlayer>
	#include <QMediaPlaylist>
	#include <QVideoWidget>
	#include <QPrinter>
	#include <QAction>
	#include <QEvent>
	#include <QMessageBox>
	#include <QTimer>
	#include <QFileDialog>
	#include <QPainter>
	#include <QPicture>
	#include <QPen>
	#include <QColor>
	#include <QPrinter>
	#include <QFont>
	#include <QWebSettings>
	#include <QBrush>
	#include <QByteArray>
	#include <QIODevice>
	#include <QAbstractSocket>
	#include <QTcpSocket>
	#include <QTcpServer>
	#include <QNetworkProxy>
	#include <QHostAddress>
	#include <QHostInfo>
	#include <QList>
	#include <QFileInfo>
	#include <QDirModel>
	#include <QModelIndex>
	#include <QFontDialog>
	#include <QDialog>
	#include <QTextCursor>
	#include <QTextBlock>
	#include <QTextDocumentFragment>
	#include <QColorDialog>
	#include <QHeaderView>
	#include <QStringList>
	#include <QKeySequence>
	#include <QLCDNumber>
	#include <QInputDialog>
	#include <QDesktopWidget>
	#include <QRect>
	#include <QTextDocument>

	extern "C" {

		#define RING_DLL __declspec(dllexport)

		RING_DLL void ringlib_init(RingState *pRingState)
		{

			new QApplication(pRingState->argc,pRingState->argv);
			ring_qt_start(pRingState) ;
		}

	}
	</code>


	<runcode>
	aStringTypes + "QString"
	aBeforeReturn + ["QString",".toStdString().c_str()"]
	aNewMethodName + ["QWebView","load","loadpage"]
	aNewMethodName + ["QMediaPlaylist","load","loadfile"]
	aNewMethodName + ["QMediaPlaylist","next","movenext"]
	aNewMethodName + ["QPainter","end","endpaint"]
	aNewMethodName + ["QPicture","load","loadfile"]
	aNewMethodName + ["QLineEdit","end","endtext"]
	aNewMethodName + ["QDialog","done","donedialog"]
	aNewMethodName + ["QTextDocument","end","enddoc"]
	aNewMethodName + ["QTextBlock","next","nextblock"]
	</runcode>

	<class>
	name: qApp
	nonew
	</class>

	<register>
	void exec(void)
	void quit(void)
	void processEvents(void)
	</register>

	<code>

	RING_FUNC(ring_qApp_quit)
	{
		qApp->quit();
	}

	RING_FUNC(ring_qApp_exec)
	{
		qApp->exec();
	}

	RING_FUNC(ring_qApp_processEvents)
	{
		qApp->processEvents();
	}

	</code>

	<class>
	name: QObject
	para: void
	</class>

	bool blockSignals(bool block)
	QObjectList children(void)
	void dumpObjectInfo(void)
	void dumpObjectTree(void)
	bool inherits(const char *className)
	void installEventFilter(QObject *filterObj)
	bool isWidgetType(void)
	void killTimer(int id)
	void moveToThread(QThread *targetThread)
	QString objectName(void)
	QObject *parent(void)
	QVariant property(const char *name)
	void removeEventFilter(QObject *obj)
	void setObjectName(QString)
	void setParent(QObject *parent)
	bool setProperty(const char *name, QVariant)
	bool signalsBlocked(void)
	int startTimer(int interval)
	QThread *thread(void)
	void deleteLater(void)

	<class>
	name: QWidget
	para: void
	parent: QObject
	</class>

	bool acceptDrops(void)
	QString accessibleDescription(void)
	QString accessibleName(void)
	void activateWindow(void)
	void addAction(QAction *action)
	void adjustSize(void)
	bool autoFillBackground(void)
	int backgroundRole(void)
	QSize baseSize(void)
	QWidget *childAt(int x, int y)
	QRect childrenRect(void)
	QRegion childrenRegion(void)
	void clearFocus(void)
	void clearMask(void)
	QMargins contentsMargins(void)
	QRect contentsRect(void)
	int contextMenuPolicy(void)
	QCursor cursor(void)
	int effectiveWinId(void)
	void ensurePolished(void)
	int focusPolicy(void)
	QWidget *focusProxy(void)
	QWidget *focusWidget(void)
	QFont font(void)
	QFontInfo fontInfo(void)
	QFontMetrics fontMetrics(void)
	int foregroundRole(void)
	QRect frameGeometry(void)
	QSize frameSize(void)
	QRect geometry(void)
	void getContentsMargins(int *left, int *top, int *right, int *bottom)
	void grabGesture(int gesture, int flags)
	void grabKeyboard(void)
	void grabMouse(void)
	int grabShortcut(QKeySequence , int context)
	QGraphicsEffect *graphicsEffect(void)
	QGraphicsProxyWidget *graphicsProxyWidget(void)
	bool hasFocus(void)
	bool hasMouseTracking(void)
	int height(void)
	int heightForWidth(int w)
	int inputMethodHints(void)
	QVariant inputMethodQuery(int query)
	void insertAction(QAction *before, QAction *action)
	bool isActiveWindow(void)
	bool isAncestorOf(QWidget *child)
	bool isEnabled(void)
	bool isEnabledTo(QWidget *ancestor)
	bool isFullScreen(void)
	bool isHidden(void)
	bool isMaximized(void)
	bool isMinimized(void)
	bool isModal(void)
	bool isVisible(void)
	bool isVisibleTo(QWidget *ancestor)
	bool isWindow(void)
	bool isWindowModified(void)
	QLayout *layout(void)
	int layoutDirection(void)
	QLocale locale(void)
	QPoint mapFrom(QWidget *parent, QPoint)
	QPoint mapFromGlobal(QPoint)
	QPoint mapFromParent(QPoint)
	QPoint mapTo(QWidget *parent, QPoint)
	QPoint mapToGlobal(QPoint pos)
	QPoint mapToParent(QPoint pos)
	QRegion mask(void)
	int maximumHeight(void)
	QSize maximumSize(void)
	int maximumWidth(void)
	int minimumHeight(void)
	QSize minimumSize(void)
	int minimumWidth(void)
	void move(int x, int y)
	QWidget *nativeParentWidget(void)
	QWidget *nextInFocusChain(void)
	QRect normalGeometry(void)
	void overrideWindowFlags(int flags)
	QPalette palette(void)
	QWidget *parentWidget(void)
	QPoint pos(void)
	QWidget *previousInFocusChain(void)
	QRect rect(void)
	void releaseKeyboard(void)
	void releaseMouse(void)
	void releaseShortcut(int id)
	void removeAction(QAction *action)
	void render(QPaintDevice *target, QPoint,QRegion, int)
	void repaint(int x, int y, int w, int h)
	void resize(int w, int h)
	bool restoreGeometry(QByteArray)
	QByteArray saveGeometry(void)
	void scroll(int dx, int dy)
	void setAcceptDrops(bool on)
	void setAccessibleDescription(QString)
	void setAccessibleName(QString)
	void setAttribute(int attribute, bool on)
	void setAutoFillBackground(bool enabled)
	void setBackgroundRole(int role)
	void setBaseSize(int basew, int baseh)
	void setContentsMargins(int left, int top, int right, int bottom)
	void setContextMenuPolicy(int policy)
	void setCursor(QCursor)
	void setFixedHeight(int h)
	void setFixedSize(int w, int h)
	void setFixedWidth(int w)
	void setFocus(int reason)
	void setFocusPolicy(int policy)
	void setFocusProxy(QWidget *w)
	void setFont(QFont)
	void setForegroundRole(int role)
	void setGeometry(int x, int y, int w, int h)
	void setGraphicsEffect(QGraphicsEffect *effect)
	void setInputMethodHints(int hints)
	void setLayout(QLayout *layout)
	void setLayoutDirection(int direction)
	void setLocale(QLocale)
	void setMask(QBitmap)
	void setMaximumHeight(int maxh)
	void setMaximumSize(int maxw, int maxh)
	void setMaximumWidth(int maxw)
	void setMinimumHeight(int minh)
	void setMinimumSize(int minw, int minh)
	void setMinimumWidth(int minw)
	void setMouseTracking(bool enable)
	void setPalette(QPalette)
	void setParent(QWidget *parent)
	void setShortcutAutoRepeat(int id, bool enable)
	void setShortcutEnabled(int id, bool enable)
	void setSizeIncrement(int w, int h)
	void setSizePolicy(int horizontal, int vertical)
	void setStatusTip(QString)
	void setStyle(QStyle *style)
	void setToolTip(QString)
	void setUpdatesEnabled(bool enable)
	void setWhatsThis(QString)
	void setWindowFilePath(QString)
	void setWindowFlags(int type)
	void setWindowIcon(QIcon)
	void setWindowIconText(QString)
	void setWindowModality(int windowModality)
	void setWindowOpacity(double level)
	void setWindowRole(QString)
	void setWindowState(int windowState)
	QSize size(void)
	QSize sizeIncrement(void)
	QSizePolicy sizePolicy(void)
	void stackUnder(QWidget *w)
	QString statusTip(void)
	QStyle *style(void)
	QString styleSheet(void)
	bool testAttribute(int attribute)
	QString toolTip(void)
	bool underMouse(void)
	void ungrabGesture(int gesture)
	void unsetCursor(void)
	void unsetLayoutDirection(void)
	void unsetLocale(void)
	void update(int x, int y, int w, int h)
	void updateGeometry(void)
	bool updatesEnabled(void)
	QRegion visibleRegion(void)
	QString whatsThis(void)
	int width(void)
	int winId(void)
	QWidget *window(void)
	QString windowFilePath(void)
	int windowFlags(void)
	QIcon windowIcon(void)
	QString windowIconText(void)
	int windowModality(void)
	double windowOpacity(void)
	QString windowRole(void)
	int windowState(void)
	QString windowTitle(void)
	int windowType(void)
	int x(void)
	int y(void)
	bool close(void)
	void hide(void)
	void lower(void)
	void raise(void)
	void setDisabled(bool disable)
	void setEnabled(bool)
	void setHidden(bool hidden)
	void setStyleSheet(QString)
	void setWindowModified(bool)
	void setWindowTitle(QString)
	void show(void)
	void showFullScreen(void)
	void showMaximized(void)
	void showMinimized(void)
	void showNormal(void)
	QWidget *find(int id)
	QWidget *keyboardGrabber(void)
	QWidget *mouseGrabber(void)
	void setTabOrder(QWidget *first, QWidget *second)

	<class>
	name: QLabel
	para: QWidget *
	parent: QWidget
	</class>

	int alignment(void)
	QWidget *buddy(void)
	bool hasScaledContents(void)
	bool hasSelectedText(void)
	int indent(void)
	int margin(void)
	QMovie *movie(void)
	bool openExternalLinks(void)
	QPicture *picture(void)
	QPixmap *pixmap(void)
	QString selectedText(void)
	int selectionStart(void)
	void setAlignment(int)
	void setBuddy(QWidget *buddy)
	void setIndent(int)
	void setMargin(int)
	void setOpenExternalLinks(bool open)
	void setScaledContents(bool)
	void setSelection(int start, int length)
	void setTextFormat(int)
	void setTextInteractionFlags(int flags)
	void setWordWrap(bool on)
	QString text(void)
	int textFormat(void)
	int textInteractionFlags(void)
	bool wordWrap(void)
	void clear(void)
	void setMovie(QMovie *movie)
	void setNum(double num)
	void setPicture(QPicture)
	void setPixmap(QPixmap)
	void setText(QString)

	<class>
	name: QPushButton
	para: QWidget *
	parent: QWidget
	codename: GPushButton
	passvmpointer
	</class>

	void setText(const char *)
	void setClickEvent(const char *)
	void setIcon(QIcon)
	void setIconSize(QSize)

	<class>
	name: QLineEdit
	para: QWidget *
	parent: QWidget
	codename: GLineEdit
	passvmpointer
	</class>

	int alignment(void)
	void backspace(void)
	QCompleter *completer(void)
	QMenu *createStandardContextMenu(void)
	void cursorBackward(bool mark, int steps)
	void cursorForward(bool mark, int steps)
	int cursorMoveStyle(void)
	int cursorPosition(void)
	int cursorPositionAt(QPoint)
	void cursorWordBackward(bool mark)
	void cursorWordForward(bool mark)
	void del(void)
	void deselect(void)
	QString displayText(void)
	bool dragEnabled(void)
	int echoMode(void)
	void end(bool mark)
	void getTextMargins(int *left, int *top, int *right, int *bottom)
	bool hasAcceptableInput(void)
	bool hasFrame(void)
	bool hasSelectedText(void)
	void home(bool mark)
	QString inputMask(void)
	void insert(QString)
	bool isModified(void)
	bool isReadOnly(void)
	bool isRedoAvailable(void)
	bool isUndoAvailable(void)
	int maxLength(void)
	QString placeholderText(void)
	QString selectedText(void)
	int selectionStart(void)
	void setAlignment(int flag)
	void setCompleter(QCompleter *c)
	void setCursorMoveStyle(int style)
	void setCursorPosition(int)
	void setDragEnabled(bool b)
	void setEchoMode(int)
	void setFrame(bool)
	void setInputMask(QString)
	void setMaxLength(int)
	void setModified(bool)
	void setPlaceholderText(QString)
	void setReadOnly(bool)
	void setSelection(int start, int length)
	void setTextMargins(int left, int top, int right, int bottom)
	void setValidator(QValidator *v)
	QString text(void)
	QMargins textMargins(void)
	QValidator *validator(void)

	void clear(void)
	void copy(void) 
	void cut(void)
	void paste(void)
	void redo(void)
	void selectAll(void)
	void setText(QString)
	void undo(void)

	void setTextChangedEvent(const char *)
	void setcursorPositionChangedEvent(const char *)
	void seteditingFinishedEvent(const char *)
	void setreturnPressedEvent(const char *)
	void setselectionChangedEvent(const char *)
	void settextEditedEvent(const char *)

.. note:: ソースコード全文は Ring ソースコードの配布物にあるため、
        この取扱説明書からは前述の設定ファイルにおける内容の大部分を割愛しています。


.. index:: 
	pair: コード生成器; 静的メソッド

静的メソッド
============

Ring 1.8 からコード生成器は staticmethods オプションに対応しました。

これにより、コード生成器はクラスでメソッドを呼び出すためのオブジェクトの準備は不要であることを検出できるようになりました。

用例:

.. code-block:: none

	<class>
	name: QStandardPaths
	para: void
	nonew
	staticmethods
	</class>

	QString displayName(QStandardPaths::StandardLocation type)
	QString findExecutable(QString executableName, QStringList paths))

.. index:: 
	pair: コード生成器; ファイルの読み込み

ファイルの読み込み
==================

コード生成器は <loadfile> 命令に対応しました (Ring 1.9 以降)。

.. code-block:: ring

	<loadfile> filename.cf

これは、拡張機能設定ファイルを複数のファイルへ分割するのに便利です。

用例:

ファイル : RingQt 拡張機能の qt_module_network.cf より引用

.. code-block:: ring

	<comment>
					モジュール (ネットワーク)
	</comment>

	<loadfile> qabstractsocket.cf
	<loadfile> qnetworkproxy.cf
	<loadfile> qtcpsocket.cf
	<loadfile> qtcpserver.cf
	<loadfile> qhostaddress.cf
	<loadfile> qhostinfo.cf
	<loadfile> qnetworkrequest.cf
	<loadfile> qnetworkaccessmanager.cf
	<loadfile> qnetworkreply.cf

.. index:: 
	pair: コード生成器; マネージドクラス

マネージドクラス
================

コード生成器は、クラス定義時の <managed> オプションに対応しました (Ring 1.9 以降)。

このオプションにより、生成器は C ポインタを返すために RING_API_RETMANAGEDCPOINTER() を使用します。

これにより、ガベージコレクターは C ポインタを管理対象にします。

用例:

.. code-block:: ring

	<class>
	name: QFont
	para: QString, int, int, bool
	managed
	</class>


.. index:: 
	pair: コード生成器; 設定ファイルの用例

設定ファイルの用例
==================

この用例から学ぶことができます。

* RingAllegro : https://github.com/ring-lang/ring/blob/master/extensions/ringallegro/allegro.cf
* RingQt : https://github.com/ring-lang/ring/blob/master/extensions/ringqt/classes/qt.cf
* RingLibSDL : https://github.com/ring-lang/ring/blob/master/extensions/ringsdl/libsdl.cf

設定ファイルの変更後に、必ずコードの生成をしてください。
この用例から学ぶことができます。

* RingAllegro : https://github.com/ring-lang/ring/blob/master/extensions/ringallegro/gencode.bat
* RingQt : https://github.com/ring-lang/ring/blob/master/extensions/ringqt/gencode.bat
* RingLibSDL : https://github.com/ring-lang/ring/blob/master/extensions/ringsdl/gencode.bat

コード生成後にライブラリのビルドを必ずしてください。この用例から学ぶことができます。

* RingAllegro : https://github.com/ring-lang/ring/blob/master/extensions/ringallegro/buildvc.bat
* RingQt : https://github.com/ring-lang/ring/blob/master/extensions/ringqt/buildmingw32.bat
* RingLibSDL : https://github.com/ring-lang/ring/blob/master/extensions/ringsdl/buildvc.bat
