class "FunctionBlock" [DraggableRect] {
init = function(self, func, x, y)
- DraggableRect.init(self, x, y, 400, 22)
+ DraggableRect.init(self, x, y, 400, 400)
WasmCodeGenerator:setup(func, mod, COLORS)
self.header_text = WasmCodeGenerator:build_header()
end
self.scroll = 0
- self.body_visible = false
+ self.body_visible = true
self.old_height = 400
+
+ self.canvas = love.graphics.newCanvas(800, 800)
+ self.redraw = true
end;
toggle_body_visible = function(self)
self.body_visible = not self.body_visible
self.rect.h = self.body_visible and self.old_height or 22
+ self.redraw = true
+ end;
+
+ onhover = function(self, x, y)
+ self.redraw = not self.selected or self.redraw
+ self.selected = true
+ end;
+
+ onunhover = function(self)
+ self.selected = false
+ self.redraw = true
end;
onclick = function(self, button, x, y, ox, oy)
})
self.ui:add_region(cmr)
end
+ self.redraw = true
end;
onwheel = function(self, _, dy)
self.scroll = self.scroll - dy * 10;
if self.scroll < 0 then self.scroll = 0 end
+ self.redraw = true
end;
ondrag = function(self, button, x, y, dx, dy)
DraggableRect.ondrag(self, button, x, y, dx, dy)
if y >= 24 and button == 3 then
- self.rect.w = math.max(100, x)
+ self.rect.w = math.min(800, math.max(100, self.rect.w + dx))
if self.body_visible then
- self.rect.h = math.max(22, y)
+ self.rect.h = math.min(800, math.max(22, self.rect.h + dy))
self.old_height = self.rect.h
end
+ self.redraw = true
end
end;
draw = function(self)
- love.graphics.setColor(0, 0, 0)
- love.graphics.rectangle("fill", 0, 0, self.rect.w, self.rect.h)
- love.graphics.setColor(self.selected and COLORS.background or COLORS.dark_background)
- love.graphics.rectangle("fill", 2, 2, self.rect.w - 4, self.rect.h - 4)
- love.graphics.setColor(COLORS.dark_background)
- love.graphics.rectangle("fill", 2, 2, self.rect.w - 4, 18)
-
- love.graphics.intersectScissor(scissor_points(0, 0, self.rect.w, self.rect.h))
- local x, y = render_text(2, 2, self.header_text)
-
- if self.body_visible and self.body_text then
- love.graphics.intersectScissor(scissor_points(2, y - 1, self.rect.w - 4, self.rect.h - 22))
- render_text(2, y + 4 - self.scroll, self.body_text)
+ if self.redraw then
+ love.graphics.setCanvas(self.canvas)
+ local oldscissor = { love.graphics.getScissor() }
+ love.graphics.push()
+ love.graphics.origin()
+ love.graphics.setScissor(0, 0, self.canvas:getWidth(), self.canvas:getHeight())
+ love.graphics.setBackgroundColor(0, 0, 0, 0)
+ love.graphics.clear()
+ love.graphics.setScissor(0, 0, self.rect.w, self.rect.h)
+
+ love.graphics.setColor(0, 0, 0)
+ love.graphics.rectangle("fill", 0, 0, self.rect.w, self.rect.h)
+ love.graphics.setColor(self.selected and COLORS.background or COLORS.dark_background)
+ love.graphics.rectangle("fill", 2, 2, self.rect.w - 4, self.rect.h - 4)
+ love.graphics.setColor(COLORS.dark_background)
+ love.graphics.rectangle("fill", 2, 2, self.rect.w - 4, 18)
+
+ local x, y = render_text(2, 2, self.header_text)
+
+ if self.body_visible and self.body_text then
+ love.graphics.intersectScissor(2, y - 1, self.rect.w - 4, self.rect.h - 22)
+ render_text(2, y + 4 - self.scroll, self.body_text)
+ end
+
+ love.graphics.pop()
+ love.graphics.setScissor(unpack(oldscissor))
+ love.graphics.setCanvas()
+ self.redraw = false
end
+
+ love.graphics.setColor(1, 1, 1)
+ love.graphics.draw(self.canvas)
end;
}
mod = decompile(arg[2])
ui_region = ScrollingUiRegion(ui)
- ui_region.rect.x = 0
- ui_region.rect.y = 0
- ui_region.rect.w = 1200
- ui_region.rect.h = 900
- ui_region.background_color = COLORS.background
- ui_region.line_color = COLORS.dark_background
+ with(ui_region) {
+ rect = Rectangle(0, 0, 1200, 900);
+ background_color = COLORS.background;
+ line_color = COLORS.dark_background;
+ }
local x = 0
local y = 0
for _, func in pairs(mod.funcs) do
- local block = FunctionBlock(func, x, y)
+ local block = FunctionBlock(func, math.random() * 10000, math.random() * 10000)
block.order = #mod.funcs * 20 + 1 - y
ui_region:add_object(block)
y = y + 20
end
ui:add_region(ui_region)
-
- -- bottom_bar_region = UiRegion()
- -- bottom_bar_region.rect.x = 0
- -- bottom_bar_region.rect.y = 800
- -- bottom_bar_region.rect.w = 1200
- -- bottom_bar_region.rect.h = 100
- -- bottom_bar_region.layer = 1
- -- bottom_bar_region.background_color = { 1, 0, 0 }
-
- -- ui:add_region(bottom_bar_region)
end
function love.update(dt)
end
function love.draw()
+ love.graphics.setBackgroundColor(0, 0, 0)
+ love.graphics.clear()
+
ui:draw()
+
+ love.graphics.setScissor()
end
end
end
- if region ~= nil then
- if region ~= self.active_region then
- if self.active_region ~= nil then
- self.active_region:onmouseleave()
- end
+ if region ~= self.active_region then
+ if self.active_region then
+ self.active_region:onmouseleave()
+ end
+ if region ~= nil then
region:onmouseenter()
end
+ end
+
+ if region ~= nil then
region:onmousemove(x - region.rect.x, y - region.rect.y, dx, dy)
end
love.graphics.setScissor(scissor_points(region.rect.x, region.rect.y, region.rect.w, region.rect.h))
love.graphics.translate(region.rect.x, region.rect.y)
region:draw()
+ love.graphics.setScissor()
love.graphics.pop()
end
end;
return obj.rect
end;
- onmousedown = function(self, button, x, y, ox, oy)
- self.is_mouse_down = button
- self.fire_onclick = true
- local new_selected = nil
-
- for _, obj in revipairs(self.objects) do
- if self:_obj_rect(obj):contains(x, y) then
- new_selected = obj
- break
- end
- end
-
+ set_selected_object = function(self, new_selected)
if self.selected_object ~= new_selected then
if self.selected_object ~= nil then
self.selected_object:onunselect()
self.selected_object:onselect()
end
end
+ end;
+
+ onmousedown = function(self, button, x, y, ox, oy)
+ self.is_mouse_down = button
+ self.fire_onclick = true
+ local new_selected = nil
+
+ for _, obj in revipairs(self.objects) do
+ if self:_obj_rect(obj):contains(x, y) then
+ new_selected = obj
+ break
+ end
+ end
+
+ self:set_selected_object(new_selected)
if self.selected_object then
self.selected_object:onmousedown(button, x, y, ox, oy)
self.selected_object:onclick(button, x - obj_rect.x, y - obj_rect.y, ox, oy)
end
end;
+
onmousemove = function(self, x, y, dx, dy)
+ local old_hovered = self.hovered_object
+
+ self.hovered_object = nil
for _, obj in revipairs(self.objects) do
if self:_obj_rect(obj):contains(x, y) then
- if self.hovered_object and obj ~= self.hovered_object then
- self.hovered_object:onunhover()
- end
-
obj:onhover(x, y)
self.hovered_object = obj
break
end
end
+ if old_hovered and self.hovered_object ~= old_hovered then
+ old_hovered:onunhover()
+ end
+
+ self:set_selected_object(self.hovered_object)
+
if self.is_mouse_down and self.selected_object ~= nil then
local obj_rect = self:_obj_rect(self.selected_object)
self.selected_object:ondrag(self.is_mouse_down, x - obj_rect.x, y - obj_rect.y, dx, dy)
- self.fire_onclick = false
+ self.fire_onclick = self.fire_onclick and (math.abs(dx) + math.abs(dy)) < 2
end
end;
onmouseenter = function(self)
self.active = false;
self.is_mouse_down = false
self.fire_onclick = false
- self.selected_object = nil
+
+ self:set_selected_object(nil)
end;
onmousewheel = function(self, dx, dy)
love.graphics.push()
love.graphics.translate(obj.rect.x, obj.rect.y)
obj:draw()
- love.graphics.setScissor()
love.graphics.pop()
end
end;
_transform_mouse = function(self, x, y)
return
- ((x + self.rect.x) - self.rect.w / 2) / self.zoom + self.rect.w / 2 - self.offset.x - self.rect.x,
- ((y + self.rect.y) - self.rect.h / 2) / self.zoom + self.rect.h / 2 - self.offset.y - self.rect.y
+ (x - self.rect.w / 2) / self.zoom + self.rect.w / 2 - self.offset.x,
+ (y - self.rect.h / 2) / self.zoom + self.rect.h / 2 - self.offset.y
end;
onmousedown = function(self, button, x, y, ox, oy)
import {
+ pprint = "lualib.pprint";
}
+function build_type(text, type_, color)
+ for _, t in ipairs(type_.param_types) do
+ table.insert(text, { text = t .. " ", color = color })
+ end
+
+ if #type_.param_types == 0 then
+ table.insert(text, { text = "void ", color = color })
+ end
+
+ table.insert(text, { text = "-> " })
+
+ for _, t in ipairs(type_.result_types) do
+ table.insert(text, { text = t .. " " })
+ end
+
+ if #type_.result_types == 0 then
+ table.insert(text, { text = "void" })
+ end
+end
+
WasmCodeGenerator = singleton {
init = function(self) end;
local text = {}
if self.mod.start ~= nil and self.mod.start.contents.func == self.func.funcidx then
- table.insert(text, { text = "*START* ", color = self.colors.primary_light })
+ table.insert(text, { text = "*START* ", color = self.colors.primary_text })
end
table.insert(text, { text = "func[" .. self.func.funcidx .. "] ", color = self.colors.code })
table.insert(text, { text = self.func.name, color = self.colors.keyword })
table.insert(text, { text = ": ", color = self.colors.code })
- local type_ = self.func.type_
- for _, t in ipairs(type_.param_types) do
- table.insert(text, { text = t .. " " })
- end
-
- if #type_.param_types == 0 then
- table.insert(text, { text = "void " })
- end
-
- table.insert(text, { text = "-> " })
-
- for _, t in ipairs(type_.result_types) do
- table.insert(text, { text = t .. " " })
- end
-
- if #type_.result_types == 0 then
- table.insert(text, { text = "void" })
- end
-
+ build_type(text, self.func.type_, self.colors.code)
table.insert(text, { newline = true })
return text
table.insert(textlist, { text = instr[1] .. " ", color = self.colors.keyword })
table.insert(textlist, { text = self.mod.funcs[instr.x].name, color = self.colors.value })
+ elseif instr[1] == "call_indirect" then
+ self:add_line_number(textlist)
+ table.insert(textlist, { text = ("%s [%d] "):format(instr[1], instr.table), color = self.colors.keyword })
+ build_type(textlist, self.mod.types.contents[instr.x + 1], self.colors.code)
+
elseif instr[1]:match("local") then
self:add_line_number(textlist)
table.insert(textlist, { text = instr[1] .. " ", color = self.colors.keyword })