Search code examples
luacoroutinemoai

attempt to index local 'self' using MOAICoroutine in Lua


I am just starting with MOAI and I am trying to create a traditional game loop using MOAICoroutine. The problem is that when I pass it the function that is part of a "class" that is built using 30log, it returns an error. It seems to continue to function, but I would like to fix the error. My guess is that the MOAICoroutine is calling the function using the dot notation rather than the syntactical sugar method with a colon. Here is the code:

class = require "30log.30log"
GameSystem = class ()

function GameSystem:__init(Name, Title)
  self.Name = Name
  self.Title = Title
  self.Ready = false
end

function GameSystem:Run()
  if self:Init() then
    self.Thread = MOAICoroutine.new ()
    self.Thread:run(self.Start)
    --self:Start()
    return true
  else
    print("Init failed.")
    return false    
  end
end

function GameSystem:Init()
  print("Initializing Game System")
  if not self:InitTimer() then return false end
  if not self:InitWindow(640,480) then return false end
  if not self:InitViewport() then return false end
  if not self:InitGraphics() then return false end
  if not self:InitSound() then return false end
  if not self:InitInput() then return false end
  self.Ready = true
  return true
end

function GameSystem:Start()
  print("Starting Game System")
  while self.Ready do
    self:UpdateTimer()
    self:UpdateGraphics()
    self:UpdateSound()
    self:UpdateInput()
    coroutine.yield()
  end
end

function GameSystem:InitTimer()
  return true
end

function GameSystem:InitWindow(width, height)
  print("Initializing Window")

  return true
end

function GameSystem:InitViewport()
  print("Initializing Viewport")

  return true
end

function GameSystem:InitGraphics()
  print("Initializing Graphics")
  return true
end

function GameSystem:InitSound()
  print("Initializing Sound")
  return true
end

function GameSystem:InitInput()
    print("Initializing Input")
  return true
end

function GameSystem:UpdateTimer()
    --print("Updating Timer")
  return true
end

function GameSystem:UpdateGraphics()
  --print("Updating Graphics")
  return true
end

function GameSystem:UpdateSound()
    --print("Updating Sound")
  return true
end

function GameSystem:UpdateInput()
  --print("Updating Input")
  return true
end

Is the 30log class code causing this problem? I have tried various things. I am pretty sure the self it is trying to access is the first argument i.e. mytable.myfunction(self, myarg). Any ideas to fix this nil value reference. The error actually occurred on the second line inside the Start function (while self.Ready do).


Solution

  •   function GameSystem:Run()
        if self:Init() then
          self.Thread = MOAICoroutine.new ()
          self.Thread:run(self.Start)
    

    My guess is that the MOAICoroutine is calling the function using the dot notation rather than the syntactical sugar method with a colon.

    How would it be calling the function using dot notion (or colon notation)? What would be on the left side of the period or colon? You haven't passed it an object, only a function. The fact that it's caller was storing that function in a table is completely unknown to it. It just receives a function, and calls it.

    If you want your coroutine to start with a method call, do that in the function you pass to coroutine.start:

    self.Thread = MOAICoroutine.new ()
    self.Thread:run(function() self:Start() end)
    

    The point is that:

    function GameSystem:Start()
    end
    

    Is exactly equivalent to:

    function GameSystem.Start(self)
    end
    

    Is exactly equivalent to:

    GameSystem.Start = function(self)
    end
    

    Is equivalent to:

    function Foobar(self)
    end
    
    GameSystem.Start = Foobar
    

    If I call:

    print(Foobar)
    print(GameSystem.Start)
    print(someGameSystemInstance.Start)
    

    print receives the same value. In Lua, a function is a function is a function, it's not "tainted" in some way by being stored in a table, such that a third party with a reference to the function can know that you want it to be called as a method to some particular 'class instance.