From 20d619235a06eb4351627a7882763a5d156cf4ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=91=D1=80=D0=B0=D0=BD=D0=B8=D0=BC=D0=B8=D1=80=20=D0=9A?= =?UTF-8?q?=D0=B0=D1=80=D0=B0=D1=9F=D0=B8=D1=9B?= Date: Wed, 3 Jul 2019 21:24:44 -0700 Subject: [PATCH] IDL: Updated to latest codegen. --- scripts/codegen.lua | 107 +++++++++++++++++++++----------- scripts/csharp.lua | 145 ++++++++++++++++++++++++-------------------- 2 files changed, 149 insertions(+), 103 deletions(-) diff --git a/scripts/codegen.lua b/scripts/codegen.lua index 5b749a3ff..63949262e 100644 --- a/scripts/codegen.lua +++ b/scripts/codegen.lua @@ -221,6 +221,69 @@ local function convert_vararg(v) end end +local function calc_flag_values(flag) + local shift = flag.shift + local base = flag.base or 0 + local cap = 1 << (flag.range or 0) + + if flag.range then + if flag.range == 64 then + flag.mask = 0xffffffffffffffff + else + flag.mask = ((1 << flag.range) - 1) << shift + end + end + + local values = {} + for index, item in ipairs(flag.flag) do + local value = item.value + if flag.const then + -- use value directly + elseif shift then + if value then + if value > 0 then + value = value - 1 + end + else + value = index + base - 1 + end + if value >= cap then + error (string.format("Out of range for %s (%d/%d)", name, value, cap)) + end + value = value << shift + elseif #item == 0 then + if value then + if value > 0 then + value = 1 << (value - 1) + end + else + local s = index + base - 2 + if s >= 0 then + value = 1 << s + else + value = 0 + end + end + end + if not value then + -- It's a combine flags + value = 0 + for _, name in ipairs(item) do + local v = values[name] + if v then + value = value | v + else + -- todo : it's a undefined flag + value = nil + break + end + end + end + item.value = value + values[item.name] = value + end +end + function codegen.nameconversion(all_types, all_funcs) for _,v in ipairs(all_types) do local name = v.name @@ -242,6 +305,9 @@ function codegen.nameconversion(all_types, all_funcs) v.typename = v.name v.name = v.name .. "::Enum" end + if v.flag then + calc_flag_values(v) + end end -- make index @@ -685,8 +751,6 @@ function codegen.gen_flag_cdefine(flag) local cname = "BGFX_" .. (flag.cname or to_underscorecase(flag.name):upper()) local s = {} local shift = flag.shift - local base = flag.base or 0 - local cap = 1 << (flag.range or 0) for index, item in ipairs(flag.flag) do local name if item.cname then @@ -695,36 +759,9 @@ function codegen.gen_flag_cdefine(flag) name = cname .. "_" .. to_underscorecase(item.name):upper() end local value = item.value - if flag.const then - -- use value directly - elseif shift then - if value then - if value > 0 then - value = value - 1 - end - else - value = index + base - 1 - end - if value >= cap then - error (string.format("Out of range for %s (%d/%d)", name, value, cap)) - end - value = value << shift - elseif #item == 0 then - if value then - if value > 0 then - value = 1 << (value - 1) - end - else - local s = index + base - 2 - if s >= 0 then - value = 1 << s - else - value = 0 - end - end - end - if value == nil then + -- combine flags + if #item > 0 then if item.comment then if type(item.comment) == "table" then for _, c in ipairs(item.comment) do @@ -752,12 +789,8 @@ function codegen.gen_flag_cdefine(flag) end local mask - if flag.range then - if flag.range == 64 then - mask = "ffffffffffffffff" - else - mask = string.format(flag.format, ((1 << flag.range) - 1) << shift) - end + if flag.mask then + mask = string.format(flag.format, flag.mask) mask = string.format("UINT%d_C(0x%s)", flag.bits, mask) end diff --git a/scripts/csharp.lua b/scripts/csharp.lua index 685646df8..b821dfd85 100644 --- a/scripts/csharp.lua +++ b/scripts/csharp.lua @@ -29,10 +29,6 @@ internal struct NativeFunctions } ]] -local function hasPrefix(str, prefix) - return prefix == "" or str:sub(1, #prefix) == prefix -end - local function hasSuffix(str, suffix) return suffix == "" or str:sub(-#suffix) == suffix end @@ -90,35 +86,62 @@ local function gen() return r end -local lastCombinedIdx = -1 - local combined = { "State", "Stencil", "Buffer", "Texture", "Sampler", "Reset" } -local function isCombinedBlock(str) - for idx, prefix in ipairs(combined) do - if hasPrefix(str, prefix) then - return idx - end - end - - return -1 +for _, v in ipairs(combined) do + combined[v] = {} end -local function endCombinedBlock() - if lastCombinedIdx ~= -1 then - yield("}") +local lastCombinedFlag + +local function FlagBlock(typ) + if typ == nil then + return end - lastCombinedIdx = -1 + local format = "0x%08x" + local enumType = "" + if typ.bits == 64 then + format = "0x%016x" + enumType = " : ulong" + elseif typ.bits == 16 then + format = "0x%04x" + enumType = " : ushort" + end + + yield("[Flags]") + yield("public enum " .. typ.name .. enumType) + yield("{") + + for _, flag in ipairs(typ.flag) do + yield("\t" + .. flag.name + .. string.rep(" ", 22 - #(flag.name)) + .. " = " + .. string.format(format, flag.value) + .. "," + ) + end + -- generate Mask + if typ.mask then + yield("\t" + .. "Mask" + .. string.rep(" ", 22 - #("Mask")) + .. " = " + .. string.format(format, flag.mask) + ) + end + + yield("}") end function converter.types(typ) if typ.handle then - endCombinedBlock() + FlagBlock(combined[lastCombinedFlag]) yield("public struct " .. typ.name .. "{ public ushort idx; }") elseif hasSuffix(typ.name, "::Enum") then - endCombinedBlock() + FlagBlock(combined[lastCombinedFlag]) yield("public enum " .. typ.typename) yield("{") @@ -127,55 +150,45 @@ function converter.types(typ) end yield("}") elseif typ.bits ~= nil then - - local idx = isCombinedBlock(typ.name) - - if idx ~= lastCombinedIdx then - endCombinedBlock() + local prefix, name = typ.name:match "(%u%l+)(.*)" + if prefix ~= lastCombinedFlag then + FlagBlock(combined[lastCombinedFlag]) end - - local format = "0x%08x" - local enumType = "" - if typ.bits == 64 then - format = "0x%016x" - enumType = " : ulong" - elseif typ.bits == 16 then - format = "0x%04x" - enumType = " : ushort" - end - - if lastCombinedIdx == -1 then - yield("[Flags]") - if idx ~= -1 then - yield("public enum " .. combined[idx] .. enumType) - else - yield("public enum " .. typ.name .. enumType) + local combinedFlag = combined[prefix] + if combinedFlag then + lastCombinedFlag = prefix + combinedFlag.bits = typ.bits + combinedFlag.name = prefix + local flags = combinedFlag.flag or {} + combinedFlag.flag = flags + local lookup = combinedFlag.lookup or {} + combinedFlag.lookup = lookup + for _, flag in ipairs(typ.flag) do + local flagName = name .. flag.name + local value = flag.value + if value == nil then + -- It's a combined flag + value = 0 + for _, v in ipairs(flag) do + value = value | assert(lookup[name .. v], v .. " is not defined for " .. flagName) + end + end + lookup[flagName] = value + table.insert(flags, { + name = flagName, + value = value, + }) end - - lastCombinedIdx = idx - yield("{") - end - - for _, flag in ipairs(typ.flag) do - if flag.value then - yield("\t" - .. flag.name - .. string.rep(" ", 22 - #(flag.name)) - .. " = " - .. string.format(format, flag.value) - .. "," - ) - else - yield("\t// Combined: " - .. flag.name - .. " = " - .. table.concat(flag, " | ") - ) + if typ.mask then + -- generate Mask + table.insert(flags, { + name = name .. "Mask", + value = typ.mask, + }) + lookup[name .. "Mask"] = typ.mask end - end - - if lastCombinedIdx == -1 then - yield("}") + else + FlagBlock(typ) end end end