mirror of
				https://github.com/Reuh/ubiquitousse.git
				synced 2025-10-27 17:19:31 +00:00 
			
		
		
		
	Since I only use the LÖVE backend anyway, this simplifies the code. Tidied some code.
		
			
				
	
	
		
			162 lines
		
	
	
	
		
			5.7 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
			
		
		
	
	
			162 lines
		
	
	
	
		
			5.7 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
| local input = require((...):gsub("axis$", "input"))
 | |
| local button_mt = require((...):gsub("axis$", "button"))
 | |
| 
 | |
| --- AxisInput methods
 | |
| local axis_mt
 | |
| axis_mt = {
 | |
| 	-- Axis inputs --
 | |
| 	-- Axis input is a container for axes detector. An axis input will return the value of the axis detector the most far away from their center (0).
 | |
| 	-- Axis input provide a threshold setting; every axis which has a distance to the center below the threshold (none by default) will be ignored.
 | |
| 	-- @tparam AxisDetectors ... all the axis detectors or axis identifiers
 | |
| 	-- @tretrun AxisInput the object
 | |
| 	_new = function(...)
 | |
| 		local r = setmetatable({
 | |
| 			hijackStack = {}, -- hijackers stack, last element is the object currently hijacking this input
 | |
| 			hijacking = nil, -- object currently hijacking this input
 | |
| 			detectors = {}, -- detectors list
 | |
| 			val = 0, -- current value between -1 and 1
 | |
| 			dval = 0, -- change between -2 and 2
 | |
| 			raw = 0, -- raw value between -max and +max
 | |
| 			max = 1, -- maximum for raw values
 | |
| 			threshold = 0, -- ie., the deadzone
 | |
| 			triggeringThreshold = 0.5 -- digital button threshold
 | |
| 		}, axis_mt)
 | |
| 		table.insert(r.hijackStack, r)
 | |
| 		r.hijacking = r
 | |
| 		r:bind(...)
 | |
| 		r.positive = input.button(function() return r:value() > r.triggeringThreshold end)
 | |
| 		r.negative = input.button(function() return r:value() < -r.triggeringThreshold end)
 | |
| 		return r
 | |
| 	end,
 | |
| 
 | |
| 	--- Returns a new AxisInput with the same properties.
 | |
| 	-- @treturn AxisInput the cloned object
 | |
| 	clone = function(self)
 | |
| 		return input.axis(unpack(self.detectors))
 | |
| 		       :threshold(self.threshold)
 | |
| 		       :triggeringThreshold(self.triggeringThreshold)
 | |
| 	end,
 | |
| 
 | |
| 	--- Bind new AxisDetector(s) to this input.
 | |
| 	-- @tparam AxisDetectors ... axis detectors or axis identifiers to add
 | |
| 	-- @treturn AxisInput this AxisInput object
 | |
| 	bind = function(self, ...)
 | |
| 		for _,d in ipairs({...}) do
 | |
| 			table.insert(self.detectors, input.axisDetector(d))
 | |
| 		end
 | |
| 		return self
 | |
| 	end,
 | |
| 	--- Unbind AxisDetector(s).
 | |
| 	-- @tparam AxisDetectors ... axis detectors or axis identifiers to remove
 | |
| 	-- @treturn AxisInput this AxisInput object
 | |
| 	unbind = button_mt.unbind,
 | |
| 	--- Unbind all AxisDetector(s).
 | |
| 	-- @treturn AxisInput this AxisInput object
 | |
| 	clear = button_mt.clear,
 | |
| 
 | |
| 	--- Hijacks the input.
 | |
| 	-- This function returns a new input object which mirrors the current object, except it will hijack every new input.
 | |
| 	-- This means any value change will only be visible to the new object; the axis will always appear to be at 0 for the initial object.
 | |
| 	-- An input can be hijacked several times; the one which hijacked it last will be the active one.
 | |
| 	-- @treturn AxisInput the new input object which is hijacking the input
 | |
| 	hijack = function(self)
 | |
| 		local hijacked
 | |
| 		hijacked = setmetatable({
 | |
| 			positive = input.button(function() return hijacked:value() > self.triggeringThreshold end),
 | |
| 			negative = input.button(function() return hijacked:value() < -self.triggeringThreshold end)
 | |
| 		}, { __index = self, __newindex = self })
 | |
| 		table.insert(self.hijackStack, hijacked)
 | |
| 		self.hijacking = hijacked
 | |
| 		return hijacked
 | |
| 	end,
 | |
| 	--- Release the input that was hijacked by this object.
 | |
| 	-- Input will be given back to the previous object.
 | |
| 	-- @treturn AxisInput this AxisInput object
 | |
| 	free = button_mt.free,
 | |
| 
 | |
| 	--- Sets the default detection threshold (deadzone).
 | |
| 	-- 0 by default.
 | |
| 	-- @tparam number new the new detection threshold
 | |
| 	-- @treturn AxisInput this AxisInput object
 | |
| 	threshold = function(self, new)
 | |
| 		self.threshold = tonumber(new)
 | |
| 		return self
 | |
| 	end,
 | |
| 
 | |
| 	--- Returns the value of the input (between -1 and 1).
 | |
| 	-- @tparam[opt=default threshold] number threshold value to use
 | |
| 	-- @treturn number the input value
 | |
| 	value = function(self, curThreshold)
 | |
| 		if self.hijacking == self then
 | |
| 			self:update()
 | |
| 			local val = self.val
 | |
| 			return math.abs(val) > math.abs(curThreshold or self.threshold) and val or 0
 | |
| 		else
 | |
| 			return 0
 | |
| 		end
 | |
| 	end,
 | |
| 	--- Returns the change in value of the input since last update (between -2 and 2).
 | |
| 	-- @treturn number the value delta
 | |
| 	delta = function(self)
 | |
| 		if self.hijacking == self then
 | |
| 			self:update()
 | |
| 			return self.dval
 | |
| 		else
 | |
| 			return 0
 | |
| 		end
 | |
| 	end,
 | |
| 	--- Returns the raw value of the input (between -max and +max).
 | |
| 	-- @tparam[opt=default threshold*max] number raw threshold value to use
 | |
| 	-- @treturn number the input raw value
 | |
| 	raw = function(self, rawThreshold)
 | |
| 		if self.hijacking == self then
 | |
| 			self:update()
 | |
| 			local raw = self.raw
 | |
| 			return math.abs(raw) > math.abs(rawThreshold or self.threshold*self.max) and raw or 0
 | |
| 		else
 | |
| 			return 0
 | |
| 		end
 | |
| 	end,
 | |
| 	--- Return the raw max of the input.
 | |
| 	-- @treturn number the input raw max
 | |
| 	max = function(self)
 | |
| 		self:update()
 | |
| 		return self.max
 | |
| 	end,
 | |
| 
 | |
| 	--- Sets the default triggering threshold, i.e. how the minimal axis value for which the associated buttons will be considered down.
 | |
| 	-- 0.5 by default.
 | |
| 	-- @tparam number new the new triggering threshold
 | |
| 	-- @treturn AxisInput this AxisInput object
 | |
| 	triggeringThreshold = function(self, new)
 | |
| 		self.triggeringThreshold = tonumber(new)
 | |
| 		return self
 | |
| 	end,
 | |
| 
 | |
| 	--- The associated button pressed when the axis reaches a positive value.
 | |
| 	positive = nil,
 | |
| 	--- The associated button pressed when the axis reaches a negative value.
 | |
| 	negative = nil,
 | |
| 
 | |
| 	--- Update axis state.
 | |
| 	-- Automatically called, don't call unless you know what you're doing.
 | |
| 	update = function(self)
 | |
| 		if not input.updated[self] then
 | |
| 			local val, raw, max = 0, 0, 1
 | |
| 			for _, d in ipairs(self.detectors) do
 | |
| 				local v, r, m = d() -- v[-1,1], r[-m,+m]
 | |
| 				if math.abs(v) > math.abs(val) then
 | |
| 					val, raw, max = v, r or v, m or 1
 | |
| 				end
 | |
| 			end
 | |
| 			self.dval = val - self.val
 | |
| 			self.val, self.raw, self.max = val, raw, max
 | |
| 			input.updated[self] = true
 | |
| 		end
 | |
| 	end,
 | |
| 
 | |
| 	--- LÖVE note: other callbacks that are defined in backend/love.lua and need to be called in the associated LÖVE callbacks.
 | |
| }
 | |
| axis_mt.__index = axis_mt
 | |
| 
 | |
| return axis_mt
 |