Break function within local scope

Currently, I want to shorten my code and make my codebase more efficient. I tried making an assert function that stopped the local scope that it was inside of, but it didn’t work and im not sure how to solve this.

voidAssert():

function Package.voidAssert<a>(assertion: a)
	if not assertion then
		return
	end
end

StartEngine():

function Package.StartEngine()
	-- Check if it's already running
	console.voidAssert(CanaryEngineFolder:GetAttribute("EngineStarted"))
	console.voidAssert(RunService:IsServer())
	
	debug.profilebegin("CanaryEngineStart")

	local UserPackages = CanaryEngineFolder.Packages -- the problem is here because the server should only start it, but when the client tries it can't find the folder since it's already reparented.
	local UserAssets = CanaryEngineFolder.Media
	local UserScripts = CanaryEngineFolder.Scripts

Would I have to use coroutines here? I would rather not.

Don’t do this, it overcomplicates your code (nor is it easily possible). Your above example can just be written like so…

local RunService = game:GetService("RunService")

local Package = {}

-- I don't know how you retrieve this, nor do I need to know.
local CanaryEngineFolder = nil

function Package.startEngine(): ()
    if not (RunService:IsServer() and CanaryEngineFolder:GetAttribute("EngineStarted")) then
        return
    end

    -- ...
end

There is also an assert global, however it will throw an error (instead of just returning the caller) so you would need to use pcall and interrupt the call stack, which can cause state issues.

Here’s how >:3

local ResultType = { --Custom Enums yay
    Return = {},
    Continue = {},
    Throw = {},
}

function try(thread)
    local resultType, values
    repeat
        local yielded = {coroutine.resume(thread)} --Or like returned I guess?
        resultType, values = yielded[1], {select(2, table.unpack(yielded))}
        if resultType == ResultType.Throw then
            error(resultType, table.unpack(values)) --hopefully an error message was returned as well?
        end
    until resultType ~= ResultType.Continue
    return table.unpack(values)
end

function startEngine()
    coroutine.yield( trueAssert(RunService:IsServer()) )
    --Yes, this way you have to wrap every function call that can tell this function to return in coroutine.yield.
    coroutine.yield ( ResultType.Return, "Done doin'" )
end

function trueAssert(value)
    if value ~= true then
        return ResultType.Throw, ("Expected true, got %s"):format(tostring(value))
    end
    return ResultType.Continue
end

try(coroutine.create(startEngine))

Haven’t tested it, don’t see why you’d do this xD Just do

if not console.voidAssert(CanaryEngineFolder:GetAttribute("EngineStarted")) return end

the voidAssert does nothing, you would have to throw an error for the code to stop. so just use assert()

Correct me if I’m wrong, but isn’t the first return value of coroutine.resume a boolean?

Anyway, why can’t you simply place coroutine.yield( ... ) within trueAssert?

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.