ソースを参照

Protype seems working.

Florian Dormont 8 年 前
コミット
4a1a2cc915
共有4 個のファイルを変更した186 個の追加59 個の削除を含む
  1. 34 59
      main.lua
  2. 48 0
      node/action.lua
  3. 84 0
      node/condition.lua
  4. 20 0
      node/init.lua

+ 34 - 59
main.lua

@@ -1,15 +1,31 @@
 local imgui = require("imgui")
+local Action = require("node.action")
+local Condition = require("node.condition")
+
+local function coro_test (action)
+    for i=0,100 do
+        action.progress = i/100
+        coroutine.yield( )
+    end
+end
+
+local function coro_test_longer (action)
+    for i=0,400 do
+        action.progress = i/400
+        coroutine.yield( )
+    end
+end
 
 local array = {
-    {name="Test", type="Action"},
-    {name="Test2", type="Action"},
-    {name="Cont", type="Container", holding={4,5,6,7,8}, condition="And"},
-    {name="Held", type="Action"},
-    {name="Held", type="Action"},
-    {name="Held", type="Action"},
-    {name="Held", type="Action"},
-    {name="Held", type="Action"},
-    {name="Held", type="Action"}
+    Action(coroutine.create( coro_test )),
+    Action(coroutine.create( coro_test )),
+    Action(coroutine.create( coro_test )),
+    Condition("and", {Action(coroutine.create( coro_test )), Action(coroutine.create( coro_test_longer ))}),
+    Condition("and", {Action(), Action(coroutine.create(function() coroutine.yield() end))}),
+    Condition("and", {Action(coroutine.create(function() coroutine.yield() end)), Action(coroutine.create(function() coroutine.yield() end))}),
+    Condition("or", {Action(coroutine.create( coro_test )), Action(coroutine.create( coro_test_longer ))}),
+    Condition("or", {Action(), Action(coroutine.create(function() coroutine.yield() end))}),
+    Condition("or", {Action(coroutine.create(function() coroutine.yield() end)), Action(coroutine.create(function() coroutine.yield() end))})
 }
 
 for i,node in ipairs(array) do node.id = i end
@@ -23,66 +39,21 @@ function not_in(v,t)
     return true
 end
 
-function draw_action_node(node)
-    local v = 0
-    imgui.BeginChildFrame(node.id,0,64, true, {"NoInputs"})
-
-    local x,y = imgui.GetCursorPos()
-    imgui.InvisibleButton("",-1,-1)
-    if imgui.IsItemClicked() then
-        selected_node = node
-    end
-    imgui.SetCursorPos(x,y)
-
-    imgui.Text(node.name)
-    imgui.Separator()
-
-    imgui.EndChildFrame()
-end
-
 function draw_array()
     imgui.Begin("Array")
     imgui.BeginChild("", 0,0, true)
     imgui.Columns(2)
-    local nodes_drawn_in_containers = {}
     for i,node in ipairs(array) do
-        if node.type == "Action" and not_in(i, nodes_drawn_in_containers) then
-            draw_action_node(node)
-        elseif node.type == "Container" then
-            if node.condition == "Or" then
-                imgui.PushStyleColor("ChildWindowBg", 0.2,0,0,1)
-            elseif node.condition == "And" then
-                imgui.PushStyleColor("ChildWindowBg", 0,0.2,0,1)
-            else
-                imgui.PushStyleColor("ChildWindowBg", 0,0,0,1)
-            end
-            imgui.BeginChild("Container "..i, 0,104, true, {"NoInputs"})
-            local x,y = imgui.GetCursorPos()
-            imgui.InvisibleButton("",-1,-1)
-            if imgui.IsItemClicked() then
-                selected_node = node
-            end
-            imgui.SetCursorPos(x,y)
-
-
-            imgui.Text("Condition | "..node.condition)
-            imgui.Separator()
-            imgui.Columns(#node.holding, nil, false)
-            imgui.PopStyleColor(1)
-            for k,v in ipairs(node.holding) do
-                nodes_drawn_in_containers[#nodes_drawn_in_containers + 1] = v
-                local node = array[v]
-                draw_action_node(node)
-                imgui.NextColumn()
-            end
-            imgui.PushStyleColor("ChildWindowBg", 1,0,0,1)
-            imgui.EndChild()
-            imgui.PopStyleColor(1)
+        local current_selected_node = node:draw_debug()
+        if current_selected_node then
+            selected_node = current_selected_node
         end
     end
     imgui.NextColumn()
     if selected_node then
         imgui.Text(selected_node.name)
+        imgui.Text(selected_node.id)
+        imgui.Text("Is finished "..tostring(selected_node:is_finished()))
     end
     imgui.Button("OK")
     imgui.EndChild()
@@ -101,6 +72,10 @@ end
 
 function love.update(dt)
     imgui.NewFrame()
+    for _,node in ipairs(array) do
+        node:update(dt)
+        if not node:is_finished() then break end
+    end
 end
 
 function love.draw()

+ 48 - 0
node/action.lua

@@ -0,0 +1,48 @@
+local Node = require("node")
+
+local Action = Node:extend"Action"
+
+function Action:init(coro)
+    Node.init(self)
+    self.coroutine = coro
+    self.progress = nil -- progress ∈ [0;1]
+end
+
+function Action:update(dt)
+    if self:is_finished() then return end
+    coroutine.resume( self.coroutine, self)
+end
+
+function Action:is_finished()
+    if not self.coroutine then return true end
+    return coroutine.status(self.coroutine) == "dead"
+end
+
+function Action:draw_debug()
+    local selected_node = nil
+    local is_finished = self:is_finished()
+    local alpha = is_finished and 0.1 or 0.3
+    imgui.PushStyleColor("Header", 1,1,1, alpha)
+    imgui.PushStyleColor("HeaderHovered", 1,1,1, alpha + 0.1)
+    imgui.PushStyleColor("HeaderActive", 1,1,1, alpha + 0.2)
+    if imgui.TreeNodeEx("Action "..self.id, {"Framed"}) then
+        if self.progress and not is_finished then
+            imgui.SameLine()
+            imgui.ProgressBar(self.progress)
+        end
+        if self.coroutine then
+            imgui.Text(coroutine.status(self.coroutine))
+        else
+            imgui.Text("-No action-")
+        end
+        imgui.TreePop()
+    elseif self.progress and not is_finished then
+        imgui.SameLine()
+        imgui.ProgressBar(self.progress)
+    end
+imgui.PopStyleColor(2)
+
+    return selected_node
+end
+
+return Action

+ 84 - 0
node/condition.lua

@@ -0,0 +1,84 @@
+local Node = require("node")
+
+local Condition = Node:extend"Condition"
+
+local default_routine = function() return true end
+local and_routine = function(accumulator, current_node) return accumulator and current_node:is_finished() end
+local or_routine = function(accumulator, current_node) return accumulator or current_node:is_finished() end
+
+
+function Condition:init(condition, nodes)
+    Node.init(self)
+    self.nodes = nodes
+    self.condition = condition
+    self.selected_condition = default_routine
+    self.num_done = 0
+    if self.condition == "or" then self.selected_condition = or_routine
+    elseif self.condition == "and" then self.selected_condition = and_routine end
+
+end
+
+function Condition:update(dt)
+    if self:is_finished() then return end
+    for _,node in ipairs(self.nodes) do
+        node:update(dt)
+    end
+
+end
+
+function Condition:is_finished()
+    if #self.nodes == 0 then return true end
+    self.num_done = 0
+    local accumulator = self.nodes[1]:is_finished()
+    if self.nodes[1]:is_finished() then self.num_done = self.num_done + 1 end
+    local i = 2
+    while i <= #self.nodes do
+        accumulator = self.selected_condition(accumulator, self.nodes[i])
+        if self.nodes[i]:is_finished() then self.num_done = self.num_done + 1 end
+        i = i + 1
+    end
+   return accumulator
+end
+
+function Condition:draw_debug()
+    local selected_node = nil
+    local is_finished = self:is_finished()
+    local alpha = is_finished and 0.1 or 0.3
+    local color = {0,0,0}
+    if self.condition == "or" then
+        color = {1,0,0}
+    elseif self.condition == "and" then
+        color = {0,1,0}
+    end
+    imgui.PushStyleColor("Header",color[1],color[2],color[3], alpha)
+    imgui.PushStyleColor("HeaderHovered",color[1],color[2],color[3], alpha+0.1)
+    imgui.PushStyleColor("HeaderActive",color[1],color[2],color[3], alpha+0.2)
+
+    if imgui.TreeNodeEx("Condition "..self.id, {"Framed"}) then
+        if #self.nodes > 0 and self.num_done > 0 and not is_finished then
+            imgui.SameLine()
+            imgui.ProgressBar((self.num_done+0.0)/#self.nodes)
+        end
+        imgui.Text("Condition "..string.upper(self.condition))
+        imgui.Text("Finished "..tostring(self:is_finished()))
+        imgui.PopStyleColor(1)
+        for k,node in ipairs(self.nodes) do
+            local current_selected_node = node:draw_debug()
+            if current_selected_node then
+                selected_node = current_selected_node
+            end
+        end
+        imgui.TreePop()
+    elseif #self.nodes > 0 and self.num_done > 0 and not is_finished then
+        imgui.SameLine()
+        imgui.ProgressBar(self.num_done/#self.nodes)
+    end
+
+    if imgui.IsItemClicked() then
+        selected_node = self
+    end
+    imgui.PopStyleColor(1)
+    return selected_node
+end
+
+return Condition

+ 20 - 0
node/init.lua

@@ -0,0 +1,20 @@
+local class = require("30log")
+
+local Node = class"Node"
+Node.id = 0
+function Node:init()
+    self.id = Node.id
+    Node.id = Node.id + 1
+end
+
+function Node:update(dt)
+end
+
+function Node:is_finished()
+    return false
+end
+
+function Node:draw_debug()
+end
+
+return Node