4.1.1 プラグインとモジュール


Crystal Space is a package of components and libraries which can all be useful for creating computer games. Although some of the packages are intended more for 3D gaming this is not as such a restriction of the package. Components such as the sound driver function just as well in a 2D gaming environment, and the Virtual File System plugin (see section Virtual File System (VFS)) can be used in non-graphical applications. This highlights one of the important characteristics of Crystal Space: the components and libraries are more or less independent of each other. If you do not want "real" physics, then just don't use the physics plugin. If you don't want scripting then don't include that. All packages are designed to be functional on their own or with a minimal number of other packages. There are some dependencies of course. For example, the 3D engine requires a 3D renderer to display its output, and a renderer requires a canvas onto which to draw. On the other hand, you could very well use the 3D renderer without the 3D engine.

Crystal Spaceはコンピュータゲームを作成するために便利なコンポーネントとライブラリのパッケージです。いくつかのパッケージが3Dゲームを対象としていますが、これはパッケージの制限というわけではありません。2Dゲーム環境で使用することのできるサウンドドライバー関数のコンポーネント、それと、仮想ファイルシステムプラグイン( see section 仮想ファイルシステム(VFS)) はグラフィカルでないアプリケーションでも使用することができます。Crystal Spaceの重要な特徴の1つは、コンポーネントとライプラリがおおよそ他のものから独立していることです。もしあなたが実物理を必要としないのであれば、あなたはただ、物理プラグインを使わなければ良いだけです。スクリプトを欲しくなければ、それを含めないことです。すべてのパッケージは、自身のみ、または最低限の他のパッケージで機能するようにデザインされています。もちろん、いくつかの従属性はあります。例えば、3Dエンジンは、出力を表示するための3Dレンダーを必要とします。そして、レンダーは描画するためのキャンパスを必要とします。一方で、あなたは3Dエンジンなしで3Dレンダーを使うことは、まずありえない。

Although there is a high level of independence, there is also a high level of integration. The components and libraries were also designed to be used together and as such offer a flexible scheme of integration.


If you are interested in developing a program using Crystal Space, then it is important to understand that Crystal Space is not a single monolithic library, but instead consists of several libraries and plug-in modules. This manual uses the term module for both libraries and plug-ins when the distinction between the two is not important.

もしあなたがCrystal Spaceを使用してプログラムを開発することに興味があるのなら、次のことを理解することが大切です。Crystal Spaceは単独な巨大ライブラリではなく、いくつかのライブラリとプラグインモジュールから成っていること。このマニュアルは、ライブラリとプラグインの違いが重要でないとき、ライブラリとプラグインの両方の用語単位に使用します。

A plug-in module is similar to a library, but has some advantages over a library. All plug-ins can be accessed in a common fashion. They have a pure interface, and they can provide this interface even if they are extracted to a dynamic load library. So, they are the better solution as long as speed is not the dictator of all decisions as in the math library (access to plug-in functions uses virtual methods). The main difference between the interface of a library and a plug-in is that a library may use SCF, the Shared Class Facility (see section Shared Class Facility (SCF)), and C++ classes; plug-ins may only use SCF.


  • SCFって?

The main SCF object is the interface. An interface is the solution to strictly decouple the public methods of an object from their implementation. You only get a pointer to an abstract class with only virtual methods, called the interface, so your program doesn't know about the actual object behind the pointer. This object is called an implementation of the interface. You as the user of Crystal Space will call functions that create the actual object, but only return the interface. After that you can use the interface like a C++ object. When you don't need it anymore, don't `delete' it, but call DecRef?(). When you pass a pointer to the interface to anywhere, call IncRef?() from there, and DecRef?() when you don't need the interface there anymore.

主なSCFオブジェクトはインターフェイスです。インターフェイスは、オブジェクトのパブリックメソッドを実装から完全に分離します。あなたは、インターフェイスから呼ばれる仮想メソッドのみの抽象クラスのポインタを取得するだけです。そのため、あなたのプログラムはポインタの先にある実オブジェクトを知りません。Crystal Spaceのユーザとしてのあなたは、実オブジェクトを作成する機能を呼ぶことができます。しかし、それはインターフェイのみを返します。その後、あなははインターフェイスをC++オブジェクトのように使うことができます。あなたが、インターフェイスを必要としなくなったときは、それを'削除'せず、DecRef?()を呼んで下さい。もしあなたが、どこかでインターフェイスのポインタを使用するときは、IncRef?()を呼んでください。そして必要なくなったらDefRec?()を呼んでください。

Starting with Crystal Space version 0.95 we also have smart pointers. A smart pointer is an instance of the class csRef. This class takes care of IncRef?() and DecRef?() for you (see section Correctly Using Smart Pointers). It is very important to use smart pointers now. They are making life a lot easier and in the future they may become required usage (i.e. no longer optional).

Crystal Space バージョン0.95から、Crystal Spaceにはスマートポインタがあります。スマートポインタは、csRefクラスのインスタンスです。csRefクラスは、IncRef?()とDecRef?()を管理します(see section Correctly Using Smart Pointers)。現在では、スマートポインタを使用することは重要なことです。それらは、プログラムを容易にし、将来は必須の使用法となるでしょう(すなわち、もはやオプションではない)。

As the user you'll only have to include a header that defines the interface, but not the implementation. Despite the obvious advantage of having a very clear structure in your code, there is the advantage that linking the interface to the implementation can be done at run-time, but more about this later.


  • ライブラリの特徴ってなに?

A library is just a normal C++ library as you know them. A library can optionally provide SCF interfaces. In the case of a library this is just a way to define a clear structure. But as their main interface, libraries provide C++ classes.


  • プラグインの特徴ってなに?

A plug-in, on the other hand, will only provide SCF interfaces, no normal C++ classes. The plug-in itself will also appear as an SCF interface. This is part of the definition of a plug-in. A plug-in can be organized as static library or DLL; this only makes a small difference in how you use it in your program.


As the user of Crystal Space, you have to do the following steps to use a plug-in:

Crystal Spaceのユーザとして、あなたはプラグインを使用するために次のステップを踏まなければなりません。

  1. First, do all these steps for the dependencies (other plug-ins) that this plug-in relies on.
  2. Register the library that contains the plug-in.
  3. Load the plug-in. This will also initialize the plug-in. It will fail if you forgot any dependencies.
  4. Query the plug-in interface. This is an SCF interface, so you now have access to the functions of the plug-in.
  1. まず、このプラグインが頼っている従属した(他のプラグイン)に対し、以下のステップをします。
  2. プラグインを含むライブラリをレジストします。
  3. プラグインをロードします。プラグインの初期化も行います。ほかの従属関係を忘れた場合は、初期化に失敗します。
  4. プラグインのインターフェイスを実行します。これは、SCFインターフェイスです。そのため、あなたはプラグインの関数にアクセスすることができます。
  • プラグインライブラリはどうやってレジストするの?

Registering means to tell SCF the name of the plug-in that was given to it by its author, and a class or a dynamic library to associate it with. Plugin libraries can contain multiple named SCF classes. For example, to use the software graphics renderer SCF must know that the SCF class `crystalspace.graphics3d.software' can be found in `soft3d.dll' (Windows) or `soft3d.so' (Unix). SCF determines dynamically which plugin libraries contain which SCF classes by consulting meta-information associated with each plugin. Depending upon the platform, the associated meta-information may be bundled into the plugin itself, or it might exist in a separate file with a `.csplugin' extension alongside the plugin module.


  1. ラグインの作者によりプラグインに与えられたプラグインの名前
  2. プラグインに関連づけられたクラスまたはDLL


How you register a library depends on whether it is a static library or a dynamic library (`.dll' or `.so'). For a static library, that is, one which is linked directly into the application rather than loaded dynamically at run-time, put the following macro invocation at top-level in one of your C++ files once for each SCF class contained in your library:

ライブラリをレジストする方法は、スタティックライブラリか、ダイナミックライブラリかに左右されます(`.dll` or `.so`)。スタティックライブラリの場合、実行時動的にロードするよりも、アプリケーションに直接リンクさせます。次のマクロを、あなたのC++ファイルの1つに1度だけ、起動のトップレベルとなる箇所に置いて下さい。あなたのC++ファイルは、あなたのライブラリの中に含まれるいくつかのSCFクラスの中の1つのファイルです。


Here, cxx-class is the name of the C++ class which implements the factory for this particular SCF class. cxx-class is the same name given to the SCF_IMPLEMENT_FACTORY() macro. scf-name is the SCF class name corrsponding to cxx-class, description is a human-readable string describing the purpose of the class, and dependencies is a comma-separated list of other SCF class upon which this class depends.


For a dynamic library, SCF will discover the plugin and register the contained classes automatically by consulting the associated meta-information.


  • どうやってプラグインをロードするの?

To load a plug-in, you must tell the plug-in manager the name of the plug-in as it was registered in the previous step. In the most common case you will probably use the plug-in loader to load the plug-in. This is a convenience class that is able to load plug-in as specified in a config file, from the commandline, or as requested by the application programmer. In addition to loading the plug-in (the plug-in loader will use the plug-in manager to do that), the plug-in loader will optionally also register the plug-in with the Object Registry.


  1. config file
  2. コマンドライン
  3. アプリケーションプログラマーの要求


The object registry is a central location in the Crystal Space framework where any module can register SCF objects. The object registry is not only for plug-ins. It can contain any SCF object. Objects in the object registry also have a tag name associated with them. By convention the default object for a given SCF interface will be added to the object registry with the tag name equal to the interface name. For example, a 3D renderer is a plug-in module that implements (among others) the `iGraphics3D' interface. At the same time there can be multiple 3D renderers in memory (for example, for procedural textures). But the default 3D renderer will be registered with the tag name `iGraphics3D'.

オブジェクトレジストリは、Crystal Space frameworkで重要な場所です。そこは、モジュールがSCFオブジェクトをレジストすることができます。オブジェクトレジストリは、プラグインのためだけにあるのではありません。それは、どんなSCFオブジェクトでも含めることができます。オブジェクトレジストリの中のオブジェクトは、それに関連付けられたタグ名を持っています。SCFにより与えられたデフォルトオブジェクトの仕様により、SCFインターフェイスはインターフェイス名と同じタグ名を用い、オブジェクトレジスタに追加されるでしょう。例えば、3Dレンダは、`iGraphics3D`インターフェイスを実装したプラグインモジュールです。同時に、メモリには複数の3Dレンダがある可能性があります(例えば、テクスチャの手続きのためのレンダ)。しかし、デフォルトの3Dレンダはタグ名`iGraphics3D`を使用しレジストされます。

Note that the decision which graphics driver you use (e.g. Software or OpenGL) is done at the time you load the plug-in by passing the name of that driver. At the time you ask for the plug-in interface and use it in your program, this does not make a difference anymore. This makes it possible to exchange the driver simply by loading another driver, but without changing your main program.

注意して下さい。どのグラフィックスドライバ(Software または OpenGL)を使用するかは、ドライバ名にパスを通すことにより、プラグインをロードした時点に行われます。プラグインインターフェイスを尋ねるときと、プログラム内で使用するときには、グラフィックスドライバは変更されません。これは、あなたの主要なプログラムの交換なしに、別のドライバをロードすることで簡単にドライバを交換することを可能にします。

The Crystal Space modules themselves will use the standard plug-ins with the default tag name as explained above. For example, the 3d engine looks for the graphics driver by looking in the object registry for an object with the tag `iGraphics3D'.

Crystal Space モジュールは、基本のプラグインに対し、上記で説明したようにデフォルトのタグ名を使用します。例えば3dエンジンは、オブジェクトレジスタの中を、タグ名`iGraphics3D`のオブジェクトを探すことによりグラフィックスドライバを探します。

Now how can you actually load the plug-in? You can either load them manually in the code using the csLoadPlugin? function or else you can use the plugin loader. As explained above, the plugin loader can load plugins specified on the commandline, a config file, or else explicitly requested in the code. This is done in a specific way: The commandline has highest priority. i.e. if the user specified the OpenGL video driver on the commandline then this will be the plugin that is loaded on the `iGraphics3D' tag. The config file and plugins requested from the code are ignored then (for that tag at least). The plugins requested from the code have lowest priority and only serve as a default if neither the commandline nor the config file specified a plug-in for the given tag.

それでは、実際どのようにあなたがプラグインをロードするのでしょうか?あなたはcsLoadPlugin?関数を使用することで、コード内で手動でロードすることもできるし、 プラグインローダを使用することによってもロードすることができます。上記で説明したように、プラグインローダはコマンドライン / config file / コード内での明白な要求により特定のプラグインをロードすることができます。これは一定の方法により実行されます:コマンドラインは最も優先されます。例えば、もしユーザがコマンドラインでOpenGLドライバを指定したとき、OpenGLドライバプラグインが`iGraphics3D`タグにロードされます。config fileとコードからのプラグインの要求はそのときは無視されます(すくなくとも、このタグに関しては)。コードからのプラグイン要求は、最低の優先度で、コマンドライン / config fileでタグ指定のないプラグインの、デフォルトとして扱うとよいでしょう。

There is a class called csInitializer() which contains various convenience routines to help initialize a Crystal Space application. This class also contains a routine (RequestPlugins?()) which will use the plugin loader automatically.

csInitializer()が呼ばれるクラスがあります。csInitializer()は、Crystal Spaceアプリケーションの初期化を手助けする、様々な便利なおきまり手順が含まれています。このクラスは、自動的にプラグインローダを使用するおきまり手順(RequestPlugins?())も含まれています。

There are several advantages to using the plugin loader as opposed to manually loading plug-ins using csLoadPlugin?:


  • The plugin loader will sort all plug-ins based on dependencies. For example, the engine depends on a 3D rasterizer so the plugin loader will make sure that the engine is loaded later. If you manually load plugins you risk that the loading will fail because a plugin that it needs is not yet present.
  • The user is able to override the plug-ins loaded by the plugin loader. He or she can modify the config file or specify an alternative plug-in on the commandline. There is no way to change what plugin is loaded using csLoadPlugin? unless by recompilation (unless of course you use some other way to read the config file and find out what plugin to load).
  • プラグインローダは、依存関係を基にプラグインをソートします。例えば、エンジンは3Dラスタライザに依存します。そのため、プラグインローダはエンジンのロードを後でロードします。もし、あなたが手動でプラグインをロードするとき、あなたはロードが失敗するリスクを負います。なぜなら、プラグインが必要とするプラグインがまだ存在していないかもしれないからです。
  • ユーザはプラグインによってロードされたプラグインをオーバーライドすることができます。彼らは、config fileを修正することができます。また、コマンドラインにより別のプラグインを指定することができます。csLoadPlugin?を使用してロードしたプラグインを交換する方法は、再コンパイル以外にありません(もちろん、あなたがconfig fileを読んで、どんなpluginをロードしたらよいかを見つける、他の方法を使用しない場合)。
  • プラグインインターフェイスを実行するには?

This is the last step before you can use the plug-in. It means that inside your program you ask the object registry for an object registered with the desired tag. The easiest way to do this is as follows: csQueryRegistry?<iInterface>(object_reg). This macro will search the object registry for the default object implementing the given interface (i.e. the object registered with the tag equal to the interface name). Alternatively you can also use csQueryRegistryTag? to get an object with a specific tag.

これが、あなたがプラグインを使用する前の最後のステップです。これは、あなたのプログラムの中で、あなたがオブジェクトレジスタに、目的とするレジストされたオブジェクトを尋ねることを意味します。これを実行する最も簡単な方法は次の通りです: csQueryRegistry?<iInterface>(object_reg)。このマクロは、与えられたインターフェイスを実装するデフォルトオブジェクトをオブジェクトレジストリから検索します(例: インターフェイス名と同じタグでレジストされたオブジェクト)。他の手段として、あなたは特定のタグを用いたオブジェクトを取得するために、csQueryRegistryTag?を使用することができます。

  • 結論

To sum it up, SCF is mainly used to provide common interfaces for DLLs, but it can also be used by statically linked libraries. If you want to know how to write a plug-in yourself, you should read the complete SCF documentation. See section Shared Class Facility (SCF).

要するに、SCFがDLLの共通のインターフェイスを供給することに主に使用されます。しかしSCFは、ライブラリを静的にリンクことによっても使用されます。もし、あなたが自身でプラグインを作成する方法を知りたければ、あなたはSCFドキュメント一式を読むべきでしょう。Shared Class Facility(SCF)をご覧下さい。

For further information about modules and plug-in drivers, see the sections on using Crystal Space (see section Using Crystal Space).

モジュールとプラグインドライバについてのこれ以上の情報は、Crystal Space の使い方の章をご覧下さい。(see section Crystal Space の使い方)

Now that you have learned some basics about the Crystal Space environment, you can try writing your first program.

今、あなたはCrystal Space環境についてのいくつかの基礎を学びました。あなたは、はじめのプログラムを書くことに挑戦することができます。