|
|
2024/1/8(Mon) 13:49:39|NO.100991
モジュール変数がどのモジュール空間に属しているかをスクリプト内で判定する方法はありますか?
#module mod_a storage
#modinit int u_a
storage = u_a
return
#global
#module mod_b storage
#modinit double u_a
storage = u_a
return
#global
newmod A, mod_a storage, 1
stop
例えば上記のような場合、Aがどのモジュール空間に属しているかスクリプト内で判定する方法はあるのでしょうか?
|
|
2024/1/8(Mon) 13:52:02|NO.100992
例文を間違えたので修正します。
正しくは、以下の例文です。
#module mod_a storage
#modinit int u_a
storage = u_a
return
#global
#module mod_b storage
#modinit double u_a
storage = u_a
return
#global
newmod A, mod_a, 1
stop
|
|
2024/1/8(Mon) 15:24:26|NO.100993
こんにちわ
modinitで文字列でモジュールの名前を返してみました。
こういう意味ですか?
※違うモジュールを一つの変数に入れてもエラーにはならないようだが、なにか面白い使い道はないだろうか。。
モジュールのタイプを別の配列に持っていれば、全モジュールを一つのモジュール型配列で管理、、する意味はあんまりないかな?
#module mod_a storage
#modinit int u_a
storage = u_a
return "mod_A"
#global
#module mod_b storage
#modinit double u_a
storage = u_a
return "mod_B"
#global
dimtype mods,5
newmod mods, mod_a, 1
a=refstr
newmod mods, mod_b, 2
b=refstr
newmod mods, mod_a, 3
c=refstr
mes a
mes b
mes c
stop
<pre/>
|
|
2024/1/8(Mon) 16:51:02|NO.100994
>buhioさん
アドバイスありがとうございます。
やっぱりモジュール変数そのものから、何かモジュール空間のIDのようなものを調べる方法はない感じなんでしょうか?
buhioさんのアドバイスとやり方は同じなのですが、modinitのreturnから値を返すやり方として以下のようなやり方を元々は考えてはいました。
;モジュール空間のIDのようなものを仮想的に作って返す
;以下、モジュール空間仮想ID一覧
#enum global MOD_A_ID = 1
#enum global MOD_B_ID
#module mod_a storage
#modinit int u_a
storage = u_a
return MOD_A_ID
#modcfunc a_get
return storage
;異なるモジュール変数の中身を合計する
;u_0 = モジュール変数(mod_a)
;u_id0 = u_0のモジュール空間仮想ID
;u_1 = モジュール変数(mod_a)
;u_id1 = u_1のモジュール空間仮想ID
#defcfunc a_sum var u_0, int u_id0, var u_1, int u_id1
;モジュール空間仮想IDが異なる場合はエラーにする
if u_id0 ! MOD_A_ID : dialog "error",1 : end
if u_id1 ! MOD_A_ID : dialog "error",1 : end
return a_get(u_0) + a_get(u_1)
#global
#module mod_b storage
#modinit int u_b
storage = u_b
return MOD_B_ID
#global
;仮にモジュール変数のモジュール空間が不明なケースとして、rndを挟んでいるケースを想定する
;以下は、*_mod_idにモジュール空間仮想IDを代入している
sw = rnd(2)
if sw == 0 {
newmod A, mod_a, 1 : A_mod_id = stat
newmod B, mod_a, 1 : B_mod_id = stat
}
if sw == 1 {
newmod A, mod_b, 1 : A_mod_id = stat
newmod B, mod_b, 1 : B_mod_id = stat
}
;この間に様々な処理が仮に入るとします
;最終的な処理
if A_mod_id == MOD_A_ID | B_mod_id == MOD_A_Id : mes str(a_sum(A, A_mod_id, B, B_mod_id))
stop
ただ、この方法だと見て分かる通り、単にモジュール変数の中身の値を合計するという単純な計算でさえ、4つも引数を必要としているのが分かると思います。
複雑な計算になっていくとID分だけそのまま増えるわけですから、実際の制作ではこれがもっと膨大な引数になっていくわけです。
何かもっとシンプルに記述できないのかなぁと思った次第なのです。
モジュール変数そのものから、そのモジュール変数の属するモジュール空間が分からないというのが一番のネックになっています。
どのモジュール空間に属しているかがモジュール変数自体から分かれば、このID分の引数が必要なくなるわけですから、かなりシンプルな記述ができるようになるはずだと思いました。
HSPの構造体側でモジュール空間のIDのようなものを持っていそうな感じもするんですけど、よく分かりませんでした。
| |
|
2024/1/8(Mon) 19:24:12|NO.100995
こんにちわ。
hspsdkフォルダのhsp3code.txt, hspdll.txtを参考にすれば分かると思いますよ。
一例ですが、どうぞ。
#module mod_a storage
#modinit int u_a
storage = u_a : return
#global
#module mod_b storage
#modinit double u_a
storage = u_a : return
#global
newmod M, mod_a, 1
newmod M, mod_b, 1
; ★p.1がモジュール変数の番号
foreach M
dupptr p, varptr(M.cnt), 16
mes "M."+cnt+"の中身は"
mes strf("STRUCT ID%d-%d PTR$%p SIZE%d", p.0>>16, p.1, p.3, p.2)
loop
; ★オマケ hspctx構造体の中身を表示
mref hspctx, 68 ; HSP コンテキスト
dupptr _, hspctx.0, 16 : allsize = _.3 ; ヘッダサイズ
dupptr hsphed, hspctx.0, allsize ; HSPオブジェクトファイルヘッダ
dupptr ds, hspctx.3, hsphed.7, 2 ; データセグメント
dupptr fi, hspctx.210, hsphed.15 ; ファンクションインフォ
mes "------------------------------------------"
mes "FINFO (STRUCTDAT)
mes "\tindex\tsubid\tprimidx\tprmmax\tnameidx\tsize\totindex\t"
repeat hsphed.15 / 28 ;STRUCTDAT size(28)
dupptr sdat, varptr(fi)+cnt*28, 28
index = sdat&$FF ; base LIBDAT index
subid = sdat>>16 ; struct index
primindex = sdat.1 ; STRUCTPRM index(MINFO)
prmmax = sdat.2 ; number of STRUCTPRM
nameidx = sdat.3 ; name index (DS)
size = sdat.4 ; struct size (stack)
otindex = sdat.5 ; OT index(Module) / cleanup flag(Dll)
getstr name, ds, nameidx
mes strf("%s\t%d\t%d\t%d\t%d\t%d\t%d\t%d",name,index,subid,primindex,prmmax,nameidx,size,otindex)
loop
mes "------------------------------------------"
| |
|
2024/1/8(Mon) 19:41:28|NO.100996
sシンプルにするとこれです。
#module
#defcfunc getModID var _v
dupptr p, varptr(_v), 8 : return p.1
#global
|
|
2024/1/9(Tue) 01:00:03|NO.100997
と言うわけで、使いやすいようにモジュール化してみました。
目的であるモジュール変数そのものからIDや名前は取得できているかと思います。
よろしかったらどうぞ。
(一応、実行ファイルにしてもDataSegmentから名前は読み取れました。)
私の方が”モジュール変数の中身の合計”という所が理解できておらず、バッチリな回答を書けないのですが、
オブジェクト指向風でいうインターフェース的な事がしたい感じですかね。
(buhioさんのおっしゃる”タイプを別の配列に持っていれば”しか使ったことないのですみません。)
; -----------------------------------------------
; モジュール名取得君 ver 1
;int getModId(var) | モジュール変数のIDを返します。
;int getModName(var) | モジュール変数の名前(小文字)を返します。
;int getModIdByName(str) | モジュール変数の名前(小文字)からIDを返します。
#module
#define SIZE_OF_STRUCTDAT 28
#define guard if vartype(list) = 4 { gosub *L_INIT_LIST }
*L_INIT_LIST
sdim list, 64
mref hspctx, 68 ; HSP Context
dupptr hsphed, hspctx.0, 16
dupptr hsphed, hspctx.0, hsphed.3 ; HSP object file header
dupptr ds, hspctx.3, hsphed.7, 2 ; Data segment
pt_finfo = hspctx.210
max_finfo = hsphed.15
repeat max_finfo / SIZE_OF_STRUCTDAT
pfinfo = pt_finfo + cnt * SIZE_OF_STRUCTDAT
dupptr finfo, pfinfo, SIZE_OF_STRUCTDAT
getstr name, ds, finfo.3
list(finfo.1) = name
loop
return
#defcfunc getModId var _v
dupptr p, varptr(_v), 8 : return p.1
#defcfunc getModIdByName str _s
guard : res = -1
foreach list : if list(cnt) = _s { res = cnt : break } : loop
return res
#defcfunc getModName var _v
guard : return list(getModId(_v))
#global
; -----------------------------------------------
; ↑ここまでおまじないコピペ
; ↓ここからサンプル
#module mod_a storage
#modinit int u_a
storage = u_a : return
#global
#module mod_b storage
#modinit double u_a
storage = u_a : return
#global
; 適当に1つの配列にモジュール変数を突っ込む
newmod M, mod_a, 1 : newmod M, mod_b, 1
newmod M, mod_a, 1 : newmod M, mod_b, 1
; 表示
mes "mod_aのIDは"+getModIdByName("mod_a")
mes "mod_bのIDは"+getModIdByName("mod_b")
foreach M
mes strf("M.%d = %s(%d)", cnt, getModName(M.cnt), getModId(M.cnt))
loop
| |
|
2024/1/9(Tue) 02:01:23|NO.100998
連続投稿ですみません。 例題こういう事ですかねぇ。。。ちょっと自信ないです。
長々と失礼いたしました。
; 上のさっきのモジュールをコピペしておく
; ちょっと裏技的だけど、同じ構造なら関数や値が読み出せる
#define PROT_VAR_ANIMAL name, age
#module animal PROT_VAR_ANIMAL
#modcfunc local getName
return name
#modcfunc local getAge
return age
#defcfunc animal_print var _v
return strf("%s(%d) : %s", getName( _v), getAge(_v), getModName( _v))
#defcfunc animal_sum var _v1, var _v2
if getModId(_v1) != getModId(_v2) : dialog "違う動物!なので合計しない!" : return 0
return getAge(_v1) + getAge(_v2)
#global
; animalと同じ構造のモジュールを2つ用意
#module dog PROT_VAR_ANIMAL
#modinit str _name, int _age
name = _name : age = _age : return
#global
#module cat PROT_VAR_ANIMAL
#modinit str _name, int _age
name = _name : age = _age : return
#global
t = 0 : names = "レオ","ココ","ムギ","ハナ","モモ","モカ","モコ"
*MAIN
title strf("%d回目", t) : cls : dimtype A,5 : dimtype B,5
randomize : sw = rnd(3) : mes "SWは"+sw
if sw == 0 {
newmod A, dog, names(rnd(length(names))), rnd(10)
newmod B, dog, names(rnd(length(names))), rnd(10)
}
if sw == 1 {
newmod A, cat, names(rnd(length(names))), rnd(10)
newmod B, cat, names(rnd(length(names))), rnd(10)
}
if sw == 2 {
newmod A, dog, names(rnd(length(names))), rnd(10)
newmod B, cat, names(rnd(length(names))), rnd(10)
}
; 共通の関数でシンプルに呼び出す。
mes "A = "+animal_print(A)
mes "B = "+animal_print(B)
mes strf("合計%2d才", animal_sum(A,B))
wait 300: t++
goto *MAIN
| |
|
2024/1/9(Tue) 16:20:24|NO.100999
> usagiさん
アドバイスありがとうございます!
教えて頂いた方法でモジュール変数の属するモジュール空間を識別できるようになりました!
このgetModIDとそれに関係する命令群はとても便利だと思いました。
HSPの標準命令としてあってもいいのではないかと思うくらい、モジュール変数を扱う命令を作る上でこれらの命令は役立つと思いました。
今まではNO.100994の方法でモジュール変数のモジュール空間を仮想的に識別するしかなかったので、今回のusagiさんに教えてもらった方法で引数の量を半分にすることができるようになりました。
今回のアドバイスでモジュール変数を扱うスクリプトが大幅に改良できるようになりました。
|
|