今っさら〜な感じですが、SATTO さんのスクリプトを、
パラメータなし #modterm で実装してみました。
これなら暗示的な破棄も可能です!!
基本的な考えは、全 chara モジュールが共有する map のアドレスを
あらかじめ charaInit で取得しておく事で、chara 破棄時に map 情報を
パラメータとして受け取らなくて済むようにしようというものに基づいています。
あと、PVAL 構造体などの HSP システム自体の仕組みを知らないと
コード化できない部分が気持ち悪かったので、
標準で用意されている varptr, dupptr で代用してみました。
これでも十分気持ち悪いけれど…。
#const VAR_TYPE_INT 4
#const VAR_TYPE_MODULE 5
#module chara x_, y_
#defcfunc _charaGetMapAddress int x, int y
return map_ + 4 * (x + length_ * y)
#deffunc _charaWriteMyAddressToMap int x, int y, int addr, local p
dupptr p, _charaGetMapAddress(x,y), 4, VAR_TYPE_INT@
p = addr
return
#deffunc charaInit array map
map_ = varptr(map)
length_ = length(map)
; dupptr では配列を復元出来ないので、
; アドレス算出可能な様に配列サイズを記録しておく
return
#modinit int x, int y
x_ = x
y_ = y
_charaWriteMyAddressToMap x, y, varptr(thismod)
return
#modterm
_charaWriteMyAddressToMap x_, y_, 0
return
#modfunc charaTest
mes "座標 (" + x_ + "," + y_ + ") のキャラクタ"
return
#global
#module aux
#deffunc auxShowMap array map, int pos_x, int pos_y, str text
pos pos_x, pos_y
mes text
y = 0: gy = pos_y + ginfo_mesy
repeat length2(map)
x = 0: gx = pos_x
repeat length(map)
pos gx, gy
mes strf("%8x",map(x,y))
x++
gx += ginfo_mesx + 10
loop
y++
gy += ginfo_mesy
loop
return
#deffunc auxGetChara var p, int addr
dupptr p, addr, 16, VAR_TYPE_MODULE@
return
#global
; ----
; ここからテスト...
; ----
font msgothic, 12, 16
; マップ生成
dim map, 5, 5
auxShowMap map, 0, 0, "初期状態"
; キャラクタ生成
charaInit map ; マップと全キャラクタを関連付け
dimtype x, VAR_TYPE_MODULE, 3 ; あらかじめ最大使用数分のメモリ領域を確保して置かないと、
newmod x, chara, 2, 1 ; 配列の伸張によるメモリ再確保が起きて map に書き込んだ
newmod x, chara, 4, 4 ; アドレスが無効になってしまう!!
newmod x, chara, 1, 3 ; その点で言えば、アドレスより index を記録した方が無難だが…。
auxShowMap map, 0, 100, "キャラクタ生成"
; キャラクタのアドレス情報を表示
pos 400, 0
mes "キャラクタ・アドレス"
foreach x
mes "x(" + cnt + ") = " + strf("%8x",varptr(x(cnt)))
loop
; マップに格納されたキャラクタアドレスからキャラクタを復元できるかテスト
auxGetChara p, map(4,4) ; アドレスからキャラクタを復元
charaTest p ; 動作テスト
; キャラクタ破棄
delmod x(0)
delmod x(1)
;delmod x(2)
auxShowMap map, 0, 200, "キャラクタ破棄"
; ここでは、x(2) を明示的に破棄していない。
; HSP アプリケーション終了時に起きる暗示的な破棄によって破棄させてみる。
; 終了時にエラーが出ないなら、暗示的な破棄も正常に終了した事に。
stop
今回の事を通してみて、HSP でポインタ使ったり、モジュール同士を関連付けたり
っていうのは労力の割りにリターンが少ないなと改めて痛感しました。
私は素直に配列、モジュール(単体)、gosub でやってこうと思います。