Recent Entries 10
- pattern minor 112d agoCall a lua function - the C++ wayI'm not that good when it comes to templates, especially when it comes to variadic templates. I want to show you some code where I use both - templates and variadic templates - to call a lua function. I'm proud that it works, and it works great, but I want to get some feedback on what I could've done better. ``` template bool run_script(int id, Args && ... args) { const int params = sizeof...(args); _load(id); push(std::forward(args)...); return _run(params); } ``` This is the "entry point". `_load` will just load the lua-function onto the stack and `_run` will run it with `params` arguments. The important part is the `push` function. ``` template void push(T && arg) { _push(std::forward(arg)); } template void push(T && arg, Args && ... other) { _push(std::forward(arg)); push(std::forward(other)...); } void _push(int arg) { lua_pushinteger(L, arg); } void _push(const std::string& arg) { lua_pushstring(L, arg.c_str()); } void _push(const char* arg) { lua_pushstring(L, arg); } ``` I had a problem before, where I had all of them named `push`, but for some reason it couldn't push a `std::string` (std::string as argument choose the template instead of `const std::string&`) but now with the templates called `push` and the functions which do the work `_push` it's working great. It's not much code, I know, but it's my the first time working with variadic templates and it took me a fair amount of time to get it working.
- pattern minor 112d agoprint(fizz..buzz)I couldn't help but notice we didn't have a FizzBuzz in lua yet. I've always wanted to take a shot at Lua, so here goes nothing. Code: `function fizzBuzz(maxNum) local fizz = "Lua" local buzz = "Yay" for i = 1, maxNum do if i % 15 == 0 then print(fizz..buzz) elseif i % 3 == 0 then print(fizz) elseif i % 5 == 0 then print (buzz) else print(i) end end end fizzBuzz(100) ` Output: `1 2 Lua 4 Yay Lua 7 8 Lua Yay 11 Lua 13 14 LuaYay 16 17 ` I highly doubt it's idiomatic Lua, so I'm open for suggestions. As far as I know mixedCase and 2-space indentation are the way to go for Lua, but feel free to prove me wrong.
- pattern minor 112d agoSimple four-operation calculator in LuaI'm a beginner at Lua and programming in general and I just made a simple calculator and I was wondering where I could make improvements. ``` print("Choose numbers:") print("Num1:") local num1 = io.read() print("num2:") local num2 = io.read() print("Choose operator: + / - / * / /") local operator = io.read() if operator == "+" then local add = num1 + num2 print(add) end if operator == "-" then local subtract = num1 - num2 print(subtract) end if operator == "*" then local multiply = num1 * num2 print(multiply) end if operator == "/" then local devide = num1 / num2 print(devide) end io.read() ```
- pattern minor 112d agoImplementing The Proper Undead's Cave GeneratorI recently stumbled onto a very old article about procedural dungeon generation on this site. Unfortunately, the author did not provide any code, only a description of the algorithm he used. Wanting to use this in my game, I tried to write my own generator following their algorithm: ``` local random = math.random local function grid() return { min = 0, max = 0, init = function(self, min, max) for i = min, max do self[i] = {} end self.min = min self.max = max end, set = function(self, x, y, c) if x >= self.min and x = self.min and y \n") end, } setmetatable(p, {__eq = function(self, right) return self.x == right.x and self.y == right.y end}) return p end local function contains_point(array, p) for i = 1, #array do if array[i] == p then return true end end return false end local function shuffle(array) local size = #array for i = 1, size do local swap = random(1, size) array[i], array[swap] = array[swap], array[i] end return array end local function offsets(p) return { point(p.x, p.y+1), point(p.x, p.y-1), point(p.x+1, p.y), point(p.x-1, p.y), } end local function circular_iterator_of(items, start) local index = start - 1 return function() local ret = items[index + 1] index = index + 1 index = index % #items + 1 return ret end end local function carve(list) local index = 1 while index minTilesCarved for i = 1, #carvedList do p = carvedList[i] if i == 1 then map:set(p.x, p.y, "D") elseif i == #carvedList then map:set(p.x, p.y, "U") else map:set(p.x, p.y, ".") end end return map end map = generate_map(64, 170, os.time()) map:print() ``` First time pos
- pattern minor 112d agoBus Announcement System in ROBLOX LuaI got bored and decided to create a lua announcement system with the ROBLOX API. One part is the display code, and the other part is the announcement code. DISPLAY CODE ``` while true do wait(0.2) if script.Parent.Parent.An.Value == 0 then script.Parent.An1.Text = "This bus terminates here" script.Parent.An2.Text = "Bus is on diversion" script.Parent.Selected.Text = "The destination has changed" script.Parent.An3.Text = "Driver change" script.Parent.An4.Text = "Next stop is closed" script.Parent.An5.Text = "Move Down" elseif script.Parent.Parent.An.Value == 1 then script.Parent.An1.Text = "Next stop is closed" script.Parent.An2.Text = "This bus terminates here" script.Parent.Selected.Text = "Bus is on diversion" script.Parent.An5.Text = "Move Down" script.Parent.An3.Text = "The destination has changed" script.Parent.An4.Text = "Driver change" elseif script.Parent.Parent.An.Value == 2 then script.Parent.An5.Text = "Move Down" script.Parent.An1.Text = "Driver change" script.Parent.An2.Text = "Next stop is closed" script.Parent.Selected.Text = "This bus terminates here" script.Parent.An3.Text = "Bus is on diversion" script.Parent.An4.Text = "The destination has changed" elseif script.Parent.Parent.An.Value == 3 then script.Parent.An1.Text = "The destination has changed" script.Parent.An2.Text = "Driver change" script.Parent.Selected.Text = "Next stop is closed" script.Parent.An3.Text = "This bus terminates here" script.Parent.An4.Text = "Bus is on diversion" script.Parent.An5.Text = "Move Down" elseif script.Parent.Parent.An.Value == 4 then script.Parent.An1.Text = "Bus is on diversion" script.Parent.An2.Text = "The destination has changed" script.Parent.Selected.Text = "Move Down" script.Parent.An3.Text = "Next stop i
- pattern minor 112d agoAsynchronous request cloning using Lua + openrestyI'm working on a project to clone a subset of requests going to our production servers to one or more non-production endpoints. I opted to do this in Nginx and Lua because at the time, I could not find a tool that fit the requirements I needed, namely, only forwarding all requests for a subset of session IDs (as opposed to a percentage of all requests). Initially, I was simply using `ngx.timer.at` to dispatch the subrequest, but I was informed that the server could run out of threads if the destination server was unavailable. So I looked at lua-resty-logger-socket and used the code that they use to buffer requests and modified it for my usage. This is my first Lua project in Nginx, and actually my first time touching Lua years, and nobody at work knows Lua well enough to give any advice, so I'd appreciate if anyone could point out any flaws in my methods or things that can be done better. example nginx.conf: ``` location = /GenerateToken { set $session_token ""; access_by_lua_file store_token_from_uri.lua; body_filter_by_lua_file store_token_from_body.lua; log_by_lua_block { local dispatcher = require "dispatcher" if not dispatcher.initialized() then local ok, err = dispatcher.init { servers = { ["127.0.0.1:" .. ngx.var.server_port] = .99 } } if not ok then ngx.log(ngx.ERR, "failed to initialize the logger: ", err) return end end dispatcher.queue_request(ngx.var.session_token) } } ``` store_token_from_uri.lua ``` ngx.req.read_body() -- Extract the token from the URI if it is present -- add "set $session_token "";" before to initialize variable ngx.ctx.args = ngx.req.get_uri_args() -- If the id argument is present, in the query string, that is our token. if ngx.ctx.args.token then ngx.var.session_token = ngx.ctx.args.token elseif ngx.ctx.args.id then
- pattern minor 112d agoString tokenization and replacing a numbered fieldI created various functions for string manipulation in Lua, where the strings are composed of tokens separated by an ASCII character (which may be the point, comma, semicolon etc.). One of these is the function `puttok()` ``` local function tokenize(C, strng) local sInput = strng or "" local sChar = string.format('%c', C) local tReturn = {} for sWord in string.gmatch(sInput, "[^"..sChar.."]+") do table.insert(tReturn, tonumber(sWord) or sWord) end return tReturn end local function puttok(text,token,N,C) local char = string.format("%c", C) local n local result local tokens = tokenize(C, text) if (N == 0) or (N > #tokens) then result = text end if (N) then n = (N > 0) and N or #tokens + N + 1 table.remove(tokens,n) table.insert(tokens,n,token) result = table.concat(tokens,char) end return result end ``` Where - `text` = string to manipulate - `token` = token (string) we want insert - `N` = position in which will be added to the token - `C` = ASCII code of the token separator This function is to replace a token with another. Here's an example ``` local text = "Violets.are.white" text = puttok(text,"blue",3,46) print(text) —› Violets.are.blue ``` The token "blue" was inserted in position 3 in place of "white," and "Violets" and "are" are respectively in position 1 and 2. The tokens are separated by a dot (.) with ASCII code 46. Is there a way to improve this code? Would metatables be usefull in this case?
- pattern minor 112d agoSum-based sliding rate limiting with Redis and LuaAs I'm new to Redis, I would like to get a review / improvement suggestions from Redis / Lua experts on the following problem and the solution I have found so far. Problem The context is: an e-commerce system used by multiple users purchasing various items at different prices. Because of regulation, user purchases must be capped to a certain amount during a certain sliding period. For example, no more than 10€ can be spent by a purchasing user during a sliding window of 1 week. The problem to solve is: using StackExchange.Redis (Redis client .NET library) and Redis v3, implement a sliding window rate limiting mechanism, based not on max count of requests (many solutions for this particular problem can be found on web), but on a total sum of purchases done during a sliding period. Solution design A single purchase is represented by a purchase ID. It is stored as a string data type with the associated purchase amount (2.5 in the example below). Because we don't need to keep it forever, we'll expire it after 1 week (604800 seconds). ``` SETEX purchaseid:98db31bf9b 604800 2.5 ``` Users and their corresponding purchases are represented by a sorted list where the key is the user ID, scores are numbers of seconds since 1970 (Epoch time), and values are purchase IDs. Likewise, the expiration is one week (renewed with each new purchase): ``` ZADD userid:hello@example.com 1443719939 purchaseid:98db31bf9b EXPIRE userid:hello@example.com 604800 ``` Fig1.: Data model (example) Because several Redis calls might be required to implement this, I used a pre-loaded Lua script (using `EVALSHA`) in order to execute several Redis commands in one shot, so to avoid race conditions and to reduce network exchanges (please correct me if I'm wrong here). Every time a user tries to purchase something, this script is called by the client application, and returns 1 if the purchase is accepted and registered, 0 otherwise. However, I'm not sure how this approach will work in the cont
- pattern minor 112d agomIRC scripting like string token manipulation in LuaI'm trying to reproduce in Lua the mIRC scripting manipulating tokens function: ``` local function tokenize(C, text) local char = string.format("%c", C) local t = {} for w in string.gmatch(tostring(text), "[^"..char.."]+") do w = tonumber(w) or tostring(w) table.insert(t,w) end return t end local function gettok(strng, position, separator, range) local char = string.format("%c", separator) local tokens = tokenize(separator, strng) local result, n, r, start, stop if (position ~= 0) then if (position > 0) then n = position else n = #tokens + position + 1 end if (range) and (position ~= range) then if (range > 0) then r = range elseif (range == 0) or ((n + range) > #tokens) then r = #tokens else r = n + (range + 1) end if (n == r) then result = tokens[i] else start = (r >= n) and n or r stop = (r <= n) and n or r for i = start, stop do result = (not result) and tokens[i] or tostring(result..char..tokens[i]) end end else for i = 1, #tokens do if (i == n) then result = tokens[i] end end end else result = strng end return result end ``` And this is the way it should work: ``` gettok(strng, position, separator, range) ``` Where - `strng` = string to manipulate - `position` = position of the token inside the string. If lesser than 0, it will be considered the position from the last token to the first. If equal to 0, returns the whole string. - `separator` = ASCII code of the token separator - `range` = optional: if specified, returns the token from position to range. If equal to 0, return all tokens from position to the end of the string. ``` local text = "apple.banana.cherry.grape.orange" ``` - apple ``` gettok(text,1,46) ``` - grape ``` gettok(text,-2,46) ``` - banana.cherry.grape ``` gettok(text,2,46,4) ``` - cherry.grape.orange ``` gettok(text,-1,46,-3) ``` Could you
- pattern minor 112d agoPong-like game built in Love2DI just started learning programming in the past two or three months. I started with Python, and now I'm learning lua. I started game programming this week and this is a game I made with the Love2D engine for lua. If you don't know how it works, there are these three main functions: ``` love.load() -- Runs at game startup and doesn't run again unless explicitly called love.update() -- Updates values in the game and runs every tick. It uses delta time as an argument for consistent speed on every machine love.draw() -- Draws the updates to the screen, however you choose for them to be displayed. ``` `love.update()` and `love.draw()` loop back and forth in-between each other. `love.update()` always runs first and then `love.draw()`. This is my first game, a Pong like game where you destroy blocks with a ball bounced off of a paddle like player. I would like less criticism on the game itself, but more on the structure of the code. Please let me know if you see anywhere I could make a function, or achieve something with less code. ``` function love.load() -- WINDOW SETUP love.window.setTitle("Block Buster") height = love.graphics.getHeight() width = love.graphics.getWidth() -- SOUND SOURCES hit = love.audio.newSource("hit.mp3") bounce = love.audio.newSource("bounce.mp3") loss = love.audio.newSource("loss.mp3") -- PLAYER SETUP player = {} function player.load() player.width = 70 player.height = 20 player.x = width/2 - player.width/2 player.y = height - player.height player.speed = 400 player.lives = 5 player.points = 0 end player.load() -- BLOCKS blocks = {} blocks.draw = {} -- LOAD BLOCKS function blocks.load() column = 0; row = 1 while 5 >= row do block = {} block.width = width/10 - 5 block.height = 20 block.x = column * (block.width + 5) block.y = row * (block.height + 5) table.insert(blocks.draw, block) column = column + 1 if column == 1