キュー

様々なデータタイプを格納できるキューのモジュールです(メモリが許す限りデータを格納できます)
そのままでは配列等は格納できませんが、DataContainerモジュールを変更すれば格納できます

様々なデータタイプを格納できるキューのモジュールです(メモリが許す限りデータを格納できます)
そのままでは配列等は格納できませんが、DataContainerモジュールを変更すれば格納できます

  • タグ:
  • タグはありません
// データを保存するだけのモジュール
// 各種データをモジュール変数として扱う用
#module DataContainer m_data, m_size, m_rsize
#modinit var p_data, int p_size, \
local index
	if p_size < 0 {
		delmod thismod
		return -1
	}
	m_size = p_size
	if m_size > 0 {
		dimtype m_data, vartype(p_data), m_size
		switch vartype(p_data)
			case vartype("int")    : m_rsize = m_size << 2 : swbreak
			case vartype("str")    : m_rsize = m_size      : swbreak
			case vartype("double") : m_rsize = m_size << 3 : swbreak
			case vartype("label")  : m_rsize = m_size << 2 : swbreak	// TODO: 64Bit版
			case vartype("struct") : delmod thismod : return -1			// 未実装
			default                : delmod thismod : return -1			// 実装する気ナシ
		swend
		memcpy m_data, p_data, m_rsize
	} else {
		dimtype m_data, vartype(p_data), 1
		m_rsize = 0
	}
	mref index, 2
	return index

// 格納されたデータを取得
#modfunc  local GetData var p_data
	if m_size > 0 {
		dimtype p_data, vartype(m_data), m_size
		memcpy p_data, m_data, m_rsize
	} else {
		dimtype p_data, vartype(m_data), 1
	}
	return

// 格納されたデータのサイズを取得
#modcfunc local GetSize
	return m_size

// 格納されたデータの実サイズを取得
#modcfunc local GetRealSize
	return m_rsize
#global


// キューのモジュール
#module Queue m_data, m_index, m_num
#modinit \
local index
	dimtype m_data, vartype("struct"), 1
	dim m_index, 1
	dim m_num
	mref index, 2
	return index

// キューにデータを追加
// Enqueue@Queue [VAR]モジュール変数, [VAR]追加するデータ, [INT]データの大きさ
// 戻り値:正常終了だと1、処理に失敗すると0
#modfunc  local Enqueue var p_data, int p_size
	newmod m_data, DataContainer, p_data, p_size
	if stat < 0 : return 0
	m_index(m_num) = stat
	m_num++
	return 1

// キューからデータを取得
// Dequeue@Queue [VAR]モジュール変数, [VAR]出力先変数
// 戻り値:正常終了だと1、処理に失敗すると0
#modfunc  local Dequeue var p_data
	if m_num <= 0 : return 0
	GetData@DataContainer m_data(m_index(0)), p_data
	m_num--
	memcpy m_index, m_index, m_num << 2, 0, 4
	return 1

// キューのデータ数を取得
// RET = GetDataNum@Queue([VAR]モジュール変数)
// 戻り値:データ数
#modcfunc local GetDataNum
	return m_num

// 次のデータのサイズを取得
// RET = GetNextDataSize@Queue([VAR]モジュール変数)
// 戻り値:データサイズ、ただしデータがないときは-1
#modcfunc local GetNextDataSize
	if m_num <= 0 : return -1
	return GetSize@DataContainer(m_data(m_index(0)))
#global


// 以下サンプル、#if 0を#if 1にして動作
#if 0
	newmod mod, Queue
	sdim text
	
	objsize 60, 20
	pos   0, 0 : input text, 200, 20
	pos 200, 0 : button "Enqueue",  *enqueue
	pos 260, 0 : button "Dequeue",  *dequeue
	pos 320, 0 : button "Count",    *count
	pos 380, 0 : button "Get Size", *getsize
	pos 10, 30
	stop

*enqueue
	if text == "" {
		mes "No Data Specified"
		stop
	}
	Enqueue@Queue mod, text, strlen(text)
	mes "Enqueued ["+text+"]"
	objprm 0, ""
	sdim text
	stop

*dequeue
	sdim data
	Dequeue@Queue mod, data
	if stat {
		mes "Dequeued ["+data+"]"
	} else {
		mes "No Data in Queue"
	}
	stop

*count
	mes "There are "+GetDataNum@Queue(mod)+" Data in Queue"
	stop

*getsize
	size = GetNextDataSize@Queue(mod)
	if size >= 0 {
		mes "Next Data is "+size+" Bytes Long"
	} else {
		mes "No Data in Queue"
	}
	stop
#endif