help
This commit is contained in:
parent
32befc1a89
commit
3bd423243e
2
.gitignore
vendored
2
.gitignore
vendored
@ -1 +1 @@
|
|||||||
local_conf.lua
|
local_conf.lua
|
||||||
|
|||||||
64
README.md
64
README.md
@ -1,33 +1,33 @@
|
|||||||

|

|
||||||
# Helium
|
# Helium
|
||||||
## Major features:
|
## Major features:
|
||||||
### Custom elements
|
### Custom elements
|
||||||
Write your own elements, and interface with them however you want to,
|
Write your own elements, and interface with them however you want to,
|
||||||
Whether you need a generalized button that can have many themes and options or something super specific, it can be done
|
Whether you need a generalized button that can have many themes and options or something super specific, it can be done
|
||||||
### Efficient rendering & updating
|
### Efficient rendering & updating
|
||||||
The elements only update&re-render when state changes
|
The elements only update&re-render when state changes
|
||||||
### Code hotswap
|
### Code hotswap
|
||||||
Change and save a file loaded through the helium.loader, and see changes immediately
|
Change and save a file loaded through the helium.loader, and see changes immediately
|
||||||
|
|
||||||
## Basic overview:
|
## Basic overview:
|
||||||
Helium is practically more like a UI framework than a fully fledged UI library.
|
Helium is practically more like a UI framework than a fully fledged UI library.
|
||||||
The idea is to build custom, build simple and build fast, encapsulate.
|
The idea is to build custom, build simple and build fast, encapsulate.
|
||||||
|
|
||||||
## Demo's / Practical examples
|
## Demo's / Practical examples
|
||||||
[There's a repository of examples here](https://github.com/qfluxstudio/helium_demos)
|
[There's a repository of examples here](https://github.com/qfluxstudio/helium_demos)
|
||||||
|
|
||||||
## Getting started:
|
## Getting started:
|
||||||
Load helium with `local helium = require 'helium'`
|
Load helium with `local helium = require 'helium'`
|
||||||
|
|
||||||
The basic structure for an element is:
|
The basic structure for an element is:
|
||||||
|
|
||||||
```lua
|
```lua
|
||||||
return function(param,state,view)
|
return function(param,state,view)
|
||||||
--Setup zone
|
--Setup zone
|
||||||
return function()
|
return function()
|
||||||
--Rendering zone
|
--Rendering zone
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
```
|
```
|
||||||
|
|
||||||
[The documentation outgrew this readme, see the github wiki](https://github.com/qfluxstudio/helium/wiki/)
|
[The documentation outgrew this readme, see the github wiki](https://github.com/qfluxstudio/helium/wiki/)
|
||||||
12
conf.lua
12
conf.lua
@ -1,7 +1,7 @@
|
|||||||
return {
|
return {
|
||||||
HOTSWAP = true, --Turns on hotswap, disable this once you're deploying a project
|
HOTSWAP = true, --Turns on hotswap, disable this once you're deploying a project
|
||||||
AUTO_RUN = true, --Replaces the default love.run
|
AUTO_RUN = true, --Replaces the default love.run
|
||||||
DEBUG = true, --Reserved for later
|
DEBUG = true, --Reserved for later
|
||||||
PURE_G = true, --whether to keep _G pure
|
PURE_G = true, --whether to keep _G pure
|
||||||
HARD_ERROR = true, --Whether to display element errors inside or hard cras
|
HARD_ERROR = true, --Whether to display element errors inside or hard cras
|
||||||
}
|
}
|
||||||
@ -1,61 +1,61 @@
|
|||||||
local path = string.sub(..., 1, string.len(...) - string.len(".core.layout"))
|
local path = string.sub(..., 1, string.len(...) - string.len(".core.layout"))
|
||||||
|
|
||||||
local layout = {}
|
local layout = {}
|
||||||
layout.__index = layout
|
layout.__index = layout
|
||||||
local element = require(path..'core.element')
|
local element = require(path..'core.element')
|
||||||
|
|
||||||
local function layout_new(type, x, y, w, h)
|
local function layout_new(type, x, y, w, h)
|
||||||
local ctx = element.getContext()
|
local ctx = element.getContext()
|
||||||
|
|
||||||
--The output will be in pixel numbers regardless of inputs
|
--The output will be in pixel numbers regardless of inputs
|
||||||
if x <= 1 or not x then
|
if x <= 1 or not x then
|
||||||
x = ctx.view.x * (x or 0)
|
x = ctx.view.x * (x or 0)
|
||||||
end
|
end
|
||||||
|
|
||||||
if y <= 1 then
|
if y <= 1 then
|
||||||
y = ctx.view.y * (y or 0)
|
y = ctx.view.y * (y or 0)
|
||||||
end
|
end
|
||||||
|
|
||||||
if w <= 1 then
|
if w <= 1 then
|
||||||
w = ctx.view.w * (w or 1)
|
w = ctx.view.w * (w or 1)
|
||||||
end
|
end
|
||||||
|
|
||||||
if h <= 1 then
|
if h <= 1 then
|
||||||
h = ctx.view.h * (h or 1)
|
h = ctx.view.h * (h or 1)
|
||||||
end
|
end
|
||||||
|
|
||||||
return setmetatable({
|
return setmetatable({
|
||||||
x = x,
|
x = x,
|
||||||
y = y,
|
y = y,
|
||||||
w = w,
|
w = w,
|
||||||
h = h
|
h = h
|
||||||
}, layout)
|
}, layout)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--Sets mode for the proceding operations
|
--Sets mode for the proceding operations
|
||||||
function layout.mode()
|
function layout.mode()
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--Sets padding for the next operations
|
--Sets padding for the next operations
|
||||||
function layout.pad()
|
function layout.pad()
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--Sets margins for the proceding operations
|
--Sets margins for the proceding operations
|
||||||
function layout.margin()
|
function layout.margin()
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function layout.offset()
|
function layout.offset()
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function layout:draw()
|
function layout:draw()
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
layout(0,0,1,1)
|
layout(0,0,1,1)
|
||||||
|
|
||||||
return layout
|
return layout
|
||||||
|
|||||||
@ -1,7 +1,8 @@
|
|||||||
local path = string.sub(..., 1, string.len(...) - string.len(".control.size"))
|
local path = string.sub(..., 1, string.len(...) - string.len(".control.size"))
|
||||||
local stack = require(path..'.core.stack')
|
local stack = require(path..'.core.stack')
|
||||||
|
|
||||||
--Sets the computed/minimum size of an element to be used with layout calculations and rendering
|
--Sets the computed/minimum size of an element to be used with layout calculations and rendering
|
||||||
return function(w, h)
|
return function(w, h)
|
||||||
|
local currentStack = stack.getContext()
|
||||||
|
currentStack.element:setCalculatedSize(w, h)
|
||||||
end
|
end
|
||||||
@ -1,19 +1,19 @@
|
|||||||
local path = string.sub(..., 1, string.len(...) - string.len(".control.state"))
|
local path = string.sub(..., 1, string.len(...) - string.len(".control.state"))
|
||||||
local context = require(path.. ".core.context")
|
local context = require(path.. ".core.stack")
|
||||||
|
|
||||||
return function (base)
|
return function (base)
|
||||||
local base = base or {}
|
base = base or {}
|
||||||
local fakeBase = {}
|
local fakeBase = {}
|
||||||
local activeContext = context.getContext()
|
local activeContext = context.getContext()
|
||||||
return setmetatable({},{
|
return setmetatable({},{
|
||||||
__index = function(t, index)
|
__index = function(t, index)
|
||||||
return fakeBase[index] or base[index]
|
return fakeBase[index] or base[index]
|
||||||
end,
|
end,
|
||||||
__newindex = function(t, index, val)
|
__newindex = function(t, index, val)
|
||||||
if fakeBase[index] ~= val then
|
if fakeBase[index] ~= val then
|
||||||
fakeBase[index] = val
|
fakeBase[index] = val
|
||||||
activeContext:bubbleUpdate()
|
activeContext:bubbleUpdate()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
@ -87,14 +87,23 @@ function element:new(param)
|
|||||||
self.context = context.new(self)
|
self.context = context.new(self)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function element:setCalculatedSize(w, h)
|
||||||
|
self.view.minW = w or self.view.minW
|
||||||
|
self.view.minH = h or self.view.minH
|
||||||
|
self.view.w = math.max(self.view.minW, self.view.w)
|
||||||
|
self.view.h = math.max(self.view.minH, self.view.h)
|
||||||
|
end
|
||||||
|
|
||||||
function element:updateInputCtx()
|
function element:updateInputCtx()
|
||||||
self.context.inputContext:update()
|
self.context.inputContext:update()
|
||||||
if self.settings.canvasW then
|
if self.settings.canvasW then
|
||||||
|
--If canvas too small make a bigger one
|
||||||
if self.settings.canvasW < self.view.w or self.settings.canvasH < self.view.h then
|
if self.settings.canvasW < self.view.w or self.settings.canvasH < self.view.h then
|
||||||
self.settings.canvasW = self.view.w*1.25
|
self.settings.canvasW = self.view.w*1.25
|
||||||
self.settings.canvasH = self.view.h*1.25
|
self.settings.canvasH = self.view.h*1.25
|
||||||
|
|
||||||
self.canvas = love.graphics.newCanvas(self.view.w*1.25, self.view.h*1.25)
|
self.canvas = love.graphics.newCanvas(self.view.w*1.25, self.view.h*1.25)
|
||||||
|
--If canvas too big make a smaller one
|
||||||
elseif self.settings.canvasW > self.view.w*1.50 or self.settings.canvasH > self.view.h*1.50 then
|
elseif self.settings.canvasW > self.view.w*1.50 or self.settings.canvasH > self.view.h*1.50 then
|
||||||
self.settings.canvasW = self.view.w*1.25
|
self.settings.canvasW = self.view.w*1.25
|
||||||
self.settings.canvasH = self.view.h*1.25
|
self.settings.canvasH = self.view.h*1.25
|
||||||
@ -246,10 +255,12 @@ local insert = table.insert
|
|||||||
--Acts as the entrypoint for beginning rendering
|
--Acts as the entrypoint for beginning rendering
|
||||||
---@param x number
|
---@param x number
|
||||||
---@param y number
|
---@param y number
|
||||||
function element:draw(x, y)
|
function element:draw(x, y, w, h)
|
||||||
if not self.view.lock then
|
if not self.view.lock then
|
||||||
if x then self.view.x = x end
|
if x then self.view.x = x end
|
||||||
if y then self.view.y = y end
|
if y then self.view.y = y end
|
||||||
|
if w then self.view.w = self.view.minW<=w and w or self.view.minW end
|
||||||
|
if h then self.view.h = self.view.minH<=h and h or self.view.minH end
|
||||||
end
|
end
|
||||||
|
|
||||||
if self.settings.firstDraw then
|
if self.settings.firstDraw then
|
||||||
|
|||||||
10
core/input.d.ts
vendored
10
core/input.d.ts
vendored
@ -1,6 +1,6 @@
|
|||||||
interface Subscription{
|
interface Subscription{
|
||||||
on():void;
|
on():void;
|
||||||
off():void;
|
off():void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function input(it:string,cb:(x?:number,y?:number)=>void,doff?:boolean,x?:number,y?:number,w?:number,h?:number): Subscription;
|
export default function input(it:string,cb:(x?:number,y?:number)=>void,doff?:boolean,x?:number,y?:number,w?:number,h?:number): Subscription;
|
||||||
142
core/signals.lua
142
core/signals.lua
@ -1,72 +1,72 @@
|
|||||||
--Internal event/zone/perf-log system
|
--Internal event/zone/perf-log system
|
||||||
local signals = {}
|
local signals = {}
|
||||||
signals.__index = signals
|
signals.__index = signals
|
||||||
|
|
||||||
function signals.newController()
|
function signals.newController()
|
||||||
return setmetatable({
|
return setmetatable({
|
||||||
stack = {},
|
stack = {},
|
||||||
|
|
||||||
eventSubs = {},
|
eventSubs = {},
|
||||||
zoneSubs = {},
|
zoneSubs = {},
|
||||||
|
|
||||||
startTime = 0,
|
startTime = 0,
|
||||||
totalTime = 0
|
totalTime = 0
|
||||||
}, signals)
|
}, signals)
|
||||||
end
|
end
|
||||||
|
|
||||||
function signals:push(name)
|
function signals:push(name)
|
||||||
self.stack[#self.stack+1] = {name = name}
|
self.stack[#self.stack+1] = {name = name}
|
||||||
|
|
||||||
self.startTime = love.timer.getTime()
|
self.startTime = love.timer.getTime()
|
||||||
|
|
||||||
if self.zoneSubs[name] then
|
if self.zoneSubs[name] then
|
||||||
for i, e in ipairs(self.zoneSubs[name]) do
|
for i, e in ipairs(self.zoneSubs[name]) do
|
||||||
if e.on and e.func() then
|
if e.on and e.func() then
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function signals:pop()
|
function signals:pop()
|
||||||
local name = self.stack[#self.stack].name
|
local name = self.stack[#self.stack].name
|
||||||
|
|
||||||
if self.zoneSubs[name] then
|
if self.zoneSubs[name] then
|
||||||
for i, e in ipairs(self.zoneSubs[name]) do
|
for i, e in ipairs(self.zoneSubs[name]) do
|
||||||
if not e.on and e.func() then
|
if not e.on and e.func() then
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
self.totalTime = love.timer.getTime() - self.startTime
|
self.totalTime = love.timer.getTime() - self.startTime
|
||||||
self.stack[#self.stack] = nil
|
self.stack[#self.stack] = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
function signals:emitEvent(name, content)
|
function signals:emitEvent(name, content)
|
||||||
if self.eventSubs[name] then
|
if self.eventSubs[name] then
|
||||||
for i,e in ipairs(self.eventSubs[name]) do
|
for i,e in ipairs(self.eventSubs[name]) do
|
||||||
e.func(content)
|
e.func(content)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function signals:onEvent(func, event)
|
function signals:onEvent(func, event)
|
||||||
if not self.eventSubs[event] then
|
if not self.eventSubs[event] then
|
||||||
self.eventSubs[event] = {}
|
self.eventSubs[event] = {}
|
||||||
end
|
end
|
||||||
self.eventSubs[event][#self.eventSubs[event]+1] = {func = func}
|
self.eventSubs[event][#self.eventSubs[event]+1] = {func = func}
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--on - true when new zone is pushed
|
--on - true when new zone is pushed
|
||||||
-- false when zone is popped
|
-- false when zone is popped
|
||||||
function signals:onSignal(func, name, on)
|
function signals:onSignal(func, name, on)
|
||||||
if not self.zoneSubs[name] then
|
if not self.zoneSubs[name] then
|
||||||
self.zoneSubs[name] = {}
|
self.zoneSubs[name] = {}
|
||||||
end
|
end
|
||||||
self.zoneSubs[name][#self.zoneSubs[name]+1] = {func = func, on = on}
|
self.zoneSubs[name][#self.zoneSubs[name]+1] = {func = func, on = on}
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
return signals
|
return signals
|
||||||
174
core/stack.lua
174
core/stack.lua
@ -1,88 +1,88 @@
|
|||||||
--Builds the element stack basically
|
--Builds the element stack basically
|
||||||
|
|
||||||
local path = string.sub(..., 1, string.len(...) - string.len(".core.stack"))
|
local path = string.sub(..., 1, string.len(...) - string.len(".core.stack"))
|
||||||
local helium = require(path .. ".dummy")
|
local helium = require(path .. ".dummy")
|
||||||
|
|
||||||
---@class context
|
---@class context
|
||||||
local context = {}
|
local context = {}
|
||||||
context.__index = context
|
context.__index = context
|
||||||
|
|
||||||
local activeContext
|
local activeContext
|
||||||
|
|
||||||
---@param elem element
|
---@param elem element
|
||||||
function context.new(elem)
|
function context.new(elem)
|
||||||
local ctx = setmetatable({
|
local ctx = setmetatable({
|
||||||
view = elem.view,
|
view = elem.view,
|
||||||
element = elem,
|
element = elem,
|
||||||
childrenContexts = {},
|
childrenContexts = {},
|
||||||
inputContext = helium.input.newContext(elem)
|
inputContext = helium.input.newContext(elem)
|
||||||
}, context)
|
}, context)
|
||||||
|
|
||||||
return ctx
|
return ctx
|
||||||
end
|
end
|
||||||
|
|
||||||
function context:bubbleUpdate()
|
function context:bubbleUpdate()
|
||||||
self.element.settings.pendingUpdate = true
|
self.element.settings.pendingUpdate = true
|
||||||
self.element.settings.needsRendering = true
|
self.element.settings.needsRendering = true
|
||||||
|
|
||||||
if self.parentCtx and self.parentCtx~=self then
|
if self.parentCtx and self.parentCtx~=self then
|
||||||
self.parentCtx:bubbleUpdate()
|
self.parentCtx:bubbleUpdate()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function context:set()
|
function context:set()
|
||||||
if activeContext then
|
if activeContext then
|
||||||
if not self.parentCtx and activeContext~=self then
|
if not self.parentCtx and activeContext~=self then
|
||||||
self.parentCtx = activeContext
|
self.parentCtx = activeContext
|
||||||
activeContext.childrenContexts[#activeContext.childrenContexts] = self
|
activeContext.childrenContexts[#activeContext.childrenContexts] = self
|
||||||
end
|
end
|
||||||
|
|
||||||
self.absX = self.parentCtx.absX + self.view.x
|
self.absX = self.parentCtx.absX + self.view.x
|
||||||
self.absY = self.parentCtx.absY + self.view.y
|
self.absY = self.parentCtx.absY + self.view.y
|
||||||
|
|
||||||
activeContext = self
|
activeContext = self
|
||||||
else
|
else
|
||||||
self.absX = self.view.x
|
self.absX = self.view.x
|
||||||
self.absY = self.view.y
|
self.absY = self.view.y
|
||||||
|
|
||||||
activeContext = self
|
activeContext = self
|
||||||
end
|
end
|
||||||
|
|
||||||
self.inputContext:set()
|
self.inputContext:set()
|
||||||
end
|
end
|
||||||
|
|
||||||
function context:unset()
|
function context:unset()
|
||||||
self.inputContext:unset()
|
self.inputContext:unset()
|
||||||
self.inputContext:afterLoad()
|
self.inputContext:afterLoad()
|
||||||
|
|
||||||
if self.parentCtx then
|
if self.parentCtx then
|
||||||
activeContext = self.parentCtx
|
activeContext = self.parentCtx
|
||||||
else
|
else
|
||||||
activeContext = nil
|
activeContext = nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function context:unsuspend()
|
function context:unsuspend()
|
||||||
self.inputContext:unsuspend()
|
self.inputContext:unsuspend()
|
||||||
end
|
end
|
||||||
|
|
||||||
function context:destroy()
|
function context:destroy()
|
||||||
self.elem:undraw()
|
self.elem:undraw()
|
||||||
for i=1,#self.childrenContexts do
|
for i=1,#self.childrenContexts do
|
||||||
self.childrenContexts[i]:destroy()
|
self.childrenContexts[i]:destroy()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function context:suspend()
|
function context:suspend()
|
||||||
self.inputContext:set()
|
self.inputContext:set()
|
||||||
self.inputContext:suspend()
|
self.inputContext:suspend()
|
||||||
self.inputContext:unset()
|
self.inputContext:unset()
|
||||||
end
|
end
|
||||||
|
|
||||||
--Function meant for external context capture
|
--Function meant for external context capture
|
||||||
function context.getContext()
|
function context.getContext()
|
||||||
return activeContext
|
return activeContext
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
return context
|
return context
|
||||||
@ -1,18 +1,18 @@
|
|||||||
Hooks are additional functions to utilize the element lifecycle more granularly
|
Hooks are additional functions to utilize the element lifecycle more granularly
|
||||||
e.g.
|
e.g.
|
||||||
|
|
||||||
```lua
|
```lua
|
||||||
local onDestroyHook = require("helium/hooks/onDestroy")
|
local onDestroyHook = require("helium/hooks/onDestroy")
|
||||||
|
|
||||||
return function (param)
|
return function (param)
|
||||||
|
|
||||||
onDestroyHook(function()
|
onDestroyHook(function()
|
||||||
doSomething()
|
doSomething()
|
||||||
end)
|
end)
|
||||||
|
|
||||||
return function()
|
return function()
|
||||||
love.graphics.print("Help")
|
love.graphics.print("Help")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
```
|
```
|
||||||
66
init.d.ts
vendored
66
init.d.ts
vendored
@ -1,33 +1,33 @@
|
|||||||
export interface parameters{
|
export interface parameters{
|
||||||
[index: string]: any;
|
[index: string]: any;
|
||||||
[index: number]: any;
|
[index: number]: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface view{
|
export interface view{
|
||||||
x: number;
|
x: number;
|
||||||
y: number;
|
y: number;
|
||||||
w: number;
|
w: number;
|
||||||
h: number;
|
h: number;
|
||||||
lock?: boolean;
|
lock?: boolean;
|
||||||
onChange?(): null;
|
onChange?(): null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface state{
|
export interface state{
|
||||||
[index: string]: any;
|
[index: string]: any;
|
||||||
[index: number]: any;
|
[index: number]: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface HeliumElement{
|
interface HeliumElement{
|
||||||
view: view;
|
view: view;
|
||||||
state: state;
|
state: state;
|
||||||
parameters: parameters;
|
parameters: parameters;
|
||||||
draw(this,x:number,y:number): null;
|
draw(this,x:number,y:number): null;
|
||||||
undraw(this): null;
|
undraw(this): null;
|
||||||
}
|
}
|
||||||
|
|
||||||
declare function HeliumLoader(filepath:string):(params:parameters, w:number, h:number)=>HeliumElement;
|
declare function HeliumLoader(filepath:string):(params:parameters, w:number, h:number)=>HeliumElement;
|
||||||
|
|
||||||
export module helium{
|
export module helium{
|
||||||
export let input: typeof import("./core/input") ;
|
export let input: typeof import("./core/input") ;
|
||||||
}
|
}
|
||||||
export function helium<T>(chunk:(params:T,state:state,view:view)=>()=>void):(params:T, w:number, h:number)=>HeliumElement;
|
export function helium<T>(chunk:(params:T,state:state,view:view)=>()=>void):(params:T, w:number, h:number)=>HeliumElement;
|
||||||
|
|||||||
14
init.lua
14
init.lua
@ -12,10 +12,16 @@ helium.input = require(path..".core.input")
|
|||||||
helium.loader = require(path..".loader")
|
helium.loader = require(path..".loader")
|
||||||
helium.elementBuffer = {}
|
helium.elementBuffer = {}
|
||||||
helium.__index = helium
|
helium.__index = helium
|
||||||
setmetatable(helium, {__call = function(s,chunk)
|
|
||||||
return function(param,w,h)
|
setmetatable(helium, {__call = function(s, chunk)
|
||||||
return helium.element(chunk,nil,w,h,param)
|
return {
|
||||||
end
|
__call = function(s, param, w, h)
|
||||||
|
return helium.element(chunk, nil, w, h, param)
|
||||||
|
end,
|
||||||
|
draw = function (param, x, y, w, h)
|
||||||
|
return helium.element.immediate(param, chunk, x, y, w, h)
|
||||||
|
end
|
||||||
|
}
|
||||||
end})
|
end})
|
||||||
|
|
||||||
function helium.render()
|
function helium.render()
|
||||||
|
|||||||
214
loader.lua
214
loader.lua
@ -1,108 +1,108 @@
|
|||||||
|
|
||||||
local path = string.sub(..., 1, string.len(...) - string.len(".loader"))
|
local path = string.sub(..., 1, string.len(...) - string.len(".loader"))
|
||||||
local helium = require(path..'.dummy')
|
local helium = require(path..'.dummy')
|
||||||
local elements = {}
|
local elements = {}
|
||||||
local debugLoader = {}
|
local debugLoader = {}
|
||||||
--Return level: 1--string; 2--chunk; 3--return value; default: element factory
|
--Return level: 1--string; 2--chunk; 3--return value; default: element factory
|
||||||
local function loader(path)
|
local function loader(path)
|
||||||
local succ = true
|
local succ = true
|
||||||
|
|
||||||
--File string
|
--File string
|
||||||
local fileContents, err = love.filesystem.read(path)
|
local fileContents, err = love.filesystem.read(path)
|
||||||
|
|
||||||
if fileContents==nil then
|
if fileContents==nil then
|
||||||
print('Error loading ',path,':',tostring(err),', will continue watching!')
|
print('Error loading ',path,':',tostring(err),', will continue watching!')
|
||||||
succ = false
|
succ = false
|
||||||
end
|
end
|
||||||
|
|
||||||
local t, lastLoaded
|
local t, lastLoaded
|
||||||
if succ then
|
if succ then
|
||||||
t = love.filesystem.getInfo(path)
|
t = love.filesystem.getInfo(path)
|
||||||
lastLoaded = t['modtime']
|
lastLoaded = t['modtime']
|
||||||
end
|
end
|
||||||
|
|
||||||
--Chunk
|
--Chunk
|
||||||
local status, err
|
local status, err
|
||||||
if succ then
|
if succ then
|
||||||
status, err = pcall(loadstring,fileContents)
|
status, err = pcall(loadstring,fileContents)
|
||||||
end
|
end
|
||||||
|
|
||||||
if status==false or status==nil then
|
if status==false or status==nil then
|
||||||
print('Error compiling ',path,':',tostring(err),', will continue watching!')
|
print('Error compiling ',path,':',tostring(err),', will continue watching!')
|
||||||
succ = false
|
succ = false
|
||||||
end
|
end
|
||||||
|
|
||||||
--Return values
|
--Return values
|
||||||
local ret
|
local ret
|
||||||
if succ then
|
if succ then
|
||||||
succ, ret = pcall(err,path)
|
succ, ret = pcall(err,path)
|
||||||
if not succ then
|
if not succ then
|
||||||
print('Error calling ',path,':',tostring(ret))
|
print('Error calling ',path,':',tostring(ret))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return fileContents, err, ret, lastLoaded
|
return fileContents, err, ret, lastLoaded
|
||||||
end
|
end
|
||||||
|
|
||||||
debugLoader.loader = function(path,returnLevel)
|
debugLoader.loader = function(path,returnLevel)
|
||||||
local level = returnLevel or 6
|
local level = returnLevel or 6
|
||||||
if elements[path] then
|
if elements[path] then
|
||||||
return elements[path][level]
|
return elements[path][level]
|
||||||
end
|
end
|
||||||
|
|
||||||
local setfuncs = {}
|
local setfuncs = {}
|
||||||
|
|
||||||
local fileContents, func, ret, lastLoaded = loader(path)
|
local fileContents, func, ret, lastLoaded = loader(path)
|
||||||
local reloader = function(setFunc)
|
local reloader = function(setFunc)
|
||||||
setfuncs[#setfuncs+1] = setFunc
|
setfuncs[#setfuncs+1] = setFunc
|
||||||
end
|
end
|
||||||
|
|
||||||
local factory = function(param,w,h)
|
local factory = function(param,w,h)
|
||||||
return helium.element(ret, reloader, w, h, param)
|
return helium.element(ret, reloader, w, h, param)
|
||||||
end
|
end
|
||||||
|
|
||||||
elements[path] = {fileContents, func, ret, path, lastLoaded, factory, setfuncs = setfuncs}
|
elements[path] = {fileContents, func, ret, path, lastLoaded, factory, setfuncs = setfuncs}
|
||||||
return elements[path][level]
|
return elements[path][level]
|
||||||
end
|
end
|
||||||
|
|
||||||
local counter = 0
|
local counter = 0
|
||||||
function debugLoader.update(dt)
|
function debugLoader.update(dt)
|
||||||
counter = counter+dt
|
counter = counter+dt
|
||||||
if counter>2 then
|
if counter>2 then
|
||||||
for ind, elem in pairs(elements) do
|
for ind, elem in pairs(elements) do
|
||||||
--Get the current last save time
|
--Get the current last save time
|
||||||
local t = love.filesystem.getInfo(elem[4])
|
local t = love.filesystem.getInfo(elem[4])
|
||||||
local ll = t['modtime']
|
local ll = t['modtime']
|
||||||
if ll ~= elem[5] then
|
if ll ~= elem[5] then
|
||||||
--If last save time differs then start reload sequence
|
--If last save time differs then start reload sequence
|
||||||
local _, _, ret, lastLoaded = loader(elem[4])
|
local _, _, ret, lastLoaded = loader(elem[4])
|
||||||
|
|
||||||
|
|
||||||
local setfuncs = {}
|
local setfuncs = {}
|
||||||
|
|
||||||
local reloader = function(setFunc)
|
local reloader = function(setFunc)
|
||||||
setfuncs[#setfuncs+1] = setFunc
|
setfuncs[#setfuncs+1] = setFunc
|
||||||
end
|
end
|
||||||
|
|
||||||
local factory = function()
|
local factory = function()
|
||||||
return helium.element(ret, reloader)
|
return helium.element(ret, reloader)
|
||||||
end
|
end
|
||||||
|
|
||||||
elem[5] = lastLoaded
|
elem[5] = lastLoaded
|
||||||
|
|
||||||
elem[6] = factory
|
elem[6] = factory
|
||||||
|
|
||||||
for i, func in ipairs(elem.setfuncs) do
|
for i, func in ipairs(elem.setfuncs) do
|
||||||
func(ret)
|
func(ret)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
counter = 0
|
counter = 0
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if helium.conf.PURE_G then
|
if helium.conf.PURE_G then
|
||||||
HeliumLoader = debugLoader.loader
|
HeliumLoader = debugLoader.loader
|
||||||
end
|
end
|
||||||
|
|
||||||
return debugLoader
|
return debugLoader
|
||||||
Loading…
x
Reference in New Issue
Block a user