diff options
| -rw-r--r-- | lua/clever_f/acquisition_service.lua | 64 | ||||
| -rw-r--r-- | tests/run.lua | 18 |
2 files changed, 81 insertions, 1 deletions
diff --git a/lua/clever_f/acquisition_service.lua b/lua/clever_f/acquisition_service.lua index f8181dd..5f15fa1 100644 --- a/lua/clever_f/acquisition_service.lua +++ b/lua/clever_f/acquisition_service.lua @@ -3,15 +3,18 @@ local domain = require("clever_f.domain") local M = {} local AcquisitionRequest = {} local AcquisitionService = {} +local TemporaryResourceScope = {} AcquisitionService.__index = AcquisitionService M.AcquisitionRequest = AcquisitionRequest M.AcquisitionService = AcquisitionService +M.TemporaryResourceScope = TemporaryResourceScope M.RepeatedDirection = { SAME = "same", } local request_records = setmetatable({}, { __mode = "k" }) local service_records = setmetatable({}, { __mode = "k" }) +local scope_records = setmetatable({}, { __mode = "k" }) local function fail(message, level) error(message, (level or 1) + 1) @@ -81,6 +84,44 @@ function AcquisitionRequest:to_table() } end +local scope_metatable = { + __index = function(scope, key) + local method = TemporaryResourceScope[key] + if method ~= nil then + return method + end + return scope_records[scope][key] + end, + __newindex = function() + fail("TemporaryResourceScope values are read-only", 2) + end, + __metatable = "clever_f.acquisition_service.TemporaryResourceScope", +} + +function TemporaryResourceScope.new(request) + if not AcquisitionRequest.is(request) then + fail("temporary resource scope requires an AcquisitionRequest", 2) + end + local scope = setmetatable({}, scope_metatable) + scope_records[scope] = { + request = request, + active = true, + } + return scope +end + +function TemporaryResourceScope.is(value) + return type(value) == "table" and scope_records[value] ~= nil +end + +function TemporaryResourceScope:release() + local record = scope_records[self] + if record == nil then + fail("temporary resource scope is invalid", 2) + end + record.active = false +end + local function normalize_options(options, dependencies) if AcquisitionService.is(options) and dependencies == nil then return options @@ -113,6 +154,8 @@ function AcquisitionService.new(options, dependencies) local service = setmetatable({}, AcquisitionService) service_records[service] = { host = options.host, + last_scope = nil, + started_scope_count = 0, } return service end @@ -125,8 +168,27 @@ function AcquisitionService:request(descriptor, context, position, count, macro_ return AcquisitionRequest.new(descriptor, context, position, count, macro_state) end +function AcquisitionService:start_temporary_scope(request) + request = AcquisitionRequest.new(request) + local record = service_records[self] + local scope = TemporaryResourceScope.new(request) + record.last_scope = scope + record.started_scope_count = record.started_scope_count + 1 + return scope +end + +function AcquisitionService:last_temporary_scope() + return service_records[self].last_scope +end + +function AcquisitionService:started_scope_count() + return service_records[self].started_scope_count +end + function AcquisitionService:acquire(descriptor, context, position, count, macro_state) - return self:request(descriptor, context, position, count, macro_state) + local request = self:request(descriptor, context, position, count, macro_state) + self:start_temporary_scope(request) + return request end function M.new(options, dependencies) diff --git a/tests/run.lua b/tests/run.lua index ce8c1b6..951210a 100644 --- a/tests/run.lua +++ b/tests/run.lua @@ -4896,6 +4896,24 @@ test("Acquisition accepts complete initiating action inputs", function() falsy(from_table.macro_state.executing) end) +test("Acquisition starts one temporary resource scope", function() + local service = acquisition_service.new(MemoryHost.new()) + local request = service:acquire( + "f", + "n", + domain.Position.new(1, 1), + 1, + nil + ) + local scope = service:last_temporary_scope() + + truthy(acquisition_service.AcquisitionRequest.is(request)) + truthy(acquisition_service.TemporaryResourceScope.is(scope)) + same(request, scope.request) + truthy(scope.active) + same(1, service:started_scope_count()) +end) + for _, item in ipairs(tests) do local ok, failure = xpcall(item.body, debug.traceback) if not ok then |
