TOP > HSP #module 考察
HSP #module 考察
HSP の #module機能をオブジェクト指向的観点から見てまとめた備忘録
[2015/10/24〜2015/11/4]
#moduleを使うと少しオフジェクト指向っぽい記述が出来るようなので、自分なりにまとめてみた。
困ったことに、HSPでの用語がややこしい(モジュール変数とモジュール型変数(?)とか)ので、一部をオフジェクト指向言語で用いる表現に変えている。これが余計に混乱を引き起こすかもしれないのは一応認識しているが、どう解決したものか。
※コードのタブサイズは4です。HSPエディタにコピペして実行できます。
考察 その1
何も出来ない原始的なモジュール
;-----------------------------------------------------------------------------
; #module 考察 その1
;
; #module
; #global
;
; (C) 2015 @taigoooo
;-----------------------------------------------------------------------------
;--------------------------------------
; モジュール
;--------------------------------------
#module Zahyo x, y ; #module モジュール名 Zahyo, モジュール変数 x, y
; モジュール名と、モジュール変数の宣言
#global ; #globalで閉じるのは決まりごと。
;-------- -- -------- -- -------- -- -------- -- -------- -- --------
; モジュールは、JavaやC++などのクラスに近い感じの機能。
; 上記のコードはJavaだと
; class Zahyo {
; private int x;
; private int y;
; }
; に近い。
; モジュール変数の宣言には型を書かない(変数名だけ)のところが違う。
;-------- -- -------- -- -------- -- -------- -- -------- -- --------
;--------------------------------------
; メイン
;--------------------------------------
newmod objZahyo, Zahyo ; newmod オブジェクト名 objZahyo, モジュール名 Zahyo
;-------- -- -------- -- -------- -- -------- -- -------- -- --------
; これで Zahyoオブジェクトが生成され、objZahyo に参照が入る。
; ただし、モジュール変数(xとy)へのアクセス方法が無いので
; このままでは何もできない。
;-------- -- -------- -- -------- -- -------- -- -------- -- --------
; 上記のコードは Java だと
; Zahyo objZahyo = new Zahyo();
; に近い。
;-------- -- -------- -- -------- -- -------- -- -------- -- --------
考察 その2
コンストラクタを付加してみる
;-----------------------------------------------------------------------------
; #module 考察 その2
;
; #module
; #modinit
; #global
;
; (C) 2015 @taigoooo
;-----------------------------------------------------------------------------
;--------------------------------------
; モジュール
;--------------------------------------
#module Zahyo x, y
#modinit int p_x, int p_y ; #modinit 引数,...
; コンストラクタの宣言。newmodで呼ばれる。
x = p_x ; コンストラクの内容。この例ではモジュール変数への書き込みをする。
y = p_y
return
#global
;-------- -- -------- -- -------- -- -------- -- --------
; 上記のコードはJavaだと
; class Zahyo {
; private int x;
; private int y;
; Zahyo(int p_x, int p_y) {
; x = p_x;
; y = p_y;
; }
; }
; に近い。
;-------- -- -------- -- -------- -- -------- -- --------
;--------------------------------------
; メイン
;--------------------------------------
newmod objZahyo, Zahyo, 14, 86 ; newmod オブジェクト名 objZAahyo, モジュール名 Zahyo, コンストラクへの引数,...
;-------- -- -------- -- -------- -- -------- -- -------- -- --------
; コンストラクタへ14, 86 を渡しており、
; それが objZahyoオブジェクトのモジュール変数(xとy)に入ることになる。
; しかし、あいかわらずモジュール変数(xとy)へのアクセス方法が無く
; 読み出せない。
;-------- -- -------- -- -------- -- -------- -- -------- -- --------
; 上記のコードは Java だと
; Zahyo objZahyo = new Zahyo(14, 86);
; に近い。
;-------- -- -------- -- -------- -- -------- -- -------- -- --------
考察 その3
ゲッター(x)を付加してみる
;-----------------------------------------------------------------------------
; #module 考察 その3
;
; #module
; #modinit
; #modcfunc
; #global
;
; (C) 2015 @taigoooo
;-----------------------------------------------------------------------------
;--------------------------------------
; モジュール
;--------------------------------------
#module Zahyo x, y
#modinit int p_x, int p_y
x = p_x
y = p_y
return
#modcfunc local getX ; #modcfunc local 命令名, 引数,...
return x ; いわゆるゲッターを例にした。ここではモジュール変数(x)を返している。
#global
;-------- -- -------- -- -------- -- -------- -- --------
; 上記のコードはJavaだと
; class Zahyo {
; private int x;
; private int y;
; Zahyo(int p_x, int p_y) {
; x = p_x;
; y = p_y;
; }
; private int getX() {
; return x;
; }
; }
; に近い。
;-------- -- -------- -- -------- -- -------- -- --------
; #modcfunc getX ではなく、 #modcfunc local getX と
; しているのがミソ。local を外すとグローバル扱いとなり、
; 結果、命令名の衝突に頭を悩ませないといけなくなる。
; これを local としておくことで、命令名の名前衝突を回避できる。
; 呼び出し側では 命令名@モジュール名 と記述して呼び出す。
; もし、local を付けなかったら、命令名衝突回避のため、
; getX_Zahyo のような命名をする羽目になり、それであれば
; はじめから getX@Zahyo としておいた方が良いと考える。
;-------- -- -------- -- -------- -- -------- -- --------
; #modcfunc は、値を返す処理には使っても良いが、
; 値を返さないものに使ってはいけない。返さない場合は
; #modfunc を使うこと。
;-------- -- -------- -- -------- -- -------- -- --------
;--------------------------------------
; メイン
;--------------------------------------
newmod objZahyo, Zahyo, 14, 86
x = getX@Zahyo(objZahyo) ; 命令名@モジュール名(オブジェクト名, 引数,...)
mes x ; これは確認のための表示。14が表示される。
;-------- -- -------- -- -------- -- -------- -- -------- -- --------
; objZahyoオブジェクトのモジュール変数(x)の読み出しを行っている。
;-------- -- -------- -- -------- -- -------- -- -------- -- --------
; 上記のコードは Java だと
; Zahyo objZahyo = new Zahyo(14, 86);
; x = objZahyo.getX();
; System.out.println(x);
; に近い。
;-------- -- -------- -- -------- -- -------- -- -------- -- --------
考察 その4-1
セッター(x)を付加してみる
;-----------------------------------------------------------------------------
; #module 考察 その4-1
;
; #module
; #modinit
; #modfunc
; #modcfunc
; #global
;
; (C) 2015 @taigoooo
;-----------------------------------------------------------------------------
;--------------------------------------
; モジュール
;--------------------------------------
#module Zahyo x, y
#modinit int p_x, int p_y
x = p_x
y = p_y
return
#modfunc local setX int p_x ; #modfunc local 命令名, 引数,...
x = p_x ; いわゆるセッターを例にした。ここではモジュール変数(x)へのセットを行っている。
return
#modcfunc local getX
return x
#global
;-------- -- -------- -- -------- -- -------- -- --------
; 上記のコードはJavaだと
; class Zahyo {
; private int x;
; private int y;
; Zahyo(int p_x, int p_y) {
; x = p_x;
; y = p_y;
; }
; private void setX(int p_x) {
; x = p_x;
; }
; private int getX() {
; return x;
; }
; }
; に近い。
;-------- -- -------- -- -------- -- -------- -- --------
; #modcfunc は、値を返す処理には使っても良いが、
; 値を返さないものに使ってはいけない。返さない場合は
; #modfunc を使うこと。
;-------- -- -------- -- -------- -- -------- -- --------
;--------------------------------------
; メイン
;--------------------------------------
newmod objZahyo, Zahyo, 14, 86
x = getX@Zahyo(objZahyo)
mes x
mes "--------------------"
setX@Zahyo objZahyo, 20 ; 命令名@モジュール名 オブジェクト名, 引数,...
; ここではモジュール変数(x)に20を書き込んでいる。
x = getX@Zahyo(objZahyo) ; 変更されているかどうか確認。20が表示される。
mes x
;-------- -- -------- -- -------- -- -------- -- -------- -- --------
; objZahyoオブジェクトのモジュール変数(x)の読み出しを行っている。
;-------- -- -------- -- -------- -- -------- -- -------- -- --------
; 上記のコードは Java だと
; Zahyo objZahyo = new Zahyo(14, 86);
; x = objZahyo.getX();
; System.out.println(x);
; System.out.println("--------------------");
; objZahyo.setX(20);
; x = objZahyo.getX();
; System.out.println(x);
; に近い。
;-------- -- -------- -- -------- -- -------- -- -------- -- --------
考察 その4-2
ゲッター/セッター(y)を付加してみる
;-----------------------------------------------------------------------------
; #module 考察 その4-2
;
; #module
; #modinit
; #modfunc
; #modcfunc
; #global
;
; (C) 2015 @taigoooo
;-----------------------------------------------------------------------------
;--------------------------------------
; モジュール
;--------------------------------------
#module Zahyo x, y
#modinit int p_x, int p_y
x = p_x
y = p_y
return
#modfunc local setX int p_x
x = p_x
return
#modfunc local setY int p_y ; モジュール変数(y)についてもx同様に作ってみる。
y = p_y
return
#modcfunc local getX
return x
#modcfunc local getY ; モジュール変数(y)についてもx同様に作ってみる。
return y
#global
;-------- -- -------- -- -------- -- -------- -- --------
; 上記のコードはJavaだと
; class Zahyo {
; private int x;
; private int y;
; Zahyo(int p_x, int p_y) {
; x = p_x;
; y = p_y;
; }
; private void setX(int p_x) {
; x = p_x;
; }
; private void setY(int p_y) {
; y = p_y;
; }
; private int getX() {
; return x;
; }
; private int getY() {
; return y;
; }
; }
; に近い。
;-------- -- -------- -- -------- -- -------- -- --------
;--------------------------------------
; メイン
;--------------------------------------
newmod objZahyo, Zahyo, 14, 86
x = getX@Zahyo(objZahyo)
y = getY@Zahyo(objZahyo) ; yを読み出す。
mes "x = "+x+", y = "+y
mes "--------------------"
setX@Zahyo objZahyo, 20
setY@Zahyo objZahyo, 75 ; yをセットする。
x = getX@Zahyo(objZahyo)
y = getY@Zahyo(objZahyo) ; yを読み出す。
mes "x = "+x+", y = "+y
;-------- -- -------- -- -------- -- -------- -- -------- -- --------
; objZahyoオブジェクトのモジュール変数(y)の読み書きも行っている。
;-------- -- -------- -- -------- -- -------- -- -------- -- --------
; 上記のコードは Java だと
; Zahyo objZahyo = new Zahyo(14, 86);
; x = objZahyo.getX();
; y = objZahyo.getY();
; System.out.println("x = "+x+", y = "+y);
; System.out.println("--------------------");
; objZahyo.setX(20);
; objZahyo.setY(75);
; x = objZahyo.getX();
; y = objZahyo.getY();
; System.out.println("x = "+x+", y = "+y);
; に近い。
;-------- -- -------- -- -------- -- -------- -- -------- -- --------
考察 その5
コンストラクターでの直接の変数操作をやめてセッターを呼び出すようにしてみる
;-----------------------------------------------------------------------------
; #module 考察 その5
;
; #module
; #modinit
; thismod
; #modfunc
; #modcfunc
; #global
;
; (C) 2015 @taigoooo
;-----------------------------------------------------------------------------
;--------------------------------------
; モジュール
;--------------------------------------
#module Zahyo x, y
#modinit int p_x, int p_y
setX thismod, p_x ; 初期化をセッターにまかせる
; setXを呼び出すときにはオブジェクトを渡す必要があり、それは自分自身なので、thismodを使う。
setY thismod, p_y ; 初期化をセッターにまかせる
return
#modfunc local setX int p_x
x = p_x
return
#modfunc local setY int p_y
y = p_y
return
#modcfunc local getX
return x
#modcfunc local getY
return y
#global
;-------- -- -------- -- -------- -- -------- -- --------
; 上記のコードはJavaだと
; class Zahyo {
; private int x;
; private int y;
; Zahyo(int p_x, int p_y) {
; setX(p_x);
; setY(p_y);
; }
; private void setX(int p_x) {
; x = p_x;
; }
; private void setY(int p_y) {
; y = p_y;
; }
; private int getX() {
; return x;
; }
; private int getY() {
; return y;
; }
; }
; に近い。
;-------- -- -------- -- -------- -- -------- -- --------
;--------------------------------------
; メイン
;--------------------------------------
newmod objZahyo, Zahyo, 14, 86
x = getX@Zahyo(objZahyo)
y = getY@Zahyo(objZahyo)
mes "x = "+x+", y = "+y
mes "--------------------"
setX@Zahyo objZahyo, 20
setY@Zahyo objZahyo, 75
x = getX@Zahyo(objZahyo)
y = getY@Zahyo(objZahyo)
mes "x = "+x+", y = "+y
;-------- -- -------- -- -------- -- -------- -- -------- -- --------
; 考察 その4-2から変更無し
;-------- -- -------- -- -------- -- -------- -- -------- -- --------
考察 その6
複数のオブジェクトを生成してみる
;-----------------------------------------------------------------------------
; #module 考察 その6
;
; #module
; #modinit
; thismod
; #modfunc
; #modcfunc
; #global
; 複数のオブジェクト利用
;
; (C) 2015 @taigoooo
;-----------------------------------------------------------------------------
;--------------------------------------
; モジュール
;--------------------------------------
#module Zahyo x, y
#modinit int p_x, int p_y
setX thismod, p_x
setY thismod, p_y
return
#modfunc local setX int p_x
x = p_x
return
#modfunc local setY int p_y
y = p_y
return
#modcfunc local getX
return x
#modcfunc local getY
return y
#global
;-------- -- -------- -- -------- -- -------- -- --------
; 考察 その5から変更無し
;-------- -- -------- -- -------- -- -------- -- --------
;--------------------------------------
; メイン
;--------------------------------------
newmod objZahyo, Zahyo, 14, 86
newmod objZahyo, Zahyo, 52, 45 ; 同じオブジェクト名で、2度目以降のnewmodは、
newmod objZahyo, Zahyo, 66, 93 ; オブジェクト変数は自動的に配列変数となり、
; この場合はそれぞれ、objZahyo(0), objZahyo(1), objZahyo(2) となる。
foreach objZahyo ; 全てのオフジェクトをなめる場合は foreach 〜 loop が便利。
x = getX@Zahyo(objZahyo(cnt)) ; オブジェクトは配列となるので「objZahyo(数値)」で渡すことになる。
y = getY@Zahyo(objZahyo(cnt))
mes "x = "+x+", y = "+y
loop
mes "--------------------"
setX@Zahyo objZahyo(1), 20 ; 複数あるオブジェクトの内一つの値を変えてみる
setY@Zahyo objZahyo(1), 75 ; 複数あるオブジェクトの内一つの値を変えてみる
foreach objZahyo ; 確認のための表示
x = getX@Zahyo(objZahyo(cnt))
y = getY@Zahyo(objZahyo(cnt))
mes "x = "+x+", y = "+y
loop
;-------- -- -------- -- -------- -- -------- -- -------- -- --------
; 上記のコードは Java だと
; Zahyo objZahyo[3];
; objZahyo[0] = new Zahyo(14, 86);
; objZahyo[1] = new Zahyo(52, 45);
; objZahyo[2] = new Zahyo(66, 93);
; for (cnt = 0; cnt < 3; cnt++) {
; x = objZahyo[cnt].getX();
; y = objZahyo[cnt].getY();
; System.out.println("x = "+x+", y = "+y);
; }
; System.out.println("--------------------");
; objZahyo[1].setX(20);
; objZahyo[1].setY(75);
; for (cnt = 0; cnt < 3; cnt++) {
; x = objZahyo[cnt].getX();
; y = objZahyo[cnt].getY();
; System.out.println("x = "+x+", y = "+y);
; }
; に近い。
;-------- -- -------- -- -------- -- -------- -- -------- -- --------
考察 その7
オブジェクトの破棄をしてみる
;-----------------------------------------------------------------------------
; #module 考察 その7
;
; #module
; #modinit
; thismod
; #modfunc
; #modcfunc
; #global
; 複数のオブジェクト利用
; オブジェクトの破棄
;
; (C) 2015 @taigoooo
;-----------------------------------------------------------------------------
;--------------------------------------
; モジュール
;--------------------------------------
#module Zahyo x, y
#modinit int p_x, int p_y
setX thismod, p_x
setY thismod, p_y
return
#modfunc local setX int p_x
x = p_x
return
#modfunc local setY int p_y
y = p_y
return
#modcfunc local getX
return x
#modcfunc local getY
return y
#global
;-------- -- -------- -- -------- -- -------- -- --------
; 考察 その5から変更無し
;-------- -- -------- -- -------- -- -------- -- --------
;--------------------------------------
; メイン
;--------------------------------------
newmod objZahyo, Zahyo, 14, 86
newmod objZahyo, Zahyo, 52, 45
newmod objZahyo, Zahyo, 66, 93
foreach objZahyo
x = getX@Zahyo(objZahyo(cnt))
y = getY@Zahyo(objZahyo(cnt))
mes "index = "+cnt+", x = "+x+", y = "+y
loop
mes "--------------------"
delmod objZahyo(1) ; delmod オブジェクト名
; オブジェクトを破棄する
foreach objZahyo ; 確認のための表示
; foreach 〜 loop では、破棄されたオブジェクトは自動的にスキップされる
x = getX@Zahyo(objZahyo(cnt))
y = getY@Zahyo(objZahyo(cnt))
mes "index = "+cnt+", x = "+x+", y = "+y
loop
;-------- -- -------- -- -------- -- -------- -- -------- -- --------
; 上記のコードは Java だと
; Zahyo objZahyo[3];
; objZahyo[0] = new Zahyo(14, 86);
; objZahyo[1] = new Zahyo(52, 45);
; objZahyo[2] = new Zahyo(66, 93);
; for (cnt = 0; cnt < 3; cnt++) {
; x = objZahyo[cnt].getX();
; y = objZahyo[cnt].getY();
; System.out.println("x = "+x+", y = "+y);
; }
; System.out.println("--------------------");
; objZahyo[1] = null; // Javaでは、C++で言うdeleteに相当する明示的な破棄は無い
; for (cnt = 0; cnt < 3; cnt++) {
; if (objZahyo[cnt] == null) : continue
; x = objZahyo[cnt].getX();
; y = objZahyo[cnt].getY();
; System.out.println("x = "+x+", y = "+y);
; }
; に近い。
;-------- -- -------- -- -------- -- -------- -- -------- -- --------
考察 その8-1
オブジェクトをモジュール変数として持つモジュールを作ってみる
;-----------------------------------------------------------------------------
; #module 考察 その8-1
;
; #module
; #modinit
; thismod
; #modfunc
; #modcfunc
; #global
; オブジェクトルをモジュール変数として持つモジュール
;
; (C) 2015 @taigoooo
;-----------------------------------------------------------------------------
;--------------------------------------
; モジュール Zahyo
;--------------------------------------
#module Zahyo x, y
#modinit int p_x, int p_y
setX thismod, p_x
setY thismod, p_y
return
#modfunc local setX int p_x
x = p_x
return
#modfunc local setY int p_y
y = p_y
return
#modcfunc local getX
return x
#modcfunc local getY
return y
#global
;-------- -- -------- -- -------- -- -------- -- --------
; 考察 その5から変更無し
;-------- -- -------- -- -------- -- -------- -- --------
;--------------------------------------
; モジュール Setsuzoku
; 使い方(メイン側から呼び出す方法):
; newmod オブジェクト名, Setsuzoku, 起点X, 起点Y, 接続モード ; 起点(x,y)と接続モード(modeが0なら終点と起点を結ばない。0以外なら結ぶ)を引数にしてオブジェクトを生成する
; addXY@Setsuzoku オブジェクト名, 接続点X, 接続点Y ; 接続点を追加する。任意の数繰り返す
; writeLine@Setsuzoku オブジェクト名 ; 線を引く
; setMode@Setsuzoku オブジェクト名, 接続モード ; モードのセッター。モードを変更するときに使用する。
;--------------------------------------
#module Setsuzoku xy, mode ; このモジュールは、Zahyoオブジェクトをモジュール変数(xy)として持つ。
; 通常のモジュール変数(mode)も持つ。
#modinit int p_x, int p_y, int p_mode ; コンストラクタ
newmod xy, Zahyo, p_x, p_y ; Zahyoオブジェクトを生成し、モジュール変数(xy)へ入れる。Zahyoモジュールのコンストラクタに引数を渡す。
setMode thismod, p_mode ; modeをセッターで設定する。
return
#modfunc local setMode int p_mode ; modeのセッター
mode = p_mode
return
#modfunc local addXY int p_x, int p_y ; 接続点を増やす
newmod xy, Zahyo, p_x, p_y ; Zahyoオブジェクトを追加する。
return
#modfunc local writeLine ; 線を描く
pos getX@Zahyo(xy(0)), getY@Zahyo(xy(0)) ; 起点座標を指定
; (0を起点と決め打ちする方法は「xyオブジェクトは一部たりとも破棄されない」ことを前提としている)
foreach xy ; xyオブジェクトの数だけ繰り返す
line getX@Zahyo(xy(cnt)), getY@Zahyo(xy(cnt)) ; 線を引く
loop
if (mode != 0) { ; 起点と結ぶなら
line getX@Zahyo(xy(0)), getY@Zahyo(xy(0)) ; 線を引く
}
return
#global
;--------------------------------------
; メイン
;--------------------------------------
newmod objSetsuzoku, Setsuzoku, 44, 40, 1 ; 起点とモード(終端接続する)の指定
addXY@Setsuzoku objSetsuzoku, 390, 97 ; 接続点の追加
addXY@Setsuzoku objSetsuzoku, 584, 300 ; 接続点の追加
addXY@Setsuzoku objSetsuzoku, 332, 406 ; 接続点の追加
addXY@Setsuzoku objSetsuzoku, 104, 260 ; 接続点の追加.... いくつでも追加できる
writeLine@Setsuzoku objSetsuzoku ; 線の描画
dialog "次に、一旦画面を消去し、モードを変えて線を描きます"
cls
setMode@Setsuzoku objSetsuzoku, 0 ; モード変更(終端接続しない)
writeLine@Setsuzoku objSetsuzoku ; 線の描画
考察 その8-2
なんちゃって継承(継承機能は無いのでラッパー作ってそれっぽくする)
すぐに破綻しそう。元のモジュールコピペして作った方がいいかもしれない。
;-----------------------------------------------------------------------------
; #module 考察 その8-2
;
; #module
; #modinit
; thismod
; #modfunc
; #modcfunc
; #global
; オブジェクトをモジュール変数として持つモジュール
; なんちゃって継承(継承機能は無いのでラッパー作ってそれっぽくする)
;
; (C) 2015 @taigoooo
;-----------------------------------------------------------------------------
;--------------------------------------
; モジュール Zahyo
;--------------------------------------
#module Zahyo x, y
#modinit int p_x, int p_y
setX thismod, p_x
setY thismod, p_y
return
#modfunc local setX int p_x
x = p_x
return
#modfunc local setY int p_y
y = p_y
return
#modcfunc local getX
return x
#modcfunc local getY
return y
#global
;-------- -- -------- -- -------- -- -------- -- --------
; 考察 その5から変更無し
;-------- -- -------- -- -------- -- -------- -- --------
;--------------------------------------
; モジュール Setsuzoku
;--------------------------------------
#module Setsuzoku xy, mode
#modinit int p_x, int p_y, int p_mode
newmod xy, Zahyo, p_x, p_y
setMode thismod, p_mode
return
#modfunc local setMode int p_mode
mode = p_mode
return
#modcfunc local getMode ; modeを返す
return mode
#modcfunc local getX int p_cnt ; Xを返す
return getX@Zahyo(xy(p_cnt))
#modcfunc local getY int p_cnt ; Yを返す
return getY@Zahyo(xy(p_cnt))
#modcfunc local getObjN ; オブジェクト配列数を返す
return length(xy) ; このように親モジュールに手を入れなければならないので、なんちゃって継承はかなり危うい。
#modfunc local addXY int p_x, int p_y
newmod xy, Zahyo, p_x, p_y
return
#modfunc local writeLine
pos getX(0), getY(0) ; ゲッターに書き換え
foreach xy
line getX(cnt), getY(cnt) ; ゲッターに書き換え
loop
if (mode != 0) {
line getX(0), getY(0) ; ゲッターに書き換え
}
return
#global
;--------------------------------------
; モジュール SetsuzokuOffset
; 使い方(メイン側から呼び出す方法):
; newmod オブジェクト名, SetsuzokuOffset, 起点X, 起点Y, 接続モード, オフセットX, オフセットY ; 起点(x,y)と接続モード(modeが0なら終点と起点を結ばない。0以外なら結ぶ)とオフセット(xo,yo)を引数にしてオブジェクトを生成する
; addXY@SetsuzokuOffset オブジェクト名, 接続点X, 接続点Y ; 接続点を追加する。任意の数繰り返す
; writeLine@SetsuzokuOffset オブジェクト名 ; 線を引く
; setMode@SetsuzokuOffset オブジェクト名, 接続モード ; モードのセッター。モードを変更するときに使用する。
; setOffsetX@SetsuzokuOffset オブジェクト名, オフセットX ; オフセットXのセッター。オフセットを変更するときに使用する。
; setOffsetY@SetsuzokuOffset オブジェクト名, オフセットY ; オフセットYのセッター。オフセットを変更するときに使用する。
;--------------------------------------
#module SetsuzokuOffset xym, oxy ; このモジュールは、Setsuzokuオブジェクトをモジュール変数(xym)とし、また、Zahyoオブジェクトをモジュール変数(oxy)として持つ。
#modinit int p_x, int p_y, int p_mode, int p_ox, int p_oy ; コンストラクタ
newmod xym, Setsuzoku, p_x, p_y, p_mode ; Setsuzokuオブジェクトを生成し、モジュール変数(xym)へ入れる。Setsuzokuモジュールのコンストラクタに引数を渡す。
newmod oxy, Zahyo, p_ox, p_oy ; Zahyoオブジェクトを生成し、モジュール変数(oxy)へ入れる。Zahyoモジュールのコンストラクタに引数を渡す。
return
#modfunc local setMode int p_mode ; modeのセッター
setMode@Setsuzoku xym, p_mode ; Setsuzokuモジュールのmodeセッターを呼び出してセットする。
return
#modfunc local setOffsetX int p_ox ; オフセットXのセッター
setX@Zahyo oxy, p_ox ; ZahyoモジュールのXセッターを呼び出してセットする。
return
#modfunc local setOffsetY int p_oy ; オフセットYのセッター
setY@Zahyo oxy, p_oy ; ZahyoモジュールのYセッターを呼び出してセットする。
return
#modfunc local addXY int p_x, int p_y ; 接続点を増やす
addXY@Setsuzoku xym, p_x, p_y ; SetsuzokuモジュールのaddXYを呼び出して追加する。
return
#modfunc local writeLine ; 線を描く
ox = getX@Zahyo(oxy) ; オフセット値Xを得る。oxはワーク変数で、Javaで言うところのメンバー変数 static int ox; に近い。モジュール変数以外の変数はモジュール内で共有される(モジュール内グローバル)
oy = getY@Zahyo(oxy) ; オフセット値Yを得る。oyも同様。
pos ox + getX@Setsuzoku(xym, 0), oy + getY@Setsuzoku(xym, 0) ; 起点座標を指定
; (0を起点と決め打ちする方法は「xyオブジェクトは一部たりとも破棄されない」ことを前提としている)
repeat getObjN@Setsuzoku(xym) ; xyオブジェクトの数だけ繰り返す
line ox + getX@Setsuzoku(xym, cnt), oy + getY@Setsuzoku(xym, cnt) ; 線を引く
loop
if (getMode@Setsuzoku(xym) != 0) { ; 起点と結ぶなら
line ox + getX@Setsuzoku(xym, 0), oy + getY@Setsuzoku(xym, 0) ; 線を引く
}
return
#global
;--------------------------------------
; メイン
;--------------------------------------
newmod objSetsuzokuOffset, SetsuzokuOffset, 44, 40, 1, 20, 10 ; 起点とモード(終端接続する)、オフセットの指定
addXY@SetsuzokuOffset objSetsuzokuOffset, 390, 97 ; 接続点の追加
addXY@SetsuzokuOffset objSetsuzokuOffset, 584, 300 ; 接続点の追加
addXY@SetsuzokuOffset objSetsuzokuOffset, 332, 406 ; 接続点の追加
addXY@SetsuzokuOffset objSetsuzokuOffset, 104, 260 ; 接続点の追加.... いくつでも追加できる
writeLine@SetsuzokuOffset objSetsuzokuOffset ; 線の描画
color 255,0,0
setOffsetX@SetsuzokuOffset objSetsuzokuOffset, -20 ; オフセットX変更
setOffsetY@SetsuzokuOffset objSetsuzokuOffset, 60 ; オフセットY変更
setMode@SetsuzokuOffset objSetsuzokuOffset, 0 ; モード変更(終端接続しない)
writeLine@SetsuzokuOffset objSetsuzokuOffset ; 線の描画
考察 その9-1
デストラクタを付けてみる
C++ではnewで生成したオブジェクトはdeleteで解放するのがお作法。HSPでも#modtermでデストラクタを書ける。
;-----------------------------------------------------------------------------
; #module 考察 その9-1
;
; #module
; #modinit
; #modterm
; thismod
; #modfunc
; #modcfunc
; #global
; オブジェクトをモジュール変数として持つモジュール
;
; (C) 2015 @taigoooo
;-----------------------------------------------------------------------------
;--------------------------------------
; モジュール Zahyo
;--------------------------------------
#module Zahyo x, y
#modinit int p_x, int p_y
setX thismod, p_x
setY thismod, p_y
return
#modterm ; デストラクタ
mes "デストラクタ(Zahyo)" ; 確認のための表示
return
#modfunc local setX int p_x
x = p_x
return
#modfunc local setY int p_y
y = p_y
return
#modcfunc local getX
return x
#modcfunc local getY
return y
#global
;-------- -- -------- -- -------- -- -------- -- --------
; デストラクタを追加。Javaにはデストラクタが無いので
; 書きようが無い。(近い機能はあるがデストラクタではない)
;-------- -- -------- -- -------- -- -------- -- --------
;--------------------------------------
; モジュール Setsuzoku
;--------------------------------------
#module Setsuzoku xy, mode
#modinit int p_x, int p_y, int p_mode
newmod xy, Zahyo, p_x, p_y
setMode thismod, p_mode
return
#modterm ; デストラクタ
mes "デストラクタENTER(Setsuzoku)" ; 確認のための表示
foreach xy ; 全ての子モジュールを解放
delmod xy(cnt)
loop
mes "デストラクタEXIT(Setsuzoku)" ; 確認のための表示
return
#modfunc local setMode int p_mode
mode = p_mode
return
#modfunc local addXY int p_x, int p_y
newmod xy, Zahyo, p_x, p_y
return
#modfunc local writeLine
pos getX@Zahyo(xy(0)), getY@Zahyo(xy(0))
foreach xy
line getX@Zahyo(xy(cnt)), getY@Zahyo(xy(cnt))
loop
if (mode != 0) {
line getX@Zahyo(xy(0)), getY@Zahyo(xy(0))
}
return
#global
;--------------------------------------
; メイン
;--------------------------------------
newmod objSetsuzoku, Setsuzoku, 44, 40, 1
addXY@Setsuzoku objSetsuzoku, 390, 97
addXY@Setsuzoku objSetsuzoku, 584, 300
addXY@Setsuzoku objSetsuzoku, 332, 406
addXY@Setsuzoku objSetsuzoku, 104, 260
writeLine@Setsuzoku objSetsuzoku
delmod objSetsuzoku ; オブジェクト解放
;-------- -- -------- -- -------- -- -------- -- --------
; Setsuzokuオブジェクトのデストラクタ
; ↓
; Zahyoオブジェクトのデストラク
; の順で呼ばれる
; 普通はこのように、順を追って解放するコードを書くべき。
;-------- -- -------- -- -------- -- -------- -- --------
考察 その9-2
子オブジェクトの解放をしなかったらどうなるかやってみたが、HSPが自動で解放しているようだ。
;-----------------------------------------------------------------------------
; #module 考察 その9-2
;
; #module
; #modinit
; #modterm
; thismod
; #modfunc
; #modcfunc
; #global
; オブジェクトをモジュール変数として持つモジュール
;
; (C) 2015 @taigoooo
;-----------------------------------------------------------------------------
;--------------------------------------
; モジュール Zahyo
;--------------------------------------
#module Zahyo x, y
#modinit int p_x, int p_y
setX thismod, p_x
setY thismod, p_y
return
#modterm
mes "デストラクタ(Zahyo)"
return
#modfunc local setX int p_x
x = p_x
return
#modfunc local setY int p_y
y = p_y
return
#modcfunc local getX
return x
#modcfunc local getY
return y
#global
;-------- -- -------- -- -------- -- -------- -- --------
; 考察 その9-1から変更無し
;-------- -- -------- -- -------- -- -------- -- --------
;--------------------------------------
; モジュール Setsuzoku
;--------------------------------------
#module Setsuzoku xy, mode
#modinit int p_x, int p_y, int p_mode
newmod xy, Zahyo, p_x, p_y
setMode thismod, p_mode
return
#modterm
mes "デストラクタENTER(Setsuzoku)"
;; foreach xy ; コメントアウトしてみる。
;; delmod xy(cnt) ; 子オブジェクトを明示的に解放しなくても、HSPが面倒見てくれるようだ。
;; loop
mes "デストラクタEXIT(Setsuzoku)"
return
#modfunc local setMode int p_mode
mode = p_mode
return
#modfunc local addXY int p_x, int p_y
newmod xy, Zahyo, p_x, p_y
return
#modfunc local writeLine
pos getX@Zahyo(xy(0)), getY@Zahyo(xy(0))
foreach xy
line getX@Zahyo(xy(cnt)), getY@Zahyo(xy(cnt))
loop
if (mode != 0) {
line getX@Zahyo(xy(0)), getY@Zahyo(xy(0))
}
return
#global
;--------------------------------------
; メイン
;--------------------------------------
newmod objSetsuzoku, Setsuzoku, 44, 40, 1
addXY@Setsuzoku objSetsuzoku, 390, 97
addXY@Setsuzoku objSetsuzoku, 584, 300
addXY@Setsuzoku objSetsuzoku, 332, 406
addXY@Setsuzoku objSetsuzoku, 104, 260
writeLine@Setsuzoku objSetsuzoku
delmod objSetsuzoku ; オブジェクト解放
;-------- -- -------- -- -------- -- -------- -- --------
; Setsuzokuオブジェクトのデストラクタ
; ↓
; Zahyoオブジェクトのデストラク
; の順で呼ばれる
; 普通はこのように、順を追って解放するコードを書くべき。
; であるが、HSPが面倒を見てくれるようだ。
;-------- -- -------- -- -------- -- -------- -- --------
考察 その10
あるオブジェクトに対し異なるオブジェクトのメソッドを呼び出してみる
JavaやC++では普通やらない(というか出来ない)ことをやってみた。
あるモジュールに対して、全く無関係なモジュールのメソッドを呼び出してみると、それなりに動く。
メソッドは、モジュール変数名は見ておらず、モジュール変数の宣言された順番で、変数にアクセスしているようだ。
;-----------------------------------------------------------------------------
; #module 考察 その10
;
; #module
; #modinit
; thismod
; #modfunc
; #modcfunc
; #global
; あるオブジェクトに対し異なるオブジェクトのメソッドを呼び出してみる
;
; (C) 2015 @taigoooo
;-----------------------------------------------------------------------------
;--------------------------------------
; モジュール Zahyo
;--------------------------------------
#module Zahyo x, y
#modinit int p_x, int p_y
setX thismod, p_x
setY thismod, p_y
return
#modfunc local setX int p_x
x = p_x
return
#modfunc local setY int p_y
y = p_y
return
#modcfunc local getX
return x
#modcfunc local getY
return y
#global
;-------- -- -------- -- -------- -- -------- -- --------
; 考察 その5から変更無し
;-------- -- -------- -- -------- -- -------- -- --------
;--------------------------------------
; モジュール Calc
;--------------------------------------
#module Calc a, b
#modinit int p_a, int p_b
setA thismod, p_a
setB thismod, p_b
return
#modfunc local setA int p_a
a = p_a
return
#modfunc local setB int p_b
b = p_b
return
#modcfunc local getA
return a
#modcfunc local getB
return b
#modcfunc local subAB
return a-b
#global
;-------- -- -------- -- -------- -- -------- -- --------
; module Zahyo ほぼそのままに、メソッド subAB を加えた。
;-------- -- -------- -- -------- -- -------- -- --------
;--------------------------------------
; メイン
;--------------------------------------
newmod objZahyo, Zahyo, 14, 33 ; Zahyo オブジェクト生成
x = getX@Zahyo(objZahyo)
y = getY@Zahyo(objZahyo)
mes "x = "+x+", y = "+y
mes "--------------------"
newmod objCalc, Calc, 71, 25 ; Calc オブジェクト生成
a = getA@Calc(objCalc)
b = getB@Calc(objCalc)
c = subAB@Calc(objCalc) ; subAB メソッド呼び出し
mes "a = "+a+", b = "+b+", c(subABメソッド結果) = "+c
mes "--------------------"
z = subAB@Calc(objZahyo) ; Zahyo オブジェクトに無理やり subAB メソッド呼び出し
mes "x = "+x+", y = "+y+", z(subABメソッド結果) = "+z
mes "--------------------"
;-------- -- -------- -- -------- -- -------- -- -------- -- --------
; HSPは 「メソッド(オブジェクト, 引数)」なので、呼び出すメソッドと
; 引き渡すオブジェクトをどうにでも組み合わせることが出来る。
; もちろん本来的にはオブジェクトとメソッドとは同じモジュールにて
; 生成/定義されたものを用いるべきではあるが。
; なお、JavaやC++では、「オブジェクト.メソッド(引数);」で呼び出すが、
; オブジェクトが具備していないメソッドは呼べないので上記のような齟齬は
; 発生しない。
;-------- -- -------- -- -------- -- -------- -- -------- -- --------
考察 その11-1
Javaで言うところのstaticなメンバ変数を使ってみる
オブジェクト毎固有に持つモジュール変数ではなく、共有の変数を使用する。
;-----------------------------------------------------------------------------
; #module 考察 その11-1
;
; #module
; #modinit
; thismod
; #modfunc
; #modcfunc
; #global
; スタティックなメンバー変数
;
; (C) 2015 @taigoooo
;-----------------------------------------------------------------------------
;--------------------------------------
; モジュール Zahyo
;--------------------------------------
#module Zahyo x, y
#modinit int p_x, int p_y
setX thismod, p_x
setY thismod, p_y
return
#modfunc local setX int p_x
x = p_x
if (maxX < x) : maxX = x ; モジュール変数でない変数maxXに代入。
; maxXの初期値は0なので、xがマイナスを扱う場合は工夫が必要となる。
return
#modfunc local setY int p_y
y = p_y
if (maxY < y) : maxY = y ; maxXに同様。
return
#modcfunc local getX
return x
#modcfunc local getY
return y
#global
;-------- -- -------- -- -------- -- -------- -- --------
; 上記のコードはJavaだと
; class Zahyo {
; static int maxX; // HSPでは宣言が無い。Javaだと初期値無し宣言では0になるのでHSPと結果は同じ。
; static int maxY; // maxXに同様
; private int x;
; private int y;
; Zahyo(int p_x, int p_y) {
; setX(p_x);
; setY(p_y);
; }
; private void setX(int p_x) {
; x = p_x;
; if (maxX < x) : maxX = x;
; return
; }
; private void setY(int p_y) {
; y = p_y;
; if (maxY < y) : maxY = y;
; return
; }
; private int getX() {
; return x;
; }
; private int getY() {
; return y;
; }
; }
; に近い。
;-------- -- -------- -- -------- -- -------- -- --------
;--------------------------------------
; メイン
;--------------------------------------
newmod objZahyo, Zahyo, 14, 33 ; Zahyo オブジェクト生成
x = getX@Zahyo(objZahyo)
y = getY@Zahyo(objZahyo)
maxX = maxX@Zahyo ; staticなメンバ変数はオブジェクトを介さずに直接読み出せる
maxY = maxY@Zahyo ; staticなメンバ変数はオブジェクトを介さずに直接読み出せる
mes "x = "+x+", y = "+y+", maxX = "+maxX+", maxY = "+maxY
mes "--------------------"
newmod objZahyo, Zahyo, 6, 57 ; Zahyo オブジェクト生成
newmod objZahyo, Zahyo, 75, 26 ; Zahyo オブジェクト生成
foreach objZahyo
x = getX@Zahyo(objZahyo(cnt))
y = getY@Zahyo(objZahyo(cnt))
maxX = maxX@Zahyo ; staticなメンバ変数はオブジェクトを介さずに直接読み出せる
maxY = maxY@Zahyo ; staticなメンバ変数はオブジェクトを介さずに直接読み出せる
mes "("+cnt+") : x = "+x+", y = "+y+", maxX = "+maxX+", maxY = "+maxY
mes "--------------------"
loop
;-------- -- -------- -- -------- -- -------- -- -------- -- --------
; x,y は、オブジェクト固有、maxX, maxY はオブジェクト共有の値が
; 返ってくる。
;-------- -- -------- -- -------- -- -------- -- -------- -- --------
考察 その11-2
Javaで言うところのstaticなメンバ変数の初期化をしてみる
オブジェクトを初めて生成した時点で自動的にstaticはメンバ変数を初期化するようにしてみる。
暗黙的に初期化されるので、使用者は余計なことを気にせず便利。
;-----------------------------------------------------------------------------
; #module 考察 その11-2
;
; #module
; #modinit
; thismod
; #modfunc
; #modcfunc
; #global
; スタティックなメンバー変数
;
; (C) 2015 @taigoooo
;-----------------------------------------------------------------------------
;--------------------------------------
; モジュール Zahyo
;--------------------------------------
#module Zahyo x, y
#modinit int p_x, int p_y
if (doneInit == 0) { ; まだ初期化してない(一度もオブジェクトを生成していない)なら
maxX = p_x ; maxX, maxY を初期化する
maxY = p_y
doneInit = 1 ; 初期化済みにする
}
setX thismod, p_x
setY thismod, p_y
return
#modfunc local setX int p_x
x = p_x
if (maxX < x) : maxX = p_x
return
#modfunc local setY int p_y
y = p_y
if (maxY < y) : maxY = p_y
return
#modcfunc local getX
return x
#modcfunc local getY
return y
#global
;-------- -- -------- -- -------- -- -------- -- --------
; 上記のコードはJavaだと
; class Zahyo {
; static int maxX;
; static int maxY;
; static boolean doneInit; // 初期値無し宣言ではfalseとなる。
; private int x;
; private int y;
; Zahyo(int p_x, int p_y) {
; if (!doneInit) {
; maxX = x;
; maxY = y;
; doneInit = true;
; }
; setX(p_x);
; setY(p_y);
; return
; }
; private void setX(int p_x) {
; x = p_x;
; if (maxX < x) : maxX = x;
; return
; }
; private void setY(int p_y) {
; y = p_y;
; if (maxY < y) : maxY = y;
; return
; }
; private int getX() {
; return x;
; }
; private int getY() {
; return y;
; }
; }
; に近い。
;-------- -- -------- -- -------- -- -------- -- --------
;--------------------------------------
; メイン
;--------------------------------------
newmod objZahyo, Zahyo, -55, -60 ; Zahyo オブジェクト生成(ここでモジュール内のmaxXとmaxYが初期化される)
x = getX@Zahyo(objZahyo)
y = getY@Zahyo(objZahyo)
maxX = maxX@Zahyo
maxY = maxY@Zahyo
mes "x = "+x+", y = "+y+", maxX = "+maxX+", maxY = "+maxY
mes "--------------------"
newmod objZahyo, Zahyo, -92, -30 ; Zahyo オブジェクト生成(ここでは初期化されない)
newmod objZahyo, Zahyo, -8, -47 ; Zahyo オブジェクト生成(ここでは初期化されない)
foreach objZahyo
x = getX@Zahyo(objZahyo(cnt))
y = getY@Zahyo(objZahyo(cnt))
maxX = maxX@Zahyo
maxY = maxY@Zahyo
mes "("+cnt+") : x = "+x+", y = "+y+", maxX = "+maxX+", maxY = "+maxY
mes "--------------------"
loop
;-------- -- -------- -- -------- -- -------- -- -------- -- --------
; x,y は、オブジェクト固有、maxX, maxY はオブジェクト共有の値が
; 返ってくる。
;-------- -- -------- -- -------- -- -------- -- -------- -- --------
考察 その11-3
Javaで言うところのstaticなメンバ変数を明示的に初期化してみる
考察11-2は暗黙的に初期化されて便利だが、パフォーマンス的にはあまりよろしくない。
また、明示的に初期化したい場合もあるだろうから、ケースバイケースで選択するのが良いと考える。
;-----------------------------------------------------------------------------
; #module 考察 その11-3
;
; #module
; #deffunc
; #modinit
; thismod
; #modfunc
; #modcfunc
; #global
; スタティックなメンバー変数
;
; (C) 2015 @taigoooo
;-----------------------------------------------------------------------------
;--------------------------------------
; モジュール Zahyo
;--------------------------------------
#module Zahyo x, y
#deffunc local init int p_x, int p_y ; staticメンバー変数初期化用命令を用意しておく。#modfunc ではなく #deffunc であることに注意。
maxX = p_x ; maxX, maxY を初期化する。
maxY = p_y
return
#modinit int p_x, int p_y
;; if (doneInit == 0) { ; オブジェクトが生成される度に判断処理していたものがしなくてよくなる。
;; maxX = p_x
;; maxY = p_y
;; doneInit = 1
;; }
setX thismod, p_x
setY thismod, p_y
return
#modfunc local setX int p_x
x = p_x
if (maxX < x) : maxX = p_x
return
#modfunc local setY int p_y
y = p_y
if (maxY < y) : maxY = p_y
return
#modcfunc local getX
return x
#modcfunc local getY
return y
#global
;-------- -- -------- -- -------- -- -------- -- --------
; 上記のコードはJavaだと
; class Zahyo {
; static int maxX;
; static int maxY;
; static boolean doneInit; // 初期値無し宣言ではfalseとなる。
; private int x;
; private int y;
; private static void init(int p_x, int p_y) { // static変数初期化メソッド
; manX = p_x;
; manY = p_y;
; return
; }
; Zahyo(int p_x, int p_y) {
; // if (!doneInit) {
; // maxX = x;
; // maxY = y;
; // doneInit = true;
; // }
; setX(p_x);
; setY(p_y);
; return
; }
; private void setX(int p_x) {
; x = p_x;
; if (maxX < x) : maxX = x;
; return
; }
; private void setY(int p_y) {
; y = p_y;
; if (maxY < y) : maxY = y;
; return
; }
; private int getX() {
; return x;
; }
; private int getY() {
; return y;
; }
; }
; に近い。
;-------- -- -------- -- -------- -- -------- -- --------
;--------------------------------------
; メイン
;--------------------------------------
init@Zahyo -2147483647, -2147483647 ; 整数の最小値で初期化(もちろん↓の-55と-60でも正しく動作する)
newmod objZahyo, Zahyo, -55, -60 ; Zahyo オブジェクト生成(ここでは初期化されない)
x = getX@Zahyo(objZahyo)
y = getY@Zahyo(objZahyo)
maxX = maxX@Zahyo
maxY = maxY@Zahyo
mes "x = "+x+", y = "+y+", maxX = "+maxX+", maxY = "+maxY
mes "--------------------"
newmod objZahyo, Zahyo, -92, -30
newmod objZahyo, Zahyo, -8, -47
foreach objZahyo
x = getX@Zahyo(objZahyo(cnt))
y = getY@Zahyo(objZahyo(cnt))
maxX = maxX@Zahyo
maxY = maxY@Zahyo
mes "("+cnt+") : x = "+x+", y = "+y+", maxX = "+maxX+", maxY = "+maxY
mes "--------------------"
loop
;-------- -- -------- -- -------- -- -------- -- -------- -- --------
; x,y は、オブジェクト固有、maxX, maxY はオブジェクト共有の値が
; 返ってくる。
;-------- -- -------- -- -------- -- -------- -- -------- -- --------
考察 その11-4
staticなメンバ変数にもゲッター/セッターを使用する
考察11-3までは直接的に代入/参照していたが、これをゲッター/セッターを使うように書き換えてみた。
正直めんどうくさいが、セッター/ゲッターに機能を持たせるなら、この方法が良いかもしれない。
;-----------------------------------------------------------------------------
; #module 考察 その11-4
;
; #module
; #deffunc
; #modinit
; thismod
; #modfunc
; #modcfunc
; #global
; スタティックなメンバー変数
;
; (C) 2015 @taigoooo
;-----------------------------------------------------------------------------
;--------------------------------------
; モジュール Zahyo
;--------------------------------------
#module Zahyo x, y
#deffunc local init int p_x, int p_y
newmod dummy, Zahyo, p_x, p_y ; maxX, maxYにセッターを使ってアクセスするためにダミーのオブジェクトを生成
setMaxX dummy, p_x ; maxX, maxY を初期化するにあたり、セッターを使用
setMaxY dummy, p_y ; セッター使用
delmod dummy ; 要らなくなったので解放する。
return
#modinit int p_x, int p_y
setX thismod, p_x
setY thismod, p_y
return
#modfunc local setX int p_x
x = p_x
if (maxX < x) : setMaxX thismod, p_x ; セッター使用
return
#modfunc local setY int p_y
y = p_y
if (maxY < y) : setMaxY thismod, p_y ; セッター使用
return
#modfunc local setMaxX int p_x ; maxXセッター
maxX = p_x
return
#modfunc local setMaxY int p_y ; maxYセッター
maxY = p_y
return
#modcfunc local getX
return x
#modcfunc local getY
return y
#modcfunc local getMaxX ; maxXゲッター
return maxX
#modcfunc local getMaxY ; maxYゲッター
return maxY
#global
;-------- -- -------- -- -------- -- -------- -- --------
; 上記のコードはJavaだと
; class Zahyo {
; static int maxX;
; static int maxY;
; private int x;
; private int y;
; private static void init(int p_x, int p_y) {
; setMaxX(p_x);
; setMaxY(p_y);
; return
; }
; Zahyo(int p_x, int p_y) {
; setX(p_x);
; setY(p_y);
; return
; }
; private void setX(int p_x) {
; x = p_x;
; if (maxX < x) : maxX = x;
; return
; }
; private void setY(int p_y) {
; y = p_y;
; if (maxY < y) : maxY = y;
; return
; }
; private void setMaxX(int p_x) {
; maxX = p_x;
; return
; }
; private void setMaxY(int p_y) {
; maxY = p_y;
; return
; }
; private int getX() {
; return x;
; }
; private int getY() {
; return y;
; }
; private int getMaxX() {
; return maxX;
; }
; private int getMaxY() {
; return maxY;
; }
; }
; に近い。
;-------- -- -------- -- -------- -- -------- -- --------
;--------------------------------------
; メイン
;--------------------------------------
init@Zahyo -2147483647, -2147483647
newmod objZahyo, Zahyo, -55, -60
x = getX@Zahyo(objZahyo)
y = getY@Zahyo(objZahyo)
maxX = getMaxX@Zahyo(objZahyo) ; ゲッターを使用
maxY = getMaxY@Zahyo(objZahyo) ; ゲッターを使用
mes "x = "+x+", y = "+y+", maxX = "+maxX+", maxY = "+maxY
mes "--------------------"
newmod objZahyo, Zahyo, -92, -30
newmod objZahyo, Zahyo, -8, -47
foreach objZahyo
x = getX@Zahyo(objZahyo(cnt))
y = getY@Zahyo(objZahyo(cnt))
maxX = getMaxX@Zahyo(objZahyo(cnt)) ; ゲッターを使用
maxY = getMaxY@Zahyo(objZahyo(cnt)) ; ゲッターを使用
mes "("+cnt+") : x = "+x+", y = "+y+", maxX = "+maxX+", maxY = "+maxY
mes "--------------------"
loop
;-------- -- -------- -- -------- -- -------- -- -------- -- --------
; 正直、面倒くさいし、オブジェクト固有の変数にアクセスしたいのか、
; 共有の変数にアクセスしたいのか見分けがつかない。
; maxX = maxX@Zahyo でアクセスする方が手軽で良いように考える。
; 一方、ゲッター/セッターに機能を持たせるならば、この考察の方法も
; 検討する価値はある。
;-------- -- -------- -- -------- -- -------- -- -------- -- --------
考察 その12-1
オブジェクトを代入してみる
newmod で生成したオブジェクトを、他の変数へ代入してみる。
単純な代入では、参照が代入されるだけ。
;-----------------------------------------------------------------------------
; #module 考察 その12-1
;
; #module
; #modinit
; #modfunc
; #modcfunc
; #global
; オブジェクトの代入
;
; (C) 2015 @taigoooo
;-----------------------------------------------------------------------------
;--------------------------------------
; モジュール
;--------------------------------------
#module Zahyo x, y
#modinit int p_x, int p_y
setX thismod, p_x
setY thismod, p_y
return
#modfunc local setX int p_x
x = p_x
return
#modfunc local setY int p_y
y = p_y
return
#modcfunc local getX
return x
#modcfunc local getY
return y
#global
;-------- -- -------- -- -------- -- -------- -- --------
; 考察 その5から変更無し
;-------- -- -------- -- -------- -- -------- -- --------
;--------------------------------------
; メイン
;--------------------------------------
newmod objZahyo, Zahyo, 14, 86 ; オブジェクト生成
x = getX@Zahyo(objZahyo)
y = getY@Zahyo(objZahyo)
mes "objZahyo : x = "+x+", y = "+y
mes "--------------------"
altObjZahyo = objZahyo ; オブジェクトの代入
setX@Zahyo altObjZahyo, 20 ; 代入先オブジェクトでsetX を発行。モジュール変数 x に 20 が書かれる。
x = getX@Zahyo(altObjZahyo) ; 変更されているかどうか確認。20が表示される。
y = getY@Zahyo(altObjZahyo)
mes "altObjZahyo : x = "+x+", y = "+y
mes "--------------------"
x = getX@Zahyo(objZahyo) ; 代入元のオブジェクトの x を確認。20が表示される。
y = getY@Zahyo(objZahyo)
mes "objZahyo : x = "+x+", y = "+y
;-------- -- -------- -- -------- -- -------- -- -------- -- --------
; 代入は、オブジェクトへの「参照」が代入されるだけであって、
; オブジェクトのメンバ変数の「値」がごっそり代入されるわけではない。
; Javaでも事情は同じで、参照だけが代入される。
;-------- -- -------- -- -------- -- -------- -- -------- -- --------
考察 その12-2
オブジェクトのクローンを作ってみる
参照の代入ではなく、同じオブジェクトをまるまるもう一個作ってみる。
(この考察でやっかいなことに気付いたのでそれは考察12-3に回す)
;-----------------------------------------------------------------------------
; #module 考察 その12-2
;
; #module
; #modinit
; #modfunc
; #modcfunc
; #global
; オブジェクトのクローン
;
; (C) 2015 @taigoooo
;-----------------------------------------------------------------------------
;--------------------------------------
; モジュール
;--------------------------------------
#module Zahyo x, y
#modinit int p_x, int p_y
setX thismod, p_x
setY thismod, p_y
return
#modfunc local clone var p_module ; クローン用メソッド
p_module = 0 ; p_module が既にオブジェクト変数だった場合、newmod にて配列として追加されてしまう。それを防ぐために数値0の代入を行い、オブジェクト変数ではなくしている。
newmod p_module, Zahyo, x, y ; このモジュールは newmod 時に全てのモジュール変数に値を引き渡せるが、
; some code ; 場合によっては、set***(p_module, ***) 等を使って、さらに値を書き込まなければならない。
return
#modfunc local setX int p_x
x = p_x
return
#modfunc local setY int p_y
y = p_y
return
#modcfunc local getX
return x
#modcfunc local getY
return y
#global
;-------- -- -------- -- -------- -- -------- -- --------
; クローンするコードは自分で書かないといけない。
; 値の直接参照ではなくゲッター/セッターを使用する際は、
; 副作用が有るかどうかを確認するなど注意を必要とする。
;-------- -- -------- -- -------- -- -------- -- --------
;--------------------------------------
; メイン
;--------------------------------------
newmod objZahyo, Zahyo, 14, 86 ; オブジェクト生成
x = getX@Zahyo(objZahyo)
y = getY@Zahyo(objZahyo)
mes "objZahyo : x = "+x+", y ="+y
mes "--------------------"
clone@Zahyo objZahyo, altObjZahyo ; オブジェクトのクローン
setX@Zahyo altObjZahyo, 20 ; クローン先オブジェクト setX を発行。モジュール変数 x に 20 が書かれる。
x = getX@Zahyo(altObjZahyo) ; 変更されているかどうか確認。20が表示される。
y = getY@Zahyo(altObjZahyo)
mes "altObjZahyo : x = "+x+", y ="+y
mes "--------------------"
x = getX@Zahyo(objZahyo) ; クローン元のオブジェクトの x を確認。元の14が表示される。
y = getY@Zahyo(objZahyo)
mes "objZahyo : x = "+x+", y ="+y
;-------- -- -------- -- -------- -- -------- -- -------- -- --------
; クローンは実行負荷がかかるので、参照で済ませられないかどうかを
; プログラム設計時に検討すべきである。
;-------- -- -------- -- -------- -- -------- -- -------- -- --------
考察 その12-3
オブジェクト参照が複数の状態で破棄してみる
Javaでは参照者が一人でもいればガベージコレクションの対象にはならない。
しかし、HSPでは、オリジナルの参照が破棄されると、他に参照者がいたとしても、デストラクタが実行される。
Java感覚で、参照をリレーする(オリジナル参照は放棄する)ようなプログラム構造は危険。
;-----------------------------------------------------------------------------
; #module 考察 その12-3
;
; #module
; #modinit
; #modfunc
; #modcfunc
; #global
; オブジェクトの代入と解放
;
; (C) 2015 @taigoooo
;-----------------------------------------------------------------------------
;--------------------------------------
; モジュール
;--------------------------------------
#module Zahyo x, y
#modinit int p_x, int p_y
setX thismod, p_x
setY thismod, p_y
return
#modterm ; デストラクタ
mes "TERM" ; 確認のメッセージ
return
#modfunc local setX int p_x
x = p_x
return
#modfunc local setY int p_y
y = p_y
return
#modcfunc local getX
return x
#modcfunc local getY
return y
#global
;-------- -- -------- -- -------- -- -------- -- --------
; 解放タイミングを確認するためにデストラクタを追加
;-------- -- -------- -- -------- -- -------- -- --------
;--------------------------------------
; メイン
;--------------------------------------
mes "オブジェクトのオリジナル側を破棄します"
newmod objZahyo, Zahyo, 14, 86 ; オブジェクト生成
altObjZahyo = objZahyo ; オブジェクト代入。参照者が二人(objZahyo, altObjZahyo)になる。
objZahyo = 0 ; 元オブジェクトの参照を破棄。Javaではまだ参照者(altObjZahyo)がいるので、ガベージコレクションの対象にならない。
; しかし、HSPではデストラクタが起動される。
mes "次はオブジェクトの代入側を破棄します"
newmod objZahyo, Zahyo, 14, 86 ; オブジェクト生成
altObjZahyo = objZahyo ; オブジェクト代入。参照者が二人(objZahyo, altObjZahyo)になる。
altObjZahyo = 0 ; 代入側を破棄。こちらを破棄してもデストラクタは呼ばれない。
;-------- -- -------- -- -------- -- -------- -- -------- -- --------
; HSPのデストラクタは、newmod で生成されたオブジェクト参照が
; 破棄されたときに呼び出させる。たとえ、他の参照者がいたとしても
; 解放されるので、(Javaのように)生存を期待して参照をリレーするような
; プログラム構造にするのは危険。
;-------- -- -------- -- -------- -- -------- -- -------- -- --------
Copyright © 2015 @taigoooo