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


HSPTV!掲示板


未解決 解決 停止 削除要請

2016
1111
名無しモジュール変数を使ったプレイリスト5解決


名無し

リンク

2016/11/11(Fri) 19:06:53|NO.77306

モジュール変数を使ってプレイリストを作ったのですが、うまくいきません。
どうしてでしょうか

インデックスを使った操作がしたくて、要素を詰める処理を入れています。

#module PlaylistItem \ Filename #modinit str _filename Filename = _filename return #modcfunc PlaylistItem_GetFileName return Filename #global #module Playlist #deffunc Playlist_Add str _filename newmod Item, PlaylistItem, _filename return Playlist_GetLen() - 1 #deffunc Playlist_Delete int _index delmod Item._index Playlist_Reorder return #deffunc Playlist_Reorder local i //無効な要素を除いて詰める repeat length(Item) if (varuse(Item.cnt) > 0) { Item.i = Item.cnt i++ } loop repeat length(Item) - i, i delmod Item.cnt loop return #defcfunc Playlist_GetLen local len repeat length(Item) if (varuse(Item.cnt) == 0) : break len = cnt + 1 loop return len #deffunc Playlist_Get var modvar, int _index modvar = Item._index return #global Playlist_Add "abc.mp3" mes "i: " + stat Playlist_Add "123.wav" mes "i: " + stat Playlist_Delete 0 //インデックス0の要素を削除 Playlist_Add "music.mp3" mes "i: " + stat Playlist_Add "alarm.wav" mes "i: " + stat repeat Playlist_GetLen() //123.wav, music.mp3, alarm.wavとなっているはずなのに Playlist_Get item, cnt mes PlaylistItem_GetFileName(item) loop



この記事に返信する


スペース

リンク

2016/11/11(Fri) 19:38:15|NO.77307

モジュール型変数は殆ど使ったこと無いのですが・・・


#deffunc Playlist_Get var modvar, int _index Dialog varuse(Item._index) modvar = Item._index return
このようにして変数の使用状況を調べてみると、0番目が2、つまり他の変数のクローンになっています。
これは関係ありませんか?



スペース

リンク

2016/11/11(Fri) 19:56:33|NO.77308

以下のスレッドを見ると、やはり=で代入するとクローンになるようです。
http://www.hsp.tv/play//pforum.php?mode=pastwch&num=67250



掘木

リンク

2016/11/11(Fri) 23:01:35|NO.77313

現状のモジュール変数は一体何をどう管理していいのか良く分からなくなることがありますね。
仕様が直感的じゃなさすぎるんよね。

newmodで確保されるモジュール型変数は、その命令の呼び出し時に指定した変数にバインドされます。
その変数を初期化、解放、上書きされると自動的に確保されたモジュール型データは解放されます。
(即時メモリ解放でなくメモリ領域の再利用(解放遅延)のため、アクセス違反が起こらないケースがあります。本ケースのように。)

また、delmodはバインド対象の変数に対して解放と参照クリアの機能であり、
バインドしていない「複製」に対して実行しても、何も起こりません。参照のクリアもできず何かしらの複製の状態のままです。
そして、複製であれば、複製元の生存状況は知ることができません。(ダングリングポインタ(対象解放済み)…なんてよくあること。)

これらの仕様から掲題のコードを見ると、
Playlist_Reorderを実行した時点でデータはすべて解放され、不正な複製がいくつか残ることとなります。
(自己代入すら自分の複製で上書きとなり、解放されます。)


newmodでバインドする変数の配列番号をそのまま使用しようとする限り仕様にぶつかります。何か別の手を考えましょう。

なお、newmodで実際に配列の何番にデータが生成されたかはmodinit内でmref使えば見れるとか。詳細は過去ログを。



GENKI

リンク

2016/11/12(Sat) 02:04:21|NO.77318

モジュール変数は配列ではないので、IDや順番を考えながら使うものではありません。考え方を変えてください。
IDや順番はHSP側が勝手に管理してくれるのでプログラマ側は手を出せない反面、気にする必要がありません。空きスペースが出たら勝手に使ってくれます。
IDで管理したいなら配列変数使えばいいのです。

#module PlaylistItem Filename, idx ;曲(Filename)と曲順(idx)の情報を持たせる。 #modinit str _filename mref id, 2 ;モジュール変数の内部での動きの確認用 Filename = _filename ;曲順としては最後に追加 idx = idx_max idx_max++ return id #modcfunc PlaylistItem_GetFileName return Filename #modcfunc PlaylistItem_GetIndex return idx #modfunc PlaylistItem_SetIndex int p_idx idx = p_idx return idx #modfunc PlaylistItem_GetIndexMax return idx_max ;------------------- ; デストラクタ #modterm seiretu idx idx_max-- return #global ;-------------------------------------------------- #module Playlist ; 曲追加 #deffunc Playlist_Add str _filename newmod Item, PlaylistItem, _filename return stat ; 曲削除 #deffunc Playlist_Delete int _index delmod Item._index return ; モジュール変数に登録された内容全てを表示 #deffunc Playlist_PrintAllItem foreach Item mes "(" + cnt + ") " + PlaylistItem_GetIndex(Item.cnt) + " : "+ PlaylistItem_GetFileName(Item.cnt) loop return ; 欠けたindexをならす #deffunc seiretu int delidx foreach Item idx = PlaylistItem_GetIndex(Item.cnt) if idx >= delidx { idx-- PlaylistItem_SetIndex Item.cnt, idx } loop return ; 曲順で並べ替えて取り出す #deffunc Playlist_PrintList PlaylistItem_GetIndexMax Item idx_max = stat repeat idx_max i = cnt foreach Item if PlaylistItem_GetIndex(Item.cnt) = i { mes "(" + cnt + ") " + PlaylistItem_GetIndex(Item.cnt) + " : "+ PlaylistItem_GetFileName(Item.cnt) } loop loop return #global ;-------------------------------------------------- mes "(モジュール内のインデックス) " + "曲順:" + "曲名" Playlist_Add "abc.mp3" mes "登録: " + stat mes "---" : Playlist_PrintAllItem : mes "-------" Playlist_Add "123.wav" mes "登録: " + stat mes "---" : Playlist_PrintAllItem : mes "-------" Playlist_Delete 0 ;こういう消し方ではなく、曲名や曲順をforeachで探して消すようにする。 Playlist_Add "music.mp3" mes "登録: " + stat mes "---" : Playlist_PrintAllItem : mes "-------" Playlist_Add "alarm.wav" mes "登録: " + stat mes "---" : Playlist_PrintAllItem : mes "-------" pos 200,30 mes "モジュール変数内を表示" Playlist_PrintAllItem mes "-------" mes "曲順ソートして取り出し" Playlist_PrintList
超適当に書いてみました。
無理に今ままで(配列変数)と同じ運用をしようとせず、モジュール変数はこういうことが出来る別のものなんだと理解した方がいいですよ。

参考になる資料
http://wiki.hsp.moe/hsp3%EF%BC%8F%E3%83%A2%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%AB%E5%A4%89%E6%95%B0.html



名無し

リンク

2016/11/12(Sat) 14:44:09|NO.77321

皆さん、ありがとうございます。
GENKIさんのスクリプトを参考に、思い通りのものができました。
一応載せておきます
(一部自分の好みで名前を変えています、ご容赦ください)

#module PlaylistItem \ Filename, \ index //曲順 #modinit str _filename Filename = _filename index = index_next index_next++ return index //曲番号を返す #modcfunc PlaylistItem_GetFileName return Filename #modcfunc PlaylistItem_GetIndex return index #modfunc PlaylistItem_SetIndex int _index index = _index return #modcfunc PlaylistItem_GetNextIndex return index_next #modterm index_next-- return #global ;-------------------------------------------------- #module Playlist ; 曲追加 #deffunc Playlist_Add str _filename newmod Item, PlaylistItem, _filename return stat ; 曲削除 #deffunc Playlist_Delete int _index index_del = Playlist_GetIdFromIndex(_index) if index_del == -1 : return -1 delmod Item.index_del foreach Item //配列変数の整理は削除したほうの役目としました index = PlaylistItem_GetIndex(Item.cnt) if index >= _index { //削除したインデックスよりも後だった場合、一つ前へ移動 PlaylistItem_SetIndex Item.cnt, index - 1 } loop return index_del // 曲順から配列のインデックス(ID)取得 #defcfunc Playlist_GetIdFromIndex int _index, local Id Id = -1 //曲番号が存在しない場合、-1を返す foreach Item if PlaylistItem_GetIndex(Item.cnt) == _index { Id = cnt break } loop return Id // ; モジュール変数に登録された内容全てを表示 #deffunc Playlist_PrintAllItem foreach Item mes "(" + cnt + ") " + PlaylistItem_GetIndex(Item.cnt) + " : "+ PlaylistItem_GetFileName(Item.cnt) loop return ; 曲順で並べ替えて取り出す #deffunc Playlist_PrintItemSorted local i idx_max = PlaylistItem_GetNextIndex(Item) repeat idx_max i = cnt foreach Item if PlaylistItem_GetIndex(Item.cnt) = i { mes "(" + cnt + ") " + PlaylistItem_GetIndex(Item.cnt) + " : "+ PlaylistItem_GetFileName(Item.cnt) } loop loop return #global ;-------------------------------------------------- mes "(モジュール内のインデックス) " + "曲順:" + "曲名" Playlist_Add "abc.mp3" mes "登録: " + stat mes "---" : Playlist_PrintAllItem : mes "-------" Playlist_Add "123.wav" mes "登録: " + stat mes "---" : Playlist_PrintAllItem : mes "-------" Playlist_Delete 0 ;曲順から曲を削除 mes "削除: " + stat mes "---" : Playlist_PrintAllItem : mes "-------" Playlist_Add "music.mp3" mes "登録: " + stat mes "---" : Playlist_PrintAllItem : mes "-------" Playlist_Add "alarm.wav" mes "登録: " + stat mes "---" : Playlist_PrintAllItem : mes "-------" pos 200,30 mes "モジュール変数内を表示" Playlist_PrintAllItem mes "-------" mes "曲順ソートして取り出し" Playlist_PrintItemSorted



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