HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2024
0108
youdaiモジュール変数がどのモジュール空間に属しているかをスクリプト内で判定する方法はありますか?8解決


youdai

リンク

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がどのモジュール空間に属しているかスクリプト内で判定する方法はあるのでしょうか?



この記事に返信する


youdai

リンク

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



buhio

リンク

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/>



youdai

リンク

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のようなものを持っていそうな感じもするんですけど、よく分かりませんでした。



usagi

リンク

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 "------------------------------------------"



usagi

リンク

2024/1/8(Mon) 19:41:28|NO.100996

sシンプルにするとこれです。

#module #defcfunc getModID var _v dupptr p, varptr(_v), 8 : return p.1 #global



usagi

リンク

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



usagi

リンク

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



youdai

リンク

2024/1/9(Tue) 16:20:24|NO.100999

> usagiさん

アドバイスありがとうございます!
教えて頂いた方法でモジュール変数の属するモジュール空間を識別できるようになりました!
このgetModIDとそれに関係する命令群はとても便利だと思いました。
HSPの標準命令としてあってもいいのではないかと思うくらい、モジュール変数を扱う命令を作る上でこれらの命令は役立つと思いました。
今まではNO.100994の方法でモジュール変数のモジュール空間を仮想的に識別するしかなかったので、今回のusagiさんに教えてもらった方法で引数の量を半分にすることができるようになりました。
今回のアドバイスでモジュール変数を扱うスクリプトが大幅に改良できるようになりました。



記事削除

記事NO.パスワード
(質問が解決したスレッドは他の利用者に活用してもらうため、削除しないようお願いします)

NO.100991への返信

マスコット

好きなマスコットを選んでください。

名前

e-mail
HOME
  1. 初めて利用する方は、HSP3掲示板の使い方をお読みください。
  2. 不要部分の多い長いスクリプトの投稿は ご遠慮ください。
  3. 書き込みは自動改行されません。適度に改行を入れてください。
  4. スクリプトは小文字の<pre>〜</pre>で囲むと見やすく表示できます。

削除用パスワード

解決したら質問者本人がここをチェックしてください。

エラー発生時、再送信すると二重送信になることがあります。
回答が得られたら、お礼書き込み時に[解決]チェックしてください。
SPAM防止のためURLから始まる文章は投稿できません。
SPAM防止のため英文字のみの本文を投稿することはできません。

ONION software Copyright 1997-2023(c) All rights reserved.