白日昏灯,且照人间路

CSVTool

CSV解析器

class_name CSVTool extends Object

# 使用 static 构造静态函数,可无需加载脚本,直接以 类名.函数名(CSVTool.load) 的方式调用方法
static func load(csv_path: String):
    assert(FileAccess.file_exists(csv_path), "文件不存在!")  # 使用 assert 进行断言,如果传回条件为false会直接打断后续操作。file_exists 方法如果获取不到文件,返回false。
    var file: FileAccess = FileAccess.open(csv_path, FileAccess.READ)  # 打开 CSV 文件进行读取操作
    var head: PackedStringArray = file.get_csv_line(",")  # 读取第一行作为表头(标题行)
    var type: PackedStringArray = file.get_csv_line(",")  # 读取第二行作为数据类型定义行
    file.get_csv_line(",")  # 此代码仅用于跳过注释行
    var items = []  # 用于存储所有的数据

    while not file.eof_reached():  # 循环读取整个文件,如果光标已经读到了文件末尾,eof_reached 会返回 true。
        var data: PackedStringArray = file.get_csv_line(",")  # 从第三行开始,for 循环读取当前行数据。
        var row: Dictionary = {}  # 存储当前行数据

        for i in data.size():  # 遍历表头的每一个列标题
            var title = head[i]  # 获取列标题,作为字典的键名。
            var value = data[i]  # 获取单元格,作为字典的键值。

            match type[i]:  # match 作用相当于 type[i] == int/flo……。即,寻找第i个元素,并确认其是否为对应类型代码。行(第i个)列(是否为对应类型列)都确定就可以找到值了。
                "int": row[title] = value.to_int()
                "flo": row[title] = value.to_float()
                "boo": row[title] = bool(value.to_int())
                "tex":
                    row[title] = (ResourceLoader.load(value) as Texture) if ResourceLoader.exists(value) else null
                "ori":
                    var ori = []
                    # 目前功能只具备初步效果,分析格式字符串中是否有player关键字,存在则获取对应属性
                    for item in value.strip_edges().split("|"):
                        ori.append(Player.get(item) if item.begins_with("player") else item)
                    # 查找 title 为 "dialog" 的字段并进行 % ori 操作
                    for key in row.keys(): if key == "dialog": row[key] = row[key] % ori
                "arr":
                    var elements = []
                    for element in value.strip_edges().split("|"):
                        var temporary = []
                        # 数据类型转化
                        for item in element.split(","):
                            temporary.append(item.to_float() if item.is_valid_float() else item.to_int() if item.is_valid_int() else item)
                        if title == "checks": temporary.resize(3)  # 标题为 checks 表示这是一个用于检定选项的数组,使用 resize 方法调整数组元素个数,避免调用时因数量不足而报错
                        elements.append(temporary)
                    row[title] = elements

                _: row[title] = value

        if not row.is_empty(): items.append(row)  # 将所有数据添加到 items 数组中, 方法 is_empty 会为空字典返回true。

    #for row in items:
        #for title in row.keys():
            #if type[head.find(title)] == "plo":
                #for placeholder_list in oris:
                    #for i in range(placeholder_list.size()):
                        #if placeholder_list[i].begins_with("player"): placeholder_list[i] = Player.get(placeholder_list[i])
                ## 替换占位符
                #row[title] = row[title].format(Array(oris[items.find(row)]))

    file.close()  # 读取完成后关闭文件
    return items
本文作者:Mansifield

版权声明:本文采用 CC BY-NC 4.0 协议授权

转载需注明作者及原文链接: https://glyphite.github.io/YDVIEQ/