会話インクルード新案

先日垂れ流していた「あらかじめ構文解析し、その後に解析したデータに従って表示」という妄想を形にしてみました。
なんだかすっごく重いです。
ああ、この間に処理しているんだなぁ、と思えるほど処理時間を体感できてしまうという、なんともお粗末なものになってしまいました。
なんでこんなに重いのだろうか。
構文解析したデータを表示するルーチン作ったら、メジャーなルーチン使ってるやつと処理時間比較してみようか。
でも構文解析したデータをスタックに積んでおけば、ログの表示とかのスピードは断然速くなるはず、と妄想。
まあ、実際に処理時間を比較してみないことにはなんとも言えませんね。


とりあえず完成した構文解析ルーチンを晒して今日は終了。

プロローグ:

Local str = "となりの<color=red>客</color>は<b>よく柿食う</b>客だ。となりの柿はよく客食う柿だ???"
Local temp = LT_TalkSyntaxAnalyzer(str, 5, 5, 470, 100)

Confirm temp

Exit

// メッセージを解析し、リスト形式の命令文を作成する
// 例:(command elem1 elem2 ...) (command elem1 elem2 ...) ...

// command sample
// メッセージ:メッセージを表示
// ポジション:表示位置を修正
// フォント:フォントを変更
// ウェイト:ウェイトタイムを取る
// リセット:表示領域をリセット

// Args(1):Message
// Args(2):始点X
// Args(3):始点Y
// Args(4):表示範囲幅
// Args(5):表示範囲高さ
// Message Sample:となりの<color=red>客</color>は<b>よく柿食う</b>客だ。となりの柿はよく客食う柿だ???
LT_TalkSyntaxAnalyzer:
// メッセージを変数に格納
Local mess = Args(1)
// 文字列の長さを取得
Local strlen = Len(mess)
// メッセージを解析してできる命令文を初期化
Local comm = "(ポジション $(Args(2)) $(Args(3)))"

// 参照中文字列のポインタ
Local StartPos EndPos
StartPos = 1
EndPos = 0

Local char temp PosX PosY NextY LimitX LimitY charWidth charHeight
// ポジションを初期化
PosX = Args(2)
PosY = Args(3)
NextY = Args(3)
LimitX = Args(2) + Args(4)
LimitY = Args(3) + Args(5)
// ポインタが文字列長より小さい間ループ
Do While (EndPos <= strlen)
	// ポインタをインクリメント
	Incr EndPos
	// 文字を取得
	char = Mid(mess, EndPos, 1)

	Switch char
	Case "<"
		# 直前までのメッセージを取得
		temp = Mid(mess, StartPos, EndPos - StartPos)
		# 命令文に追加
		comm = comm & " (メッセージ $(temp))"

		# タグを解析
		# 文字列ポインタを修正
		Incr EndPos
		StartPos = EndPos
		# タグが閉じられるまでループ
		Do While (Mid(mess, EndPos, 1) != ">")
			Incr EndPos
		Loop
		# タグデータを取得
		temp = Mid(mess, StartPos, EndPos - StartPos)
		# タグデータを解析
		temp = LT_TagAnalyzer(temp)
		# 命令文に追加
		comm = comm & " (フォント $(temp))"

		# 文字列ポインタを修正
		StartPos = EndPos + 1
	Case ";"
		# ここで改行を行う
		# 直前までのメッセージを取得
		temp = Mid(mess, StartPos, EndPos - StartPos)
		# 表示位置を修正
		PosX = Args(2)
		PosY = NextY
		# 命令文に追加
		comm = comm & " (メッセージ $(temp)) (ポジション $(PosX) $(PosY))"
		# 文字ポインタを修正
		StartPos = EndPos + 1
	Case ":"
		# 直前までのメッセージを取得
		temp = Mid(mess, StartPos, EndPos - StartPos)
		# 命令文に追加
		comm = comm & " (メッセージ $(temp)) (ウェイト Click)"
		# 文字ポインタを修正
		StartPos = EndPos + 1
	Case Else
		# 参照文字の高さと幅を取得
		charWidth = TextWidth(char)
		charHeight = TextHeight(char)
		# 文字列幅が指定範囲を超えたら
		If (PosX + charWidth) > LimitX Then
			# 直前までの文字列をメッセージとして登録
			# 文字列を取得
			temp = Mid(mess, StartPos, EndPos - StartPos)
			# 表示位置を修正
			PosX = Args(2)
			PosY = NextY
			# 命令文に追加
			comm = comm & " (メッセージ $(temp)) (ポジション $(PosX) $(PosY))"
			# 文字ポインタを修正
			StartPos = EndPos
		Endif
		# 文字列高さが指定範囲を超えたら
		If (PosY + charHeight) > LimitY Then
			# 命令文に追加
			comm = comm & " (ウェイト Click) (リセット) (ポジション $(Args(2)) $(Args(3)))"
			# 表示位置を修正
			PosX = Args(2)
			PosY = Args(3)
			NextY = Args(3)
		Endif
		# 表示位置を修正
		PosX = PosX + charWidth
		# 次のY座標候補を取得
		NextY = Max(NextY, PosY + charHeight)
	EndSw
Loop
# 最後のメッセージを確認
If StartPos != EndPos Then
	temp = Mid(mess, StartPos, EndPos - StartPos)
	# 命令文に追加
	comm = comm & " (メッセージ $(temp))"
Endif
Return comm





LT_TagAnalyzer:
Local elem

# フォントカラーの設定
If Left(Args(1),6) = "color=" or Left(Args(1),6) = "COLOR=" Then
	elem = Mid(Args(1),7)
	Switch elem
	Case "Red" "red" "RED"
		elem = "#ff0000"
	Case "Blue" "blue" "BLUE"
		elem = "#0000ff"
	Case "Yellow" "yellow" "YELLOW"
		elem = "#ffff00"
	Case "Green" "green" "GREEN"
		elem = "#008000"
	Case "Purple" "purple" "PURPLE"
		elem = "#800080"
	Case "Gray" "gray" "GRAY"
		elem = "#808080"
	Case "Silver" "silver" "SILVER"
		elem = "#c0c0c0"
	Case "White" "white" "WHITE"
		elem = "#ffffff"
	Case "Black" "black" "BLACK"
		elem = "#000000"
	Case "Lime" "lime" "LIME"
		elem = "#00ff00"
	Case "Aqua" "aqua" "AQUA"
		elem = "#00ffff"
	Case "Fuchsia" "fuchsia" "FUCHSIA"
		elem = "#ff00ff"
	Case "Maroon" "maroon" "MAROON"
		elem = "#800000"
	Case "Olive" "olive" "OLIVE"
		elem = "#808000"
	Case "Teal" "teal" "TEAL"
		elem = "#008080"
	Case "Navy" "navy" "NAVY"
		elem = "#000080"
	Case Else
		If Left(elem, 3) = "RGB" Then
			elem = Eval(elem)
		Endif
	EndSw
Endif

# 単純なタグを処理
Switch Args(1)
Case "B" "b"
	# フォントウェイトをBoldに設定
	elem = "Bold"
Case "I" "i"
	# フォントウェイトをItalicに設定
	elem = "Italic"
Case "BIG" "big" "Big"
	# フォントサイズを+2
	elem = Replace(LT_FontSize, "pt", "")
	Incr elem 2
	elem = elem & "pt"
Case "SMALL" "small" "Small"
	elem = Replace(LT_FontSize, "pt", "")
	Incr elem -2
	elem = elem & "pt"
EndSw

# フォントサイズを変更
Switch Left(Args(1),5)
Case "size=" "SIZE=" "Size="
	elem = Mid(Args(1),6)
	elem = Replace(elem, "pt", "")
	elem = elem & "pt"
EndSw

# フォントの設定を解除の場合
If Left(Args(1), 1) = "/" Then
	Switch Mid(Args(1),2)
	Case "B" "b" "I" "i"
		elem = LT_FontWeight
	Case "BIG" "big" "Big" "SMALL" "small" "Small" "SIZE" "size" "Size"
		elem = LT_FontSize
	Case "COLOR" "color" "Color"
		elem = LT_FontColor
	EndSw
Endif

# 修正内容を返す
Return elem