@@ -19,6 +19,7 @@ import java.util.Locale.getDefault
1919import androidx.core.graphics.toColorInt
2020// Thư viện phân tích TOML (cần thêm vào build.gradle, ví dụ: implementation("org.tomlj:tomlj:1.1.1"))
2121import org.tomlj.Toml
22+ import org.tomlj.TomlArray
2223import org.tomlj.TomlTable
2324
2425/* *
@@ -900,11 +901,11 @@ class PageConfigReader {
900901 // Các mục nằm "bên trong" một group (con của nó) khai báo bằng đường dẫn lồng:
901902 // [[group.action]], [[group.page]], [[group.text]] ...
902903 //
903- // Giới hạn cần biết: TOML không lưu được thứ tự XEN KẼ giữa các bảng KHÁC TÊN
904- // (vd 1 action rồi tới 1 page rồi lại 1 action nữa ) - mỗi tên gom thành 1 danh sách
905- // riêng. Mặc định các loại được sắp theo thứ tự: group, text, switch, picker, action,
906- // page, editor, resource; nếu cần chỉ định thứ tự chính xác, thêm field `order = <số>`
907- // (số nhỏ hơn hiện trước) vào từng mục .
904+ // Thứ tự hiển thị: LUÔN theo đúng vị trí xuất hiện trong file (trên trước, dưới sau),
905+ // bất kể loại mục là gì (group, action, page, text ... ) - kể cả khi các loại XEN KẼ
906+ // nhau (vd 1 action rồi tới 1 page rồi lại 1 action nữa). Vị trí này lấy trực tiếp từ
907+ // dòng khai báo `[[ten]]` trong file thông qua API vị trí của tomlj, không cần khai báo
908+ // thêm field `order` nào .
908909 //
909910 // Ví dụ:
910911 // [[group]]
@@ -977,23 +978,45 @@ class PageConfigReader {
977978 }
978979 }
979980
980- // Gom toàn bộ node con của 1 bảng (root, hoặc bảng của 1 group), theo đúng thứ tự
981- // mặc định (tomlNodeTypeOrder), trừ khi từng mục có field `order` để chỉ định vị trí.
981+ // Lấy số dòng (trong file gốc) nơi 1 mục được khai báo, để dùng làm căn cứ sắp xếp
982+ // "trên trước, dưới sau". Với bảng mảng [[ten]] (nhiều mục cùng tên), phải lấy vị trí
983+ // của TỪNG phần tử qua TomlArray, vì vị trí của chính khoá `ten` chỉ trỏ tới mục ĐẦU
984+ // TIÊN. Nếu vì lý do gì đó không lấy được vị trí (API thay đổi, lỗi...), trả về null
985+ // và nơi gọi sẽ tự rơi về thứ tự xuất hiện khi đọc (seq) để không bao giờ crash.
986+ private fun tomlEntryLine (parent : TomlTable , key : String , index : Int ): Int? {
987+ return try {
988+ if (parent.isArray(key)) {
989+ val arr: TomlArray ? = parent.getArray(key)
990+ arr?.inputPositionOf(index)?.line()
991+ } else if (parent.isTable(key)) {
992+ parent.inputPositionOf(key)?.line()
993+ } else {
994+ null
995+ }
996+ } catch (ex: Exception ) {
997+ null
998+ }
999+ }
1000+
1001+ // Gom toàn bộ node con của 1 bảng (root, hoặc bảng của 1 group). Thứ tự hiển thị luôn
1002+ // theo đúng vị trí xuất hiện trong file (trên trước, dưới sau), không phân biệt loại
1003+ // mục và không cần field `order`.
9821004 private fun tomlChildren (parent : TomlTable ): ArrayList <NodeInfoBase > {
983- data class Entry (val order : Double , val seq : Int , val node : NodeInfoBase )
1005+ data class Entry (val line : Int , val seq : Int , val node : NodeInfoBase )
9841006
9851007 val entries = ArrayList <Entry >()
9861008 var seq = 0
987- for ((typeIndex, type) in tomlNodeTypeOrder.withIndex()) {
988- val defaultBase = typeIndex * 100000.0
989- for (table in tomlEntries(parent, type)) {
1009+ for (type in tomlNodeTypeOrder) {
1010+ for ((index, table) in tomlEntries(parent, type).withIndex()) {
9901011 seq++
9911012 val node = tomlBuildNode(type, table) ? : continue
992- val explicitOrder = tomlGet(table, " order " )?.trim()?.toDoubleOrNull()
993- entries.add(Entry (explicitOrder ? : (defaultBase + seq) , seq, node))
1013+ val line = tomlEntryLine(parent, type, index) ? : Int . MAX_VALUE
1014+ entries.add(Entry (line , seq, node))
9941015 }
9951016 }
996- return ArrayList (entries.sortedWith(compareBy({ it.order }, { it.seq })).map { it.node })
1017+ // Sắp theo dòng thực tế trong file; nếu không lấy được dòng (line == MAX_VALUE)
1018+ // thì rơi về đúng thứ tự đọc được (seq) để vẫn ổn định, không xáo trộn ngẫu nhiên.
1019+ return ArrayList (entries.sortedWith(compareBy({ it.line }, { it.seq })).map { it.node })
9971020 }
9981021
9991022 private fun tomlBuildNode (type : String , table : TomlTable ): NodeInfoBase ? {
0 commit comments