2

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).

Psyfun
  • 353
  • 3
  • 15

1 Answers1

3
  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.

Mud
  • 28,277
  • 11
  • 59
  • 92
  • @EgorSkriptunoff Yeah, that's what I meant. Thanks for pointing out my mistake. – Mud Jan 29 '13 at 16:34
  • That makes sense as all examples I have seen that uses MOAICoroutine declares the function inline. Will the Start function still have access to other functions and members stored in the instance's table? Just want to make sure that the class encapsulation I am using will not cause problems getting to members of the table. I don't want to orphan the Start function where it can't update the table. I guess that's what the self reference is for, to maintain the link to the original table. – Psyfun Jan 29 '13 at 17:07
  • Yes, that indeed solved the problem. I knew how the functions behaved inside a table, just wasn't sure how the MOAICoroutine was expecting the function. In fact, both methods worked using either the dot notation or the colon. Thanks so much for the help. Great explanation. – Psyfun Jan 29 '13 at 17:13
  • "Will the Start function still have access to other functions and members stored in the instance's table?" Of course, because you're passing the table to them. – Mud Jan 29 '13 at 17:42