# HG changeset patch # User Kazuma Takeda # Date 1487066343 -32400 # Node ID 4d06f18af177369672faa49410be75eea4075d95 # Parent 207fa0b0c3a21a0f312f919759055e23dc8bfbdc add prepaper. diff -r 207fa0b0c3a2 -r 4d06f18af177 paper/images/cassandra_quorum_read.pdf Binary file paper/images/cassandra_quorum_read.pdf has changed diff -r 207fa0b0c3a2 -r 4d06f18af177 paper/images/cassandra_quorum_write.pdf Binary file paper/images/cassandra_quorum_write.pdf has changed diff -r 207fa0b0c3a2 -r 4d06f18af177 paper/images/cassandra_ring.pdf Binary file paper/images/cassandra_ring.pdf has changed diff -r 207fa0b0c3a2 -r 4d06f18af177 paper/main.pdf Binary file paper/main.pdf has changed diff -r 207fa0b0c3a2 -r 4d06f18af177 paper/main.tex --- a/paper/main.tex Tue Feb 14 17:11:47 2017 +0900 +++ b/paper/main.tex Tue Feb 14 18:59:03 2017 +0900 @@ -36,12 +36,12 @@ \setlength{\itemsep}{-1zh} -\title{ゲームエンジンにおける木構造データベースJungleの提案} +\title{ゲームエンジンにおける木構造データベースjungleの提案} \title{Proposal of tree structured database Jungle in Game Engine.} \icon{ \includegraphics[width=80mm,bb=0 0 595 642]{fig/ryukyu.pdf} %%元は 642じゃなくて842 } -\year{平成28年度 卒業論文} +\year{平成29年度 卒業論文} \belongto{琉球大学工学部情報工学科} \author{135768K 武田 和馬 \\ 指導教員 {河野 真治} } @@ -237,7 +237,6 @@ \section{Jungleの提案} この章の前半ではRDBとNoSQLの利点と問題点を取り上げた。 -RDBではプログラム 非破壊的木構造データベースのJungleを提案している\cite{jungle}。 Jungleはスケーラビリティのあるデータベースとして開発している。 @@ -735,7 +734,7 @@ ItemTreeではRootノードはItemのTypeが書かれた子ノードを持っている。 子ノードはStageを構成するBox Type、回復アイテムとするFood Typeの2種類である。 -\section{Attributeの格納するデータの型} +\section{ゲームエンジンに特化したデータベース} C\#の再実装を行った際にJavaのJungleに沿ってデータの型、つまりByteArrayで設計を行っていた。 @@ -782,18 +781,15 @@ 分散構造や、ネットワークで必要な時だけ変換する。 -\chapter{ベンチマーク} +\chapter{Jungle-Sharpの評価} 本章ではC\#とJava版Jungleとの比較、Jungle-SharpとUnity上で使われるSQLite3、PlayerPrefsとの比較を行う。 \section{Javaとの比較} 本論文ではJavaで書かれたJungle DatabaseをC\#で再実装した。 - 同じオペレーションでJavaとC\#で計測する。 - なお、1回目の処理はキャッシュを作り処理が遅くなるため、計測は行わず、2回目以降から行う。 - 計測時に使用したデータ挿入のオペレーションを以下に記述する。 % 単一のベンチマーク @@ -847,14 +843,14 @@ Jungleでは木構造を変更する計算量として、O(1)からO(n)が期待される。 -図\ref{BenchMark}より、Unityで実行した結果ではO(n)となっている。 +図\ref{BenchMark}より、Unityで実行した結果ではO(n)のグラフを示している。 Unityではレンダリングの機能も兼ねている。 - そのためプログラムを実行している間もレンダリングを行っているため、 純粋なPutAttributeの計算時間ではないと考えられる。 XamarinはC\#の性能を確認するために実行した。 -結果として見るとJavaに比べてC\#が早い。 +C\#で再実装したJungleはJava版とほぼ同じ計算量を示している。 + % なんでか?みたいなお話 % プリミティブ型?データ型? diff -r 207fa0b0c3a2 -r 4d06f18af177 paper/src/InhelitClients.java --- a/paper/src/InhelitClients.java Tue Feb 14 17:11:47 2017 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,14 +0,0 @@ -@Override -public void inhelitClients(String hostName, short newVNCServerId, int x, int y, int width, int height, int scale) { - final ConnectionPresenter connectionPresenter = createNewConnectionPresenter(hostName, newVNCServerId, x, y, width, height, scale); - isApplet = true; - this.setNoConnection(false); - final Viewer v = this; - - new Thread(new Runnable() { - @Override - public void run() { - connectionPresenter.startVNCConnection(v, false, null, null); - } - }, "ServerChangeThread").start(); -} diff -r 207fa0b0c3a2 -r 4d06f18af177 prepaper/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/prepaper/Makefile Tue Feb 14 18:59:03 2017 +0900 @@ -0,0 +1,36 @@ +# Created by Daichi Toma on Nov 16, 2011 + +TARGET=finalPre + +LATEX=platex +BIBTEX=pbibtex +DVIPDF=dvipdfmx -p a4 +#You need setting "-l" option if You think You get a landscape PDF +#DVIPDF_OPT=-l + +#Embed fonts +#DVIPDF_OPT=-f hiraginoEmbed.map + +.SUFFIXES: .tex .dvi .pdf + +.tex.dvi: + $(LATEX) $< + $(BIBTEX) $(TARGET) + $(LATEX) $< + $(LATEX) $< + +.dvi.pdf: + $(DVIPDF) $(DVIPDF_OPT) $< + + +all: $(TARGET).pdf + open $(TARGET).pdf + +dvi: $(TARGET).dvi + +pdf: $(TARGET).pdf + + +clean: + rm -f *.dvi *.aux *.log *.pdf *.ps *.gz *.bbl *.blg *.toc *~ *.core + diff -r 207fa0b0c3a2 -r 4d06f18af177 prepaper/dummy.tex --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/prepaper/dummy.tex Tue Feb 14 18:59:03 2017 +0900 @@ -0,0 +1,60 @@ +%%% jdummy.def +% +\DeclareRelationFont{JY1}{mc}{it}{}{OT1}{cmr}{it}{} +\DeclareRelationFont{JT1}{mc}{it}{}{OT1}{cmr}{it}{} +\DeclareFontShape{JY1}{mc}{m}{it}{<5> <6> <7> <8> <9> <10> sgen*min + <10.95><12><14.4><17.28><20.74><24.88> min10 + <-> min10}{} +\DeclareFontShape{JT1}{mc}{m}{it}{<5> <6> <7> <8> <9> <10> sgen*tmin + <10.95><12><14.4><17.28><20.74><24.88> tmin10 + <-> tmin10}{} +\DeclareRelationFont{JY1}{mc}{sl}{}{OT1}{cmr}{sl}{} +\DeclareRelationFont{JT1}{mc}{sl}{}{OT1}{cmr}{sl}{} +\DeclareFontShape{JY1}{mc}{m}{sl}{<5> <6> <7> <8> <9> <10> sgen*min + <10.95><12><14.4><17.28><20.74><24.88> min10 + <-> min10}{} +\DeclareFontShape{JT1}{mc}{m}{sl}{<5> <6> <7> <8> <9> <10> sgen*tmin + <10.95><12><14.4><17.28><20.74><24.88> tmin10 + <-> tmin10}{} +\DeclareRelationFont{JY1}{mc}{sc}{}{OT1}{cmr}{sc}{} +\DeclareRelationFont{JT1}{mc}{sc}{}{OT1}{cmr}{sc}{} +\DeclareFontShape{JY1}{mc}{m}{sc}{<5> <6> <7> <8> <9> <10> sgen*min + <10.95><12><14.4><17.28><20.74><24.88> min10 + <-> min10}{} +\DeclareFontShape{JT1}{mc}{m}{sc}{<5> <6> <7> <8> <9> <10> sgen*tmin + <10.95><12><14.4><17.28><20.74><24.88> tmin10 + <-> tmin10}{} +\DeclareRelationFont{JY1}{gt}{it}{}{OT1}{cmbx}{it}{} +\DeclareRelationFont{JT1}{gt}{it}{}{OT1}{cmbx}{it}{} +\DeclareFontShape{JY1}{mc}{bx}{it}{<5> <6> <7> <8> <9> <10> sgen*goth + <10.95><12><14.4><17.28><20.74><24.88> goth10 + <-> goth10}{} +\DeclareFontShape{JT1}{mc}{bx}{it}{<5> <6> <7> <8> <9> <10> sgen*tgoth + <10.95><12><14.4><17.28><20.74><24.88> tgoth10 + <-> tgoth10}{} +\DeclareRelationFont{JY1}{gt}{sl}{}{OT1}{cmbx}{sl}{} +\DeclareRelationFont{JT1}{gt}{sl}{}{OT1}{cmbx}{sl}{} +\DeclareFontShape{JY1}{mc}{bx}{sl}{<5> <6> <7> <8> <9> <10> sgen*goth + <10.95><12><14.4><17.28><20.74><24.88> goth10 + <-> goth10}{} +\DeclareFontShape{JT1}{mc}{bx}{sl}{<5> <6> <7> <8> <9> <10> sgen*tgoth + <10.95><12><14.4><17.28><20.74><24.88> tgoth10 + <-> tgoth10}{} +\DeclareRelationFont{JY1}{gt}{sc}{}{OT1}{cmbx}{sc}{} +\DeclareRelationFont{JT1}{gt}{sc}{}{OT1}{cmbx}{sc}{} +\DeclareFontShape{JY1}{mc}{bx}{sc}{<5> <6> <7> <8> <9> <10> sgen*goth + <10.95><12><14.4><17.28><20.74><24.88> goth10 + <-> goth10}{} +\DeclareFontShape{JT1}{mc}{bx}{sc}{<5> <6> <7> <8> <9> <10> sgen*tgoth + <10.95><12><14.4><17.28><20.74><24.88> tgoth10 + <-> tgoth10}{} +\DeclareRelationFont{JY1}{gt}{it}{}{OT1}{cmr}{it}{} +\DeclareRelationFont{JT1}{gt}{it}{}{OT1}{cmr}{it}{} +\DeclareFontShape{JY1}{gt}{m}{it}{<5> <6> <7> <8> <9> <10> sgen*goth + <10.95><12><14.4><17.28><20.74><24.88> goth10 + <-> goth10}{} +\DeclareFontShape{JT1}{gt}{m}{it}{<5> <6> <7> <8> <9> <10> sgen*tgoth + <10.95><12><14.4><17.28><20.74><24.88> tgoth10 + <-> tgoth10}{} +\endinput +%%%% end of jdummy.def diff -r 207fa0b0c3a2 -r 4d06f18af177 prepaper/finalPre.pdf Binary file prepaper/finalPre.pdf has changed diff -r 207fa0b0c3a2 -r 4d06f18af177 prepaper/finalPre.tex --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/prepaper/finalPre.tex Tue Feb 14 18:59:03 2017 +0900 @@ -0,0 +1,325 @@ +\documentclass[twocolumn,twoside,9.5pt]{jarticle} +\usepackage[dvipdfmx]{graphicx} +\usepackage{picins} +\usepackage{fancyhdr} +\usepackage{ascmac} +\usepackage{abstract} +\usepackage{url} +%\pagestyle{fancy} +\lhead{\parpic{\includegraphics[height=1zw,keepaspectratio,bb=0 0 251 246]{pic/emblem-bitmap.pdf}}琉球大学主催 工学部情報工学科 卒業研究発表会} +\rhead{} +\cfoot{} + +\setlength{\topmargin}{-1in \addtolength{\topmargin}{15mm}} +\setlength{\headheight}{0mm} +\setlength{\headsep}{5mm} +\setlength{\oddsidemargin}{-1in \addtolength{\oddsidemargin}{11mm}} +\setlength{\evensidemargin}{-1in \addtolength{\evensidemargin}{21mm}} +\setlength{\textwidth}{181mm} +\setlength{\textheight}{261mm} +\setlength{\footskip}{0mm} +\pagestyle{empty} + +\input{dummy.tex} +\renewcommand{\abstractname}{Abstract} +\begin{document} +\title{ゲームエンジンにおける木構造データベースJungleの提案} +%\title{Supporting NAT in Screen Sharing System TreeVNC} +\author{135768K 氏名 {武田}{和馬} 指導教員 : 河野 真治} +\date{} +\twocolumn [ +\maketitle +\begin{onecolabstract} +There are some problems to Relational Databases and NoSQLs. +One of them as Impedance mismatch. This problem is cased by a difference between the first normal form of database and the programs. +There is a problem that NoSQL is unfit for parallel processing. + +% まだかけてない... +\end{onecolabstract}] +\thispagestyle{fancy} + +\section{ゲームエンジンにおけるデータベース} + +Relational Database(RDB)は、列と行からなる2次元のテーブルにより実装されるデータベースである。 +データ型として文字列、数値、日付、Bool型がある。 +RDBはスキーマの決まったデータを扱うことを長所としている。 + +RDBではプログラムとデータベースとの間にミスマッチが発生する。 +プログラムではリストやネスト構造によりデータを持つことができる。 +しかし、データのネスト構造を許さない第一正規形を要求するRDBとは相容れない。 +これをインピーダンスミスマッチという。 + +この例として、ゲーム中のユーザが持つアイテムという単純なものでは +RDBではユーザとアイテムの組をキーとする巨大な表として管理する。 + +インピーダンスミスマッチの解決方法としてORMapperが挙げられる。 +これはデータベースのレコードをプログラム中のオブジェクトにマッピングし扱うことができる。 +オブジェクトに対する操作を行うとORMapperがSQLを発行し、処理を行ってくれる。 +しかし、レコードをプログラム中のオブジェクトを対応させるORMapperの技術でインピーダンスミスマッチの本質的な部分を解決することはできない。 + +NoSQLはNot Only SQLの略である。 + +通常NoSQLデータベースは非リレーショナル型であり、スキームの定義がない\cite{nosql}。 +そのため、扱うデータの型が決まっていなくても気軽に扱える。 + +しかし、トランザクションとしてJsonの一括といった形で処理されている。 +そのため並列処理を必要とするアプリケーションには向かない。 + +\section{Jungle Databaseの提案} + +この章の前半ではRDBとNoSQLの利点と問題点を取り上げた。 + +非破壊的木構造データベースのJungleを提案している\cite{jungle}。 +Jungleはスケーラビリティのあるデータベースとして開発している。 + +ウェブサイトの構造は大体が木構造であるため、Jungleではデータ構造として木構造を採用している。 +しかし、ウェブサイトだけでなくゲームにおいてもデータ構造が木構造になっている。 + +そこで、本研究ではJungleの木構造である特性を活かし、ゲームエンジンUnityで作成したゲームで使用する方法を提案する。 + +データベースとしてJungle Databaseを採用する。 + +JungleはJavaとHaskellによりそれぞれの言語で開発されている。 +本研究で扱うのはJava版をC\#で再実装したものである。 + +\section{Jungle-Sharpの再実装} + +JungleはもともとJavaとHaskellで書かれていた。 +今回はJava版をベースにC\#で再実装する。 +エラーをチェックするEitherの部分だけはHaskellの要素を取ってくる。 + +Jungleではデータの編集を行った後、Eitherを用いてエラーのチェックを行う。 +エラーがあればエラーが包まれたEitherが返される。 +エラーがない場合は指定した型のオブジェクトがEitherに包まれて返される。 + +これは関数型プログラミング言語、Haskellから採用したものである。 + +編集を行うたび、Eitherのチェックbindで行うことにより、より関数型プログラミングに特化した書き方が可能になる。 +C\#で実装したbindは以下に記述する。 + +\begin{itembox}[l]{DefaultEither.cs} +\scriptsize{ +\begin{verbatim} +public Either bind (System.Func> f) { + if (this.isA ()) { + return this; + } + + return f (this.b ()); +} +\end{verbatim} +} +\end{itembox} + +bindでのEitherをチェックしつつデータを格納する例を以下に記述する。 + +\begin{itembox}[l]{DataSaveTest.cs} +\scriptsize{ +\begin{verbatim} + Item apple = new Item("Apple"); + + either = either.bind ((JungleTreeEditor arg) => { + return arg.addNewChildAt (rootPath, 0); + }); + + either = either.bind ((JungleTreeEditor arg) => { + return arg.putAttribute (apple); + }); + +\end{verbatim} +} +\end{itembox} + +bindの実装により、ユーザ側でEitherのErrorチェックを行う必要がなくなる。 + +\section{Unityで実装したアプリケーション} + +本論文ではC\#で再実装を行ったJungleをUnityで作られたゲームの上に構築する。 +例題のゲームとしては図\ref{craft}に記載した、マインクラフト\cite{minecraft}の簡易版を作成する。 + +\begin{figure}[h] +\begin{center} +\includegraphics[width=6cm]{images/craft.png} +\caption{craft} +\label{craft} +\end{center} +\end{figure} + +プレイヤーは自由にマップを移動し、ステージの破壊や、生成を行うことができる。 +破壊や生成のオペレーションに合わせてJungleのノードにも同期する。 +この同期も非破壊で行われる。 + +\section{データの設計} + +Unityにおけるゲームの構成はObjectの親子関係、つまり木構造である。 +同じくJungle Databaseは木構造である。 +% Unityでシーンを構成する際にデータの設計を気にしなくてもいい。 + +Jungleでは複数の木を持つことができる。 +ゲームのシーンを構成するGameTreeとアイテムを管理するItemTreeをJungle内に作る。 + +GameTreeではシーン内にあるPlayerやStageを構成するCubeなどを格納している。 +図\ref{GameTree}ではJungleに格納する構造を示したものである。 + +\begin{figure}[h] +\begin{center} +\includegraphics[width=6cm]{images/Tree.pdf} +\caption{GameTree} +\label{GameTree} +\end{center} +\end{figure} + +ItemTreeではItemの情報が格納されている。 +ItemTreeはマスターデータとしている\cite{gamedata}\cite{gamedata2}。 +マスターデータとは、アイテムの名前や敵の出現確率などを示す。 +ゲーム開発者のみが更新できる。 + +図\ref{ItemTree}ではJungleに格納しているItemの構造を示したものである。 + +\begin{figure}[h] +\begin{center} +\includegraphics[width=6cm]{images/ItemTree.pdf} +\caption{ItemTree} +\label{ItemTree} +\end{center} +\end{figure} + +\section{ゲームに特化したデータベース} + +C\#の再実装を行った際にJavaのJungleに沿ってデータの型、つまりByteArrayで設計を行っていた。 +データの格納を行うたびにByte Arrayへのキャストを行う必要がある。 +しかし、キャストの処理は軽くはない。 + +そこで、シーンを構成するObjectをそのまま格納するに仕様を変更した。 +C\#ではObjectクラスのエイリアスとしてobject型が使える。 + +object型を使うことによってユーザーが定義した任意の変数を代入することができる。 +以下にその使用例を記述する。 + +\begin{itembox}[l]{SaveData.cs} +\scriptsize{ +\begin{verbatim} +Player player = new Player (); +either = either.bind ((JungleTreeEditor arg) => { + return arg.putAttribute ("Player", player); +}); + +Enemy enemy = new Enemy (); +either = either.bind ((JungleTreeEditor arg) => { + return arg.putAttribute ("Enemy", enemy); +}); +\end{verbatim} +} +\end{itembox} + +データを取り出すにはGenericで型を指定する、もしくはas演算子を用いてキャストを行う。 +以下に取り出す例を記述する。 + +\begin{itembox}[l]{SaveData.cs} +\scriptsize{ +\begin{verbatim} +Player player = attr.get ("Player"); +Enemy enemy = attr.get ("Enemy") as Enemy; +\end{verbatim} +} +\end{itembox} + +データの型の再設計を行ったことによりシーン内のオブジェクトをそのまま格納が可能になった。 +格納の際にByte Arrayに変換する必要がない。 + +分散構造や、ネットワークで必要な時だけ変換する。 + +\section{Jungle-Sharpの評価} + +本論文ではJavaで書かれたJungle DatabaseをC\#で再実装した。 +同じオペレーションでJavaとC\#で計測を行った。 +なお、1回目の処理はキャッシュを作り処理が遅くなるため、計測は行わず、2回目以降から行う。 +計測時に使用したデータ挿入のオペレーションを以下に記述する。 + +\begin{itembox}[l]{BenchMarkmark.cs} +\scriptsize{ +\begin{verbatim} +for (int i = 0; i < trial; i++) { + Either either = edt.addNewChildAt (path, i); + either = either.bind ((JungleTreeEditor arg) => { + return arg.putAttribute ("name", "Kazuma"); + }); +} +\end{verbatim} +} +\end{itembox} + +計測に使用したマシンの環境を記述する。 + +\begin{table}[htb] +\begin{center} +\caption{計測環境} +\begin{tabular}{|p{7em}|p{7em}|} \hline +OS & +Mac OS Sierra 10.12.3 \\ \hline +Memory & +8 GB 2133 MHz LPDDR3 \\ \hline +CPU & +2.9 GHz Intel Core i5 \\ \hline +Java & +1.8.0111 \\ \hline +.NET Runtimes (MonoDevelop-Unity) & +Mono 4.0.5 \\ \hline +.NET Runtimes (Xamarin) & +Mono 4.6.2 \\ \hline +\end{tabular} +\label{itembox} +\end{center} +\end{table} + +計測結果を図\ref{BenchMark}に示す。 + +\begin{figure}[h] +\begin{center} +\includegraphics[width = 8cm]{images/benchmark.pdf} +\caption{BenchMark} +\label{BenchMark} +\end{center} +\end{figure} + +図\ref{BenchMark}より、Unityで実行した結果ではO(n)のグラフを示している。 +Unityではレンダリングの機能も兼ねている。 +そのためプログラムを実行している間もレンダリングを行っているため、 +純粋なPutAttributeの計算時間ではないと考えられる。 + +そこで、純粋な速度を測定するためXamarinで動かし測定した。 +C\#で再実装したJungleはJava版とほぼ同じ計算量を示している。 +これにより、本来のJavaと同じ、もしくはそれ以上のパフォーマンスを引き出すことができる。 + +\section{まとめ} + +本研究ではJungleDatabaseをC\#で再実装を行った。 +JavaとC\#は比較的似ている言語であるため移行は難しくはなかった。 + +性能としてもJava版に劣らない、もしくはそれ以上のパフォーマンスを出せる。 + +Eitherでのbindの実装で、より関数型プログラミングを意識しながら記述することができる。 +これはJava版にはない実装である。 + +Jungle DatabaseはもともとWeb向けに作られたデータベースである。 + +Webではリニアにデータが書き換わることは多くない。 +しかしゲームでは扱うデータが多くリニアに書き換わる。 + +そのため、Jungleの構成は保ちつつ、ゲームに合わせたJungleの拡張を行った。 + +データの格納の際にByteBufferであったものをObject型に変更した。 +これにより、シーンを構成するObjectを手間なく格納することを可能にした。 + +Jungleは非破壊であるため、過去の変更を持っている。 + +ゲームにおいて過去の木を持ち続けることはパフォーマンスの低下につながる。 +そのため、過去の木をどこまで必要かを検討しなければならない。 + +現在C\#版のJungleにはデータを永続化させる仕組みは備わっていない。 +実用的なゲームのデータベースとして使うためには永続化を実装する必要がある。 + +\nocite{*} +\bibliographystyle{junsrt} +\bibliography{reference} +\end{document} diff -r 207fa0b0c3a2 -r 4d06f18af177 prepaper/images/ItemTree.pdf Binary file prepaper/images/ItemTree.pdf has changed diff -r 207fa0b0c3a2 -r 4d06f18af177 prepaper/images/Tree.pdf Binary file prepaper/images/Tree.pdf has changed diff -r 207fa0b0c3a2 -r 4d06f18af177 prepaper/images/benchmark.pdf Binary file prepaper/images/benchmark.pdf has changed diff -r 207fa0b0c3a2 -r 4d06f18af177 prepaper/images/craft.png Binary file prepaper/images/craft.png has changed diff -r 207fa0b0c3a2 -r 4d06f18af177 prepaper/images/emblem-bitmap.pdf Binary file prepaper/images/emblem-bitmap.pdf has changed diff -r 207fa0b0c3a2 -r 4d06f18af177 prepaper/jlisting.sty --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/prepaper/jlisting.sty Tue Feb 14 18:59:03 2017 +0900 @@ -0,0 +1,216 @@ +\NeedsTeXFormat{LaTeX2e} +\def\filedate{2006/02/20} +\def\fileversion{0.2} +\ProvidesPackage{jlisting}[\filedate\space\fileversion\space(Thor)] +% +\newcount\lst@nextchar +\let\lst@@ProcessSpace\lst@ProcessSpace +\def\lst@ProcessSpace#1{% + \lst@check@chartype{#1}% + \lst@@ProcessSpace + \lst@whitespacetrue} +\let\lst@@ProcessLetter\lst@ProcessLetter +\def\lst@ProcessLetter#1#2{% + \lst@check@chartype{#2}% + {\lst@@ProcessLetter{#1}}% + \relax} +\let\lst@@ProcessDigit\lst@ProcessDigit +\def\lst@ProcessDigit#1#2{% + \lst@check@chartype{#2}% + {\lst@@ProcessDigit{#1}}% + \relax} +\let\lst@@ProcessOther\lst@ProcessOther +\def\lst@ProcessOther#1#2{% + \lst@check@chartype{#2}% + {\lst@@ProcessOther{#1}}% + \relax} +\let\lst@@ProcessTabulator\lst@ProcessTabulator +\def\lst@ProcessTabulator#1{% + \lst@check@chartype{#1}% + \lst@@ProcessTabulator + \relax} +\def\lst@check@chartype#1#2#3{% + \edef\@tempa{\lst@nextchar=`\string#1\relax}% + \afterassignment\remove@to@nnil + \@tempa\@nnil + #2% + \ifnum\lst@nextchar<\@cclvi + #3% + \else + \lst@ifletter \else \lst@OutputOther \fi + \lst@whitespacefalse + \expandafter\lst@AppendJchar + \fi + #1} +\def\lst@AppendJchar#1#2{% + \lst@check@chartype{#2}% + {\advance\lst@length\@ne\lst@Append{#1}}% + \relax} +\def\lst@check@chartype@BOL#1{% + \edef\@tempa{\lst@nextchar=`\string#1\relax}% + \afterassignment\remove@to@nnil + \@tempa\@nnil + \ifnum\lst@nextchar<\@cclvi\else + \lst@whitespacefalse + \expandafter\lst@AppendJchar + \fi + #1} +\def\lst@InputListing#1{% + \begingroup + \lsthk@PreSet \gdef\lst@intname{#1}% + \expandafter\lstset\expandafter{\lst@set}% + \lsthk@DisplayStyle + \catcode\active=\active + \lst@Init\relax \let\lst@gobble\z@ + \lst@SkipToFirst + \lst@ifprint \def\lst@next{\lst@get@filecontents{#1}}% + \else \let\lst@next\@empty + \fi + \lst@next + \lst@DeInit + \endgroup} +\newread\lst@inputfile +\def\lst@get@filecontents#1{% + \let\lst@filecontents\@empty + \openin\lst@inputfile=#1\relax + \let\@lst@get@filecontents@prevline\relax + \lst@get@filecontents@loop + \closein\lst@inputfile + \lst@filecontents\empty} +\def\lst@get@filecontents@loop{% + \read\lst@inputfile to\@lst@get@filecontents@currline + \ifx\@lst@get@filecontents@prevline\relax\else + \expandafter\expandafter\expandafter\def + \expandafter\expandafter\expandafter\lst@filecontents + \expandafter\expandafter\expandafter{% + \expandafter\lst@filecontents\@lst@get@filecontents@prevline}% + \fi + \let\@lst@get@filecontents@prevline\@lst@get@filecontents@currline + \ifeof\lst@inputfile\else + \expandafter\lst@get@filecontents@loop + \fi} +%%% [$B$3$N=hM}$b!$AjEv6/0z$G$9!%(B] +\def\lst@BOLGobble{% + \ifnum\lst@gobble>\z@ + \@tempcnta\lst@gobble\relax + \expandafter\lst@BOLGobble@ + \else + \expandafter\lst@check@chartype@BOL + \fi} +\def\lst@BOLGobble@#1{% + \let\lst@next#1% + \ifx \lst@next\relax\else + \ifx \lst@next\lst@MProcessListing\else + \ifx \lst@next\lst@ProcessFormFeed\else + \ifx \lst@next\lstenv@backslash + \let\lst@next\lstenv@BOLGobble@@ + \else + \let\lst@next\lst@BOLGobble@@ + \ifx #1\lst@ProcessTabulator + \advance\@tempcnta-\lst@tabsize\relax + \ifnum\@tempcnta<\z@ + \lst@length-\@tempcnta \lst@PreGotoTabStop + \fi + \else + \edef\@tempa{\lst@nextchar=`\string#1\relax}% + \@tempa + \ifnum\lst@nextchar<\@cclvi\else + \advance\@tempcnta\m@ne + \fi + \advance\@tempcnta\m@ne + \fi + \fi \fi \fi \fi + \lst@next} +\def\lst@BOLGobble@@{% + \ifnum\@tempcnta>\z@ + \expandafter\lst@BOLGobble@ + \else + \expandafter\lst@check@chartype@BOL + \fi +} +% +% \begin{$B=$@5;v9`(B}{1.3} +% $B$A$g$C$H$7$?=$@5(B +\gdef\lst@breakProcessOther#1{\lst@ProcessOther#1} +% $B%=!<%9%3!<%IL\:\$7$^$7$?!#(B + +\begin{quote} + \url{http://http://cise.edu.mie-u.ac.jp/~okumura/texfaq/qa/21172.html}\\ + \url{http://http://cise.edu.mie-u.ac.jp/~okumura/texfaq/qa/21184.html}\\ + \url{http://http://cise.edu.mie-u.ac.jp/~okumura/texfaq/qa/21189.html}\\ + \url{http://http://cise.edu.mie-u.ac.jp/~okumura/texfaq/qa/21197.html} +\end{quote} + + Copyright $B$O5H1JE/H~;a$K$"$k$N$@$H;W$$$^$9!%(B + +\section{$B99?7MzNr(B}% ChageLogs + +\begin{description} + \item[ver.~0.1 (2004/03/24)] + $B$H$j$"$($:8x3+!%(B + \item[ver.~0.2 (2006/02/20)] + \verb|\lst@breakProcessOther| $BL?Na$NDj5A$NDI2C!%(B +\end{description} + +\section{$B%=!<%9%3!<%I(B} +\par\narrowbaselines +\verbatiminput{jlisting.sty} +\end{document} diff -r 207fa0b0c3a2 -r 4d06f18af177 prepaper/picins.sty --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/prepaper/picins.sty Tue Feb 14 18:59:03 2017 +0900 @@ -0,0 +1,578 @@ +% PICINS.STY --- Style File zum Einbinden von Bildern +% Autor: J. Bleser, E. Lang +% Hochschulrechenzentrum +% Technische Hochschule Darmstadt +% !!! Dieses Style-File ist urheberrechtlich geschuetzt !!! +% !!! Aenderungen nur mit Zustimmung der Autoren !!! +\message{Option `picins' Version 3.0 Sep. 1992, TH Darmstadt/HRZ} +\newbox\@BILD% +\newbox\@TEXT% +\newdimen\d@breite% +\newdimen\d@hoehe% +\newdimen\d@xoff% +\newdimen\d@yoff% +\newdimen\d@shad% +\newdimen\d@dash% +\newdimen\d@boxl% +\newdimen\d@pichskip% +\newdimen\d@tmp +\newdimen\d@tmpa +\newdimen\d@bskip +\newdimen\hsiz@% +\newdimen\p@getot@l% +\newcount\c@breite +\newcount\c@hoehe +\newcount\c@xoff +\newcount\c@yoff +\newcount\c@pos +\newcount\c@shad +\newcount\c@dash +\newcount\c@boxl +\newcount\c@zeilen% +\newcount\@changemode% +\newcount\c@piccaption% +\newcount\c@piccaptionpos% +\newcount\c@picpos +\newcount\c@whole% +\newcount\c@half% +\newcount\c@tmp +\newcount\c@tmpa +\newcount\c@tmpb +\newcount\c@tmpc +\newcount\c@tmpd +\newskip\d@leftskip +\newif\if@list \@listfalse% +\newif\if@offset% + + +\c@piccaptionpos=1% +\c@picpos=0 +\d@shad=4pt% +\d@dash=4pt% +\d@boxl=10pt% +\d@pichskip=1em% +\@changemode=0% +\def\@captype{figure}% +\let\old@par=\par% + +\def\pichskip#1{\d@pichskip #1\relax} + + +\def\shadowthickness#1{\d@shad #1\relax} + + +\def\dashlength#1{\d@dash #1\relax} + + +\def\boxlength#1{\d@boxl #1\relax} + + +\def\picchangemode{\@changemode=1}% +\def\nopicchangemode{\@changemode=0}% + + +\def\piccaptionoutside{\c@piccaptionpos=1}% +\def\piccaptioninside{\c@piccaptionpos=2}% +\def\piccaptionside{\c@piccaptionpos=3}% +\def\piccaptiontopside{\c@piccaptionpos=4}% + +\def\piccaption{\@ifnextchar [{\@piccaption}{\@piccaption[]}} +\def\@piccaption[#1]#2{\c@piccaption=1\def\sh@rtf@rm{#1}\def\capti@nt@xt{#2}} +\def\make@piccaption{% + \hsiz@\d@breite% + \ifnum\c@piccaptionpos=2% + \advance\hsiz@ -2\fboxsep% + \fi% + \ifnum\c@piccaptionpos>2% + \hsiz@\hsize\advance\hsiz@-\d@breite\advance\hsiz@-\d@pichskip% + \fi% + \setbox\@TEXT=\vbox{\hsize\hsiz@\caption[\sh@rtf@rm]{\capti@nt@xt}}% +} + + + +\def\newcaption{\refstepcounter\@captype\@dblarg{\@newcaption\@captype}} +\long\def\@newcaption#1[#2]#3{% + \old@par% + \addcontentsline{\csname ext@#1\endcsname }{#1}% + {\protect\numberline{\csname the#1\endcsname}{\ignorespaces #2}} + \begingroup\@parboxrestore\normalsize% + \@newmakecaption{\csname fnum@#1\endcsname}{\ignorespaces #3}\old@par% + \endgroup% +} +\long\def\@newmakecaption#1#2{% + \vskip 10pt% + \setbox\@tempboxa \hbox {#1: #2}% + \ifdim \wd\@tempboxa >\hsize% + \setbox0=\hbox{#1: }\dimen0=\hsize\advance\dimen0 by-\wd0 + \setbox1=\vtop{\hsize=\dimen0 #2} + \hbox{\box0 \box1} + \par + \else \hbox to\hsize {\hfil \box \@tempboxa \hfil} + \fi +} + + + + + +\def\parpic{% + \@ifnextchar ({\iparpic}{\iparpic(0pt,0pt)} +} +\def\iparpic(#1,#2){% + \@ifnextchar ({\@offsettrue\iiparpic(#1,#2)}% + {\@offsetfalse\iiparpic(#1,#2)(0pt,0pt)} +} +\def\iiparpic(#1,#2)(#3,#4){% + \@ifnextchar [{\iiiparpic(#1,#2)(#3,#4)}{\iiiparpic(#1,#2)(#3,#4)[l]} +} +\def\iiiparpic(#1,#2)(#3,#4)[#5]{% + \@ifnextchar [{\ivparpic(#1,#2)(#3,#4)[#5]}{\ivparpic(#1,#2)(#3,#4)[#5][]} +} +\def\ivparpic(#1,#2)(#3,#4)[#5][#6]#7{% + \let\par=\old@par\par% + \hangindent0pt\hangafter1% + \setbox\@BILD=\hbox{#7}% + \d@breite=#1\d@breite=\the\d@breite% + \ifdim\d@breite=0pt\d@breite=\wd\@BILD\fi% + \c@breite=\d@breite\divide\c@breite by65536% + \multiply\c@piccaption\c@piccaptionpos% + \d@hoehe=#2\d@hoehe=\the\d@hoehe% + \ifdim\d@hoehe=0pt\d@hoehe=\ht\@BILD\advance\d@hoehe by\dp\@BILD\fi% + \c@hoehe=\d@hoehe\divide\c@hoehe by65536% + \d@xoff=#3\c@xoff=\d@xoff\divide\c@xoff by65536% + \d@yoff=\d@hoehe% + \advance\d@yoff by-#4\c@yoff=\d@yoff\divide\c@yoff by65536% + \c@pos=1\unitlength1pt% + \if@offset% + \setbox\@BILD=\hbox{% + \begin{picture}(\c@breite,\c@hoehe)% + \put(0,0){\makebox(\c@breite,\c@hoehe){}}% + \put(\c@xoff,\c@yoff){\box\@BILD}% + \end{picture}% + }% + \else% + \setbox\@BILD=\hbox{% + \begin{picture}(\c@breite,\c@hoehe)% + \put(0,0){\makebox(\c@breite,\c@hoehe)[#6]{\box\@BILD}}% + \end{picture}% + }% + \fi% + \ifnum\c@piccaption=2% + \make@piccaption% + \advance\d@hoehe\ht\@TEXT\advance\d@hoehe\dp\@TEXT% + \c@hoehe=\d@hoehe\divide\c@hoehe by65536% + \setbox\@BILD=\vbox{\box\@BILD\vspace{-5pt}% + \hbox{\hspace{\fboxsep}\box\@TEXT}% + \vspace{4pt}}% + \fi% + \@tfor\@tempa := #5\do{% + \if\@tempa f\setbox\@BILD=\hbox{\Rahmen(\c@breite,\c@hoehe){\box\@BILD}}\fi% + \if\@tempa s\setbox\@BILD=\hbox{\Schatten(\c@breite,\c@hoehe){\box\@BILD}}\fi% + \if\@tempa o\setbox\@BILD=\hbox{\Oval(\c@breite,\c@hoehe){\box\@BILD}}\fi% + \if\@tempa d\setbox\@BILD=\hbox{\Strich(\c@breite,\c@hoehe){\box\@BILD}}\fi% + \if\@tempa x\setbox\@BILD=\hbox{\Kasten(\c@breite,\c@hoehe){\box\@BILD}}\fi% + \if\@tempa l\c@pos=1\fi% + \if\@tempa r\c@pos=2\fi% + }% + \ifnum\c@piccaption=1% + \make@piccaption% + \advance\d@hoehe\ht\@TEXT\advance\d@hoehe\dp\@TEXT% + \c@hoehe=\d@hoehe\divide\c@hoehe by65536% + \setbox\@BILD=\vbox{\box\@BILD\vspace{-5pt}\hbox{\box\@TEXT}\vspace{4pt}}% + \fi% + \ifodd\count0\c@picpos=0\else\c@picpos=\@changemode\fi% + \pagetotal=\the\pagetotal% + \d@tmp=\pagegoal\advance\d@tmp by-\pagetotal\advance\d@tmp by-\baselineskip% + \ifdim\d@hoehe>\d@tmp% + \vskip 0pt plus\d@hoehe\relax\pagebreak[3]\vskip 0pt plus-\d@hoehe\relax% + \ifnum\c@picpos=1\c@picpos=0\else\c@picpos=\@changemode\fi% + \fi% + \ifnum\c@picpos=1\ifnum\c@pos=1\c@pos=2\else\c@pos=1\fi\fi% + \ifnum\@listdepth>0 + \@listtrue\parshape 0% + \advance\hsize -\rightmargin% + \d@leftskip \leftskip% + \leftskip \@totalleftmargin% + \if@inlabel\rule{\linewidth}{0pt}\vskip-\baselineskip\relax\fi% + \else\@listfalse\medskip% + \fi% + \if@list\d@tmpa=\linewidth\else\d@tmpa=\hsize\fi% + \ifnum\c@piccaption=3% + \make@piccaption% + \d@tmp\ht\@TEXT\advance\d@tmp\dp\@TEXT% + \ifdim\d@hoehe>\d@tmp% + \setbox\@TEXT=\vbox to\d@hoehe{\vfill\box\@TEXT\vspace{.2\baselineskip}\vfill}% + \else% + \setbox\@BILD=\vbox to\d@tmp{\vfill\box\@BILD\vfill}% + \d@hoehe\d@tmp% + \fi% + \fi% + \ifnum\c@piccaption=4% + \make@piccaption% + \d@tmp\ht\@TEXT\advance\d@tmp\dp\@TEXT% + \setbox\@TEXT=\vbox to\d@hoehe{\vspace{-10pt}\box\@TEXT\vfil}% + \advance\d@hoehe-\d@tmp% + \fi% + \ifnum\c@pos=1\d@tmpa=0pt% + \ifnum\c@piccaption>2% + \setbox\@BILD=\hbox{\box\@BILD\hspace{\d@pichskip}\hbox{\box\@TEXT}}% + \fi% + \else\advance\d@tmpa by-\wd\@BILD\d@breite=-\d@breite% + \ifnum\c@piccaption>2% + \d@tmpa=0pt% + \setbox\@BILD=\hbox{\hbox{\box\@TEXT}\hspace{\d@pichskip}\box\@BILD}% + \fi% + \fi% + \p@getot@l\the\pagetotal% + \d@bskip\d@hoehe\advance\d@bskip by\parskip\advance\d@bskip by.3\baselineskip% + {\noindent\hspace*{\d@tmpa}\relax% + \box\@BILD\nopagebreak\vskip-\d@bskip\relax\nopagebreak}% + \d@tmp=-\d@hoehe\divide\d@tmp by\baselineskip% + \c@zeilen=\d@tmp\advance\c@zeilen by-1% + \ifdim\d@breite<0pt\advance\d@breite by-\d@pichskip% + \else\advance\d@breite by\d@pichskip% + \fi% + \hangindent=\d@breite% + \hangafter=\c@zeilen% + \let\par=\x@par% + \ifnum\c@piccaption=3% + \hangindent0pt\hangafter1\let\par=\old@par% + \vskip\d@hoehe\vskip.2\baselineskip% + \fi% + \c@piccaption=0% +} + + + + +\newdimen\ptoti +\newdimen\ptotii +\def\x@par{% + \ptoti\pagetotal% + \old@par% + \ptotii\pagetotal% + \ifdim\ptoti=\ptotii% + \d@tmp\d@hoehe% + \else% + \d@tmp\baselineskip% + \multiply\d@tmp by\prevgraf% + \advance\d@tmp by\parskip% + \global\advance\d@hoehe by-\d@tmp\d@tmp=\d@hoehe% + \fi% + \ifdim\d@hoehe>0pt% + \divide\d@tmp by\baselineskip\c@zeilen=-\d@tmp\advance\c@zeilen by-1% + \c@zeilen=\the\c@zeilen% + \else\c@zeilen=0 + \fi + \ifnum\c@zeilen<0\hangafter=\c@zeilen\hangindent=\d@breite% + \else\let\par=\old@par% + \hangindent 0pt% + \leftskip \d@leftskip% + \if@list\parshape \@ne \@totalleftmargin \linewidth% + \advance\hsize \rightmargin% + \fi% + \fi% +} + + +\def\picskip#1{% + \let\par=\old@par% + \par% + \pagetotal\the\pagetotal% + \c@tmp=#1\relax% + \ifnum\c@tmp=0% + \d@tmp\baselineskip\multiply\d@tmp by\prevgraf\advance\d@tmp\parskip% + \ifdim\p@getot@l<\pagetotal + \advance\d@hoehe by-\d@tmp\advance\d@hoehe by1ex% + \ifdim\d@hoehe>0pt\vspace*{\d@hoehe}\fi% + \fi% + \ifdim\p@getot@l=\pagetotal% + \advance\d@hoehe by-\d@tmp\advance\d@hoehe by1ex% + \ifdim\d@hoehe>0pt\vspace*{\d@hoehe}\fi% + \fi% + \else\hangafter=-\c@tmp\hangindent=\d@breite% + \fi% + \leftskip \d@leftskip% + \if@list\parshape \@ne \@totalleftmargin \linewidth% + \advance\hsize \rightmargin% + \fi% +} + + + + + + +\def\hpic{% + \@ifnextchar ({\ihpic}{\ihpic(0pt,0pt)} +} +\def\ihpic(#1,#2){% + \@ifnextchar ({\@offsettrue\iihpic(#1,#2)}% + {\@offsetfalse\iihpic(#1,#2)(0pt,0pt)} +} +\def\iihpic(#1,#2)(#3,#4){% + \@ifnextchar [{\iiihpic(#1,#2)(#3,#4)}{\iiihpic(#1,#2)(#3,#4)[l]} +} +\def\iiihpic(#1,#2)(#3,#4)[#5]{% + \@ifnextchar [{\ivhpic(#1,#2)(#3,#4)[#5]}{\ivhpic(#1,#2)(#3,#4)[#5][]} +} +\def\ivhpic(#1,#2)(#3,#4)[#5][#6]#7{% + \setbox\@BILD=\hbox{#7}% + \d@breite=#1\d@breite=\the\d@breite% + \ifdim\d@breite=0pt\d@breite=\wd\@BILD\fi% + \c@breite=\d@breite\divide\c@breite by65536% + \d@hoehe=#2\d@hoehe=\the\d@hoehe% + \ifdim\d@hoehe=0pt\d@hoehe=\ht\@BILD\advance\d@hoehe by\dp\@BILD\fi% + \c@hoehe=\d@hoehe\divide\c@hoehe by65536% + \d@xoff=#3\c@xoff=\d@xoff\divide\c@xoff by65536% + \d@yoff=\d@hoehe% + \advance\d@yoff by-#4\c@yoff=\d@yoff\divide\c@yoff by65536% + \c@pos=0\d@tmpa=\parindent\parindent=0pt\unitlength1pt% + \if@offset + \setbox\@BILD=\hbox{% + \begin{picture}(\c@breite,\c@hoehe)% + \put(0,0){\makebox(\c@breite,\c@hoehe){}}% + \put(\c@xoff,\c@yoff){\box\@BILD}% + \end{picture}% + }% + \else% + \setbox\@BILD=\hbox{% + \begin{picture}(\c@breite,\c@hoehe)% + \put(0,0){\makebox(\c@breite,\c@hoehe)[#6]{\box\@BILD}}% + \end{picture}% + }% + \fi% + \@tfor\@tempa := #5\do{% + \if\@tempa f\setbox\@BILD=\hbox{\Rahmen(\c@breite,\c@hoehe){\box\@BILD}}\fi% + \if\@tempa s\setbox\@BILD=\hbox{\Schatten(\c@breite,\c@hoehe){\box\@BILD}}\fi% + \if\@tempa o\setbox\@BILD=\hbox{\Oval(\c@breite,\c@hoehe){\box\@BILD}}\fi% + \if\@tempa d\setbox\@BILD=\hbox{\Strich(\c@breite,\c@hoehe){\box\@BILD}}\fi% + \if\@tempa x\setbox\@BILD=\hbox{\Kasten(\c@breite,\c@hoehe){\box\@BILD}}\fi% + \if\@tempa t\c@pos=1\fi% + \if\@tempa b\c@pos=2\fi% + }% + \ifnum\c@pos=0\parbox{\d@breite}{\makebox[0cm]{}\\\box\@BILD\smallskip}\fi% + \ifnum\c@pos=1\parbox[t]{\d@breite}{\makebox[0cm]{}\\\box\@BILD\smallskip}\fi% + \ifnum\c@pos=2\parbox[b]{\d@breite}{\makebox[0cm]{}\\\box\@BILD\smallskip}\fi% + \parindent=\d@tmpa% +} + + + + + + +\def\Rahmen(#1,#2)#3{% + \c@whole=\@wholewidth\divide\c@whole by65536% + \c@half=\@halfwidth\divide\c@half by65536% + \c@tmpa=#1\advance\c@tmpa by\c@whole\advance\c@tmpa by\c@whole% + \c@tmpb=#2\advance\c@tmpb by\c@whole\advance\c@tmpb by\c@whole% + \begin{picture}(\c@tmpa,\c@tmpb)% + \put(\c@whole,\c@half){\framebox(#1,#2){#3}}% + \end{picture}% + \global\advance\d@breite by2\@wholewidth% + \global\advance\d@hoehe by2\@wholewidth% +} + + +\def\Schatten(#1,#2)#3{% + \c@whole=\@wholewidth\divide\c@whole by65536% + \c@half=\@halfwidth\divide\c@half by65536% + \c@shad=\d@shad\divide\c@shad by65536% + \c@tmp=\c@whole\advance\c@tmp by\c@whole\c@tmpd=\c@tmp% + \advance\c@tmp by\c@shad% + \advance\c@tmpd by#1% + \advance\c@half by\c@shad% + \c@tmpa=#1\advance\c@tmpa by\c@tmp% + \c@tmpb=#2\advance\c@tmpb by\c@tmp% + \begin{picture}(\c@tmpa,\c@tmpb)% + \put(\c@whole,\c@half){\framebox(#1,#2){#3}}% + \put(\c@shad,0){\rule{\c@tmpd pt}{\c@shad pt}}% + \put(\c@tmpd,0){\rule{\c@shad pt}{#2 pt}}% + \end{picture}% + \global\advance\d@breite by2\@wholewidth\global\advance\d@breite by\d@shad% + \global\advance\d@hoehe by2\@wholewidth\global\advance\d@hoehe by\d@shad% +} + + +\def\Oval(#1,#2)#3{% + \@wholewidth=0.4pt% + \c@tmpa=\the#1\divide\c@tmpa by2% + \c@tmpb=\the#2\divide\c@tmpb by2% + \begin{picture}(#1,#2)% + \put(\c@tmpa,\c@tmpb){\oval(#1,#2)}% + \put(0.4,0.4){#3}% + \end{picture}% + \global\advance\d@breite by1pt\global\advance\d@hoehe by1pt% +} + + +\def\Strich(#1,#2)#3{% + \c@whole=\@wholewidth\divide\c@whole by65536% + \c@half=\@halfwidth\divide\c@half by65536% + \c@dash=\d@dash\divide\c@dash by65536% + \c@tmp=\c@whole\advance\c@tmp by\c@whole% + \c@tmpa=#1\advance\c@tmpa by\c@tmp% + \c@tmpb=#2\advance\c@tmpb by\c@tmp% + \c@tmpc=#1\advance\c@tmpc by\c@whole% + \c@tmpd=#2\advance\c@tmpd by\c@whole% + \begin{picture}(\c@tmpa,\c@tmpb)% + \put(\c@half,\c@half){\dashbox{\c@dash}(\c@tmpc,\c@tmpd){#3}}% + \end{picture}% + \global\advance\d@breite by2\@wholewidth% + \global\advance\d@hoehe by2\@wholewidth% +} + + +\def\Kasten(#1,#2)#3{% + \@wholewidth=0.4pt% + \c@boxl=\d@boxl\divide\c@boxl by65536\c@boxl=\the\c@boxl% + \c@tmpa=#1\advance\c@tmpa by\c@boxl% + \c@tmpb=#2\advance\c@tmpb by\c@boxl% + \c@tmp=#2% + \begin{picture}(\c@tmpa,\c@tmpb)% + \put(0,\c@boxl){\framebox(#1,#2){#3}}% + \put(\c@boxl,0){\line(-1,1){\c@boxl}}% + \put(\c@boxl,0){\line(1,0){#1}\line(-1,1){\c@boxl}}% + \put(\c@boxl,0){\put(#1,0){\line(0,1){\c@tmp}% + \put(0,\c@tmp){\line(-1,1){\c@boxl}}}}% + \end{picture}% + \global\advance\d@breite by\d@boxl% + \global\advance\d@hoehe by\d@boxl% +} + + + + + +\newbox\env@box% +\newdimen\d@envdp +\newcount\c@hsize +\newcount\c@envdp +\newdimen\d@envb + +\long\def\frameenv{\@ifnextchar [{\@frameenv}{\@frameenv[\textwidth]}} +\long\def\@frameenv[#1]{% + \hsiz@=\textwidth \textwidth=#1 \d@envb=#1 + \advance\textwidth by-2\@wholewidth + \advance\textwidth by-2\fboxsep + \hsize=\textwidth \linewidth=\textwidth + \setbox\env@box=\vbox\bgroup}% +\def\endframeenv{% + \egroup% + \hsize=\hsiz@ \textwidth=\hsiz@ \linewidth=\hsiz@ + \c@breite=\d@envb \divide\c@breite by65536 + \advance\d@envb by-2\@wholewidth + \c@hsize=\d@envb \divide\c@hsize by65536% + \d@envdp=\dp\env@box \advance\d@envdp by\ht\env@box% + \advance\d@envdp by2\fboxsep% + \d@hoehe=\d@envdp \advance\d@hoehe by2\@wholewidth + \c@hoehe=\d@hoehe \divide\c@hoehe by65536 + \c@envdp=\d@envdp \divide\c@envdp by65536% + \c@tmp=\@wholewidth \divide\c@tmp by65536 + \vskip\@wholewidth% + \unitlength 1pt\noindent% + \begin{picture}(\c@breite,\c@hoehe)(0,0) + \put(\c@tmp,\c@tmp){\framebox(\c@hsize,\c@envdp){\box\env@box}} + \end{picture}% +} + + + +\long\def\shadowenv{\@ifnextchar [{\@shadowenv}{\@shadowenv[\textwidth]}} +\long\def\@shadowenv[#1]{% + \hsiz@=\textwidth \textwidth=#1 \d@envb=#1 + \advance\textwidth by-2\@wholewidth + \advance\textwidth by-2\fboxsep + \advance\textwidth by-\d@shad% + \hsize=\textwidth \linewidth=\textwidth + \setbox\env@box=\vbox\bgroup}% +\def\endshadowenv{% + \egroup + \hsize=\hsiz@ \textwidth=\hsiz@ \linewidth=\hsiz@ + \d@tmpa=\d@envb + \c@breite=\d@envb \divide\c@breite by65536 + \advance\d@envb by-2\@wholewidth \advance\d@envb by-\d@shad + \c@hsize=\d@envb \divide\c@hsize by65536% + \d@envdp=\dp\env@box \advance\d@envdp by\ht\env@box% + \advance\d@envdp by2\fboxsep% + \c@envdp=\d@envdp \divide\c@envdp by65536% + \d@hoehe=\d@envdp + \advance\d@hoehe by2\@wholewidth \advance\d@hoehe by\d@shad + \c@hoehe=\d@hoehe \divide\c@hoehe by65536 + \c@shad =\d@shad \divide\c@shad by65536 + \c@tmp=\@wholewidth \divide\c@tmp by65536 + \advance\d@tmpa by-2\d@shad + \c@xoff =\d@tmpa \divide\c@xoff by65536 + \advance\c@xoff by\c@shad \advance\c@xoff by-1 + \advance\d@envdp by\@wholewidth + \vskip\@halfwidth + \unitlength 1pt\noindent% + \begin{picture}(\c@breite,\c@hoehe)(0,0) + \put(\c@tmp,\c@shad){\framebox(\c@hsize,\c@envdp){\box\env@box}} + \put(\c@shad,0){\rule{\d@tmpa}{\d@shad}}% + \put(\c@xoff,0){\rule{\d@shad}{\d@envdp}}% + \end{picture}% + \vskip\@halfwidth +} + + +\long\def\dashenv{\@ifnextchar [{\@dashenv}{\@dashenv[\textwidth]}} +\long\def\@dashenv[#1]{% + \hsiz@=\textwidth \textwidth=#1 \d@envb=#1 + \advance\textwidth by-2\@wholewidth \advance\textwidth by-2\fboxsep + \hsize=\textwidth \linewidth=\textwidth + \setbox\env@box=\vbox\bgroup}% +\long\def\enddashenv{% + \egroup + \hsize=\hsiz@ \textwidth=\hsiz@ \linewidth=\hsiz@ + \c@breite=\d@envb \divide\c@breite by65536 + \advance\d@envb by-\@wholewidth + \c@hsize=\d@envb \divide\c@hsize by65536% + \d@envdp=\dp\env@box \advance\d@envdp by\ht\env@box% + \advance\d@envdp by2\fboxsep% + \advance\d@envdp by\@wholewidth + \d@hoehe=\d@envdp \advance\d@hoehe by2\@wholewidth + \c@hoehe=\d@hoehe \divide\c@hoehe by65536 + \c@envdp=\d@envdp \divide\c@envdp by65536% + \c@dash=\d@dash \divide\c@dash by65536% + \c@whole=\@wholewidth \divide\c@whole by65536 + \c@half=\@halfwidth \divide\c@half by 65536 + \noindent\unitlength 1pt + \begin{picture}(\c@breite,\c@hoehe)(0,0) + \put(\c@half,\c@whole){\dashbox{\c@dash}(\c@hsize,\c@envdp){\box\env@box}} + \end{picture}% +} + + +\long\def\ovalenv{\@ifnextchar [{\@ovalenv}{\@ovalenv[\textwidth]}}% +\long\def\@ovalenv[#1]{% + \hsiz@=\textwidth \textwidth=#1 \d@envb=#1 + \advance\textwidth by-4\fboxsep + \hsize=\textwidth \linewidth=\textwidth + \setbox\env@box=\vbox\bgroup}% +\long\def\endovalenv{% + \egroup + \hsize=\hsiz@ \textwidth=\hsiz@ \linewidth=\hsiz@ + \@wholewidth=0.4pt + \c@breite=\d@envb \divide\c@breite by65536 + \advance\d@envb by-2\@wholewidth + \c@hsize=\d@envb \divide\c@hsize by65536% + \d@envdp=\dp\env@box \advance\d@envdp by\ht\env@box% + \advance\d@envdp by4\fboxsep% + \c@envdp=\d@envdp \divide\c@envdp by65536% + \d@hoehe=\d@envdp \advance\d@hoehe by2\@wholewidth + \c@hoehe=\d@hoehe \divide\c@hoehe by65536 + \c@tmpa=\c@hsize \divide\c@tmpa by2% + \c@tmpb=\c@envdp \divide\c@tmpb by2% + \d@tmpa=2\fboxsep \advance\d@tmpa by\@wholewidth + \c@xoff=\d@tmpa \divide\c@xoff by65536% + \advance\d@tmpa by\dp\env@box + \c@yoff=\d@tmpa \divide\c@yoff by65536% + \unitlength 1pt\noindent + \begin{picture}(\c@breite,\c@hoehe)(0,0) + \put(\c@tmpa,\c@tmpb){\oval(\c@hsize,\c@envdp)} + \put(\c@xoff,\c@yoff){\box\env@box}% + \end{picture}% +} diff -r 207fa0b0c3a2 -r 4d06f18af177 prepaper/reference.bib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/prepaper/reference.bib Tue Feb 14 18:59:03 2017 +0900 @@ -0,0 +1,32 @@ +@Misc{minecraft, + author = "MicroSoft", + howpublished = "\url{https://minecraft.net/ja-jp/}" +} + +@Misc{jungle, + author = "Shoshi Tamaki, Seiyu Tani, Shinji Kono", + title = "Cassandraを使ったスケーラビリティのあるCMSの設計", + year = 2011, + journal = "情報処理学会システムソフトウェアとオペレーティング・システム研究会", +} + +@Misc{nosql, + author = "PETTER NÄSHOLM", + title = "Extracting Data from NoSQL Databases", + month = "jan", + year = 2012 +} + +@Misc{gamedata, + author = "{Hitonishi Masaki}", + title = "ゲームエンジニアのためのデータベース設計", + howpublished = "\url{http://www.slideshare.net/sairoutine/ss-62485460}" + +} + +@article{gamedata2, + author = "{Ryosuke Iwanaga}", + title = "ソーシャルゲームのためのMySQL入門", + howpublished = "\url{http://engineer.dena.jp/2010/11/mysql-for-socialgame.html}" +} + diff -r 207fa0b0c3a2 -r 4d06f18af177 presen/slide.pdf.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/presen/slide.pdf.html Tue Feb 14 18:59:03 2017 +0900 @@ -0,0 +1,667 @@ + + + + + ゲームエンジンにおけるJungleDatabaseの提案 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+ +
+ + + + + + + +
+
+

ゲームエンジンにおけるJungleDatabaseの提案

+
+
+
+ Kazuma Takeda + +
+
+
+
+ +
+ + + +

この発表のセクション

+ +
    +
  • RDBとNoSQL
  • +
  • Jungle Databseの提案
  • +
  • Jungleの仕様
  • +
  • ゲームのデータ構造
  • +
  • Jungle-Sharpの実装
  • +
  • 例題ゲームの実装
  • +
  • Jungle-Sharpの改良点
  • +
+ + +
+
+ +

RDBとNoSQL

+ +

Relational Databseと呼ばれるRDBは行と列からなる2次元のテーブルにより実装されているデータベース。 +データ型として文字列や数値、日付、Bool型がある。

+ +

データの一貫性を重視しているRDBでは分散システムには向いていない。

+ +

NoSQL(Not Only SQL) Databaseと呼ばれる非リレーショナル型のデータベース。 +スキームを持たないため、扱うデータの型を気にしなくてもよい。

+ +

一貫性を一部犠牲にしているNoSQLでは分散させることが可能である。 +CassandraやMongoDBなどが例に挙げられる。

+ + +
+
+ +

インピーダンスミスマッチ

+ +

プログラム中ではListやネスト構造によりデータを扱うことができる。 +しかしデータベースにはそのような概念はない。

+ +

そこにプログラムとデータベースの間にギャップが生じる。 +これをインピーダンスミスマッチという。

+ +

RDBではネスト構造を許さない第一正規形とは相容れない。

+ + +
+
+ +

NoSQLのトランザクション

+ +

CassandraやほとんどのNoSQLではACIDなトランザクションがない。 +トランザクション中の処理は外部からは閲覧出来ない。 +しかし、複数行を1回で書き換える機能を持っていないため、 +データを書き込んでいる途中の状態が見えてしまう場合がある。

+ + +
+
+ +

Jungle Databaseの提案

+ +

前章までRDBではプログラムとのミスマッチや分散構造に向いていない問題、NoSQLではトランザクションでの問題点について触れた。 +これらの問題を解決するため、当研究室で開発しているデータベースJungleを提案する。

+ +

Jungleは過去の変更データを保存しつつ新しい木を構築してく木構造(非破壊構造)の手法をとる。 +非破壊にすることにより、データを読み出す側と書き込む側のデータを安全に扱うことができる。

+ +

Jungleは名前で管理された木のあつまりからなる。 +木は複数のノードの集合からなる。

+ +

ノード自身にはKey-Valueのデータを格納することができる。 +これはデータベースのレコードに相当する。

+ +

Jungleのトランザクションはルートから変更を行うノードまでコピーを行い、新しく木構造を構築する。 +最後にルートをアトミックに入れ替えてコミットする。 +コミットが失敗した場合は最初からやり直す。 +これにより、原子性を実現する。

+ +

Jungleはcommit logを持ち、それを他のノードやディスクに転送することにより、 +分散構成と永続性を実現する。

+ + +
+
+ +

JungleのAPI

+ +

前章ではJungleの概要を記述した。 +本章ではJungleの主なAPIについて紹介する。

+ + +
+
+ +

Jungleの木

+ +

Jungleは複数の木を名前を利用して管理しており、名前により作成・編集を行う。

+ +
// Jungleに新しく木を生成する。木の名前が重複した場合、生成に失敗しnullを返す
+JungleTree  createNewTree(string treeName)
+
+// JungleからtreeNameと名前が一致するtreeを取得する。名前が一致するTreeがない場合取得は失敗しnullを返す
+JungleTree  getTreeByName(string treeName)
+
+
+ +

以下のコードは、Jungleの木を”TreeName”で生成し取得する。

+ +
JungleTree tree = jungle.createNewTree("GameTree");
+
+ + +
+
+ +

TreeNode

+ +

Jungleが保持している木は、複数のノードの集合で出来ている。 +ノードは、自身の子のListと属性名と属性値の組でデータを持つ。 +ノードに対するアクセスは、TreeNodeクラスに記述されているAPIを用いて行われる。

+ +
// ノードの子供を扱うChildrenオブジェクトを返す
+Children getChildren()
+
+// ノードが保持しているデータを扱うAttribteオブジェクトを返す
+Attribute getAttribute()
+
+ + +
+
+ +

ChildrenとAttribute

+ +

Childrenクラスを利用し、ノードの子どもにアクセスする。

+ +
// ノードが持っている子どもの個数を返す
+int size()
+
+// ノードが持つ子どもの中から、 変数numで指定された位置にある子ノードを返す
+Either<Error, TreeNode> at(int num)
+
+ +

Attributeクラスを利用し、ノードの保持する値にアクセスする。

+ +
// ノードからKeyで管理されるValueをobject型で返す
+object get(string key)
+
+// ノードからKeyで管理されるValueをstring型で返す
+string getString(string key)
+
+ + +
+
+ +

Eitherクラス

+ +

Jungleでは例外がある場合、Eitherクラスを用いて行う。

+ +
    +
  • 失敗時はA
  • +
  • 成功時はB
  • +
+ +

を包んで返す。 +失敗した場合ははじめからやり直す。 +以下に例を記述する。

+ +
Either<Error,TreeNode> either = children.at(2);
+if (either.isA()) 
+    return either.a();
+TreeNode child = either.b();
+
+
+ + +
+
+ +

Jungleのサンプルコード

+ +

Jungleの例を記載する。

+ +

以下のコードは、ルートノードの2番目の子どもから、属性名”name”とペアになっている属性値を取得する。

+ +
JungleTree tree = jungle.getTreeByName("GameTree");
+TreeNode root = tree.getRootNode();
+Children children = root.getChildren();
+Either<Error,TreeNode> either = children.at(2);
+if (either.isA()) 
+    return either.a();
+TreeNode child = either.b();
+Attribute attribute = child.getAttribute();
+string value = attribute.getstring("name");
+
+
+ + +
+
+ +

Jungleの木の編集

+ +

Jungleの木の編集はJungleTreeEditorクラスを用いて行われる。

+ +

JungleTreeEditorクラスには編集を行うために、定義されているAPIを記述する。

+ +

また、ノードを指定して編集を行う際にNodePathクラスを用いる。

+ + +
+
+ +

NodePath

+ +

Jungleでは、木のノードの位置をNodePathクラスを使って表す。

+ +

NodePathクラスはルートノードからスタートし、対象のノードまでの経路を、数字を用いて指し示すことで対象のノードの場所を表す。

+ +

また、ルートノードは例外として-1と表記される。

+ +
+ message +
+ + +
+
+ +

ノードの追加

+ +
// 変数pathで指定した場所にある、ノードの子供の変数posで指定した位置子ノードを追加
+Either<Error, JungleTreeEditor> addNewChildAt( NodePath path, int pos)
+// 変数pathで指定した場所にあるノードに、属性名 変数key 属性値 変数valueのペアで値を挿入
+Either<Error, JungleTreeEditor> putAttribute( NodePath path, string key, object value)
+
+// 変数pathで指定した場所にあるノードが持つ、属性名 変数keyとペアで保存されているデータを削除
+Either< Error, JungleTreeEditor> deleteAttribute( NodePath path, string key)
+
+
+ + +
+
+ +

コミット

+ +

編集の最後にTreeに対してコミットを行う。

+ +
// 木へ行った変更をコミット。自分が編集を行っていた間に、他のJungleTreeEditorクラスによって木が更新されていた場合、コミットは失敗
+Either<Error, JungleTreeEditor> commit()
+
+ + +
+
+ +

ゲームのデータ構造

+ +

Jungleはもともと認証管理システムやWeb向けに作られたものである。 +これらはすべて木構造をベースとしている。

+ +

ゲームでも同じことが考えられる。 +そこでゲームエンジンUnity向けにJungleの再実装を行い、ゲーム向けのデータベースとしての提案を行う。

+ +

Unityは3Dゲームエンジンで、ゲームを構成する要素(Object)をC#で制御する。 +Objectは一つのゲームのシーン(一画面の状況)の中で木構造を持つ。 +これをシーングラフと言う。 +シーングラフをそのままJungleに格納するという手法が考えられる。

+ + +
+
+ +

Jungle-Sharpの実装

+ +

JungleはもともとJavaとHaskellで書かれていた。 +今回はJava版をベースにC#で再実装する。

+ +

エラーをチェックするEitherの部分だけはHaskellの要素を取ってくる。

+ + +
+
+ +

Atomic Refarenceの実装

+ +

Jungleの木の変更(commit)はCAS(Check and Set)を用いてatomicに行われる。 +競合している書き込み中に自分の書き込みが成功した場合に関数commit()が成功する。 +失敗した場合ははじめからもう一度行う。

+ +

JavaのモジュールにはAtomicRefarenceが存在した。 +C#では自分で作る必要があった。

+ +

+// C\#  
+public bool CompareAndSet(T newValue, T prevValue) {
+    T oldValue = value;
+    return (oldValue 
+        != Interlocked.CompareExchange 
+                  (ref value, newValue, prevValue));
+}
+
+
+ + +
+
+ +

Listの実装

+ +

木やリストをたどる時にJavaではIteratorを用いる。 +Iteratorは次の値があるかを返すboolean hasNext()と、Tという型の次の値を取ってくるT next()を持つObjectである。 +C#では木やリストを辿りながらyeildで次の値を返す。 +Javaでは以下のように実装されている。

+ +

+public Iterator<T> iterator() {
+  return new Iterator<T>() {
+    Node<T> currentNode = head.getNext();
+
+    @Override
+    public boolean hasNext() {
+      return currentNode.getAttribute() 
+                                    != null;
+    }
+
+    @Override
+    public T next() {
+      T attribute 
+            = currentNode.getAttribute();
+      currentNode 
+            = currentNode.getNext();
+      return attribute;
+    }
+  };
+}
+
+
+ + +
+
+ +

Listの実装

+ +

C#ではそもそも匿名クラスの中でメソッドを定義できない。 +この場合はIEnuratorを使って書き直すことができた。

+ +

+// C\#
+public IEnumerator<T> iterator() {
+  Node<T> currentNode = head.getNext();
+  while (currentNode.getAttribute() != null) {
+    yield return (T)currentNode.getAttribute();
+    currentNode = currentNode.getNext ();
+  }
+}
+
+
+ + +
+
+ +

Eitherのチェック

+ +

Haskellでは例外処理はモナド内部で行う設計になっている。 +Eitherもその一つである。

+ +

Jungleではある処理に対してエラーであればA、 +なければBをEitherに包んで返す。

+ +

JavaのJungleでは分岐を使ってチェックする必要があった。

+ +

+// Java
+Either<Error,TreeNode> either = children.at(2);
+if (either.isA()) 
+    return either.a();
+TreeNode child = either.b();
+
+
+ + +
+
+ +

bindの実装

+ +

Eitherクラスに実装したbindは自身のEitherをチェックした後、 +エラーがなければ関数fを実行し評価する仕組みである。

+ +

+public Either<A, B> bind (System.Func<B, Either<A, B>> f) {
+    if (this.isA ()) {
+      return this;
+    }
+    return f (this.b ());
+}
+
+
+ +

ユーザー側でのエラーのチェックは不要になるが、関数fのLambda式を自分で定義する必要がある。 +次のページにその例を示す。

+ + +
+
+ +

bindの引数に渡すラムダ式の例

+ +

+Either<Error, JungleTreeEditor> either = DefaultEither<Error, JungleTreeEditor>.newB(editor);
+Item apple = new Item("Apple");
+
+either = either.bind ((JungleTreeEditor arg) => {
+	return arg.putAttribute (rootNode, item.name, item);
+});
+
+
+ + +
+
+ +

例題のゲーム

+ +

前章ではJungle-Sharpのどのように実装したかを述べた。

+ +

この章では実際にゲームを構築し、そのデータベースとしてJungleを導入する。

+ +

今回作ったゲームはMinecraftの簡易版である。

+ +
+ message +
+ +

プレイヤーは自由にマップを移動し、ステージの破壊や、生成を行うことができる。

+ +

破壊や生成のオペレーションに合わせてJungleのノードにも同期する。

+ + +
+
+ +

ゲームデータの種類

+ +

ゲームのデータにはいくつかの種類が考えられる。

+ +

オブジェクトが単体で持つデータ

+ +

シーン内に存在するオブジェクトが持つパラメータ。

+ +

例えば、プレイヤーのHPや経験値、位置座標などを示す。

+ +

オブジェクト1つで複数持つデータ

+ +

プレイヤーが持つアイテムデータなどを示す。

+ +

マスタデータ(ReadOnly)

+ +

アイテムの名前や敵の出現確率などを示す。

+ +

ゲーム開発者のみが更新できる。

+ + +
+
+ +

データのデータ設計

+ +

Jungleには複数の木を持つことができる。

+ +

ゲームのシーンを構成するGameTreeとアイテムを管理するItemTreeをJungle内に作る。

+ + +
+
+ +

GameTree

+ +

GameTreeではシーン内にあるPlayerやStageを構成するCubeなどを格納している。 +Jungleではオブジェクトが単体で持つデータと、オブジェクト一つで複数持つデータを同時に表現できる。 +以下にその例を示す。

+ +
+ message +
+ + +
+
+ +

ItemTree

+ +

ItemTreeではItemデータを格納している。 +データの種類ではマスターデータにあたいする。 +以下にその例を示す。

+ +
+ message +
+ + +
+
+ +

Jungleの改良

+ +

前章では例題となるゲームを作成した。 +その上でJungleではデータ型について問題となった。

+ +

C#の再実装を行った際にJavaのJungleに沿ってデータの型、つまりByteArrayで設計を行っていた。

+ +

データの格納を行うたびにByte Arrayへのキャストを行う必要がある。 +しかし、キャストの処理は軽くはない。

+ +

そこで、シーンを構成するObjectをそのまま格納するに仕様を変更した。 +C#ではObjectクラスのエイリアスとしてobject型が使える。

+ +

+Player player = new Player ();
+either = either.bind ((JungleTreeEditor arg) => {
+  return arg.putAttribute ("Player", player);
+});
+
+Enemy enemy = new Enemy ();
+either = either.bind ((JungleTreeEditor arg) => {
+  return arg.putAttribute ("Enemy", enemy);
+});
+
+
+ + +
+
+ +

データを取り出す

+ +

データを取り出すにはGenericで型を指定する、もしくはas演算子を用いてキャストを行う。 +以下に取り出す例を記述する。

+ +
Player player = attr.get<Player> ("Player");
+Enemy enemy = attr.get ("Enemy") as Enemy;
+
+ +

データの型の再設計を行ったことによりシーン内のオブジェクトをそのまま格納が可能になった。 +格納の際にByte Arrayに変換する必要がない。

+ +

分散構造や、ネットワークで必要な時だけ変換する。

+ + +
+
+ +

まとめ

+ +

本研究の流れは

+ +
    +
  • Jungle-Sharpの実装
  • +
  • UnityでのApplicationの実装
  • +
  • 問題点の改良
  • +
+ +

となった。

+ +

Jungle-Sharpの実装ではそれほど難しくはなかった。 +C#版のJungleではJavaに劣らない、もしくはそれ以上のパフォーマンスを出すことが出来た。

+ +

実際のゲームに合わせたJungleの拡張を行った。

+ +

データの格納の際にByteBufferであったものをObject型に変更した。 +これにより、シーンを構成するObjectデータを手間なく格納することを可能にした。

+ +

Jungleは非破壊であるため、過去の変更を持っている。

+ +

ゲームにおいて過去の木を持ち続けることはパフォーマンスの低下につながる。 +そのため、過去の木をどこまで必要かを検討しなければならない。

+ +

現在C#版のJungleにはデータを永続化させる仕組みは備わっていない。 +実用的なゲームのデータベースとして使うためには永続化を実装する必要がある。

+ +
+ + +
+ +