text: /*
   * framework/core/l-stage.c
   *
   * Copyright(c) 2007-2020 Jianjun Jiang <8192542@qq.com>
   * Official site: http://xboot.org
   * Mobile phone: +86-18665388956
   * QQ: 8192542
   *
   * Permission is hereby granted, free of charge, to any person obtaining a copy
   * of this software and associated documentation files (the "Software"), to deal
   * in the Software without restriction, including without limitation the rights
   * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   * copies of the Software, and to permit persons to whom the Software is
   * furnished to do so, subject to the following conditions:
   *
   * The above copyright notice and this permission notice shall be included in all
   * copies or substantial portions of the Software.
   *
   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
   * SOFTWARE.
   *
   */
  
  #include <framework/core/l-stage.h>
  
  static const char stage_lua[] = X(
  local M = Class(DisplayObject)
  
  function M:init()
  	self._running = true
  	self._timerlist = {}
  	self._window = Window.new()
  	self.super:init(self._window:getSize())
  	self:markDirty()
  end
  
  function M:exit()
  	self._running = false
  	return self
  end
  
  function M:hasTimer(timer)
  	local tl = self._timerlist
  
  	if not tl or #tl == 0 then
  		return false
  	end
  
  	for i, v in ipairs(tl) do
  		if v == timer then
  			return true
  		end
  	end
  
  	return false
  end
  
  function M:addTimer(timer)
  	if self:hasTimer(timer) then
  		return false
  	end
  
  	timer:start()
  	table.insert(self._timerlist, timer)
  	return true
  end
  
  function M:removeTimer(timer)
  	local tl = self._timerlist
  
  	if not tl or #tl == 0 then
  		return false
  	end
  
  	for i, v in ipairs(tl) do
  		if v == timer then
  			v:pause()
  			table.remove(tl, i)
  			return true
  		end
  	end
  
  	return false
  end
  
  function M:schedTimer(dt)
  	for i, v in ipairs(self._timerlist) do
  		if v._running then
  			v._runtime = v._runtime + dt
  
  			if v._runtime >= v._delay then
  				v._runcount = v._runcount + 1
  				v._listener(v)
  				v._runtime = 0
  
  				if v._iteration ~= 0 and v._runcount >= v._iteration then
  					self:removeTimer(v)
  				end
  			end
  		end
  	end
  end
  
  function M:getDotsPerInch()
  	local w, h = self._window:getSize()
  	local pw, ph = self._window:getPhysicalSize()
  	return w * 25.4 / pw, h * 25.4 / ph
  end
  
  function M:setBacklight(brightness)
  	return self._window:setBacklight(brightness)
  end
  
  function M:getBacklight()
  	return self._window:getBacklight()
  end
  
  function M:setLauncher(enable)
  	self._window:setLauncher(enable)
  	return self
  end
  
  function M:snapshot()
  	return self._window:snapshot()
  end
  
  function M:addFont(family, path)
  	return self._window:addFont(family, path)
  end
  
  function M:loop()
  	local Event = Event
  	local window = self._window
  	local stopwatch = Stopwatch.new()
  
  	self:addTimer(Timer.new(1 / 60, 0, function(t)
  		self:dispatch(Event.new("enter-frame"))
  		self:render(window)
  		collectgarbage("step")
  	end))
  
  	while self._running do
  		local e = Event.pump()
  		if e ~= nil then
  			if e.type == "system-exit" then
  				self:exit()
  			end
  			self:dispatch(e)
  		end
  
  		local elapsed = stopwatch:elapsed()
  		if elapsed > 0 then
  			stopwatch:reset()
  			self:schedTimer(elapsed)
  		end
  	end
  end
  
  return M
  );
  
  int luaopen_stage(lua_State * L)
  {
  	if(luaL_loadbuffer(L, stage_lua, sizeof(stage_lua) - 1, "Stage.lua") == LUA_OK)
  		lua_call(L, 0, 1);
  	return 1;
  }
  