diff --git a/modpol/api.lua b/modpol/api.lua
index 8c2bc48..f5e04e6 100644
--- a/modpol/api.lua
+++ b/modpol/api.lua
@@ -13,7 +13,9 @@ dofile (localdir .. "/orgs/process.lua")
dofile (localdir .. "/interactions/interactions.lua")
--modules
+--TODO make this automatic and directory-based
+dofile (localdir .. "/modules/add_child_org.lua")
dofile (localdir .. "/modules/consent.lua")
dofile (localdir .. "/modules/join_org_consent.lua")
dofile (localdir .. "/modules/remove_org_consent.lua")
---dofile (localdir .. "/modules/child_org.lua")
+dofile (localdir .. "/modules/remove_org.lua")
diff --git a/modpol/interactions/interactions.lua b/modpol/interactions/interactions.lua
index 5e2bddf..b198e4f 100644
--- a/modpol/interactions/interactions.lua
+++ b/modpol/interactions/interactions.lua
@@ -34,17 +34,16 @@ function modpol.interactions.dashboard(user)
print('All users: ' .. table.concat(all_users, ', '))
print()
- print('Access which org?')
-
+ print('Access which org id?')
local sel = io.read()
print()
if modpol.orgs.array[tonumber(sel)] then
local sel_org = modpol.orgs.array[tonumber(sel)].name
+ modpol.interactions.org_dashboard(user, sel_org)
else
- return
+ print("Org id not found.")
end
- modpol.interactions.org_dashboard(user, sel_org)
end
@@ -72,8 +71,8 @@ function modpol.interactions.org_dashboard(user, org_name)
-- list available modules
local org_modules = {}
- for k,v in ipairs(org.modules) do
- table.insert(org_modules, org.modules[k].slug)
+ for k,v in pairs(org.modules) do
+ table.insert(org_modules, v.slug)
end
-- list pending actions
@@ -136,6 +135,7 @@ function modpol.interactions.org_dashboard(user, org_name)
end
else
print("Command not found")
+ modpol.interactions.org_dashboard(user, org_name)
end
end
@@ -230,6 +230,13 @@ end
-- Function: modpol.interactions.message_org
-- input: initiator (string), org_id (number), message (string)
-- output: broadcasts message to all org members
+function modpol.interactions.message_org(initiator, org_id, message)
+ local org = modpol.orgs.get_org(org_id)
+ local users = org:list_members()
+ for k,v in ipairs(users) do
+ modpol.interactions.message(v, message)
+ end
+end
-- Function: modpol.interactions.binary_poll_org
-- input: initator (user string), org_id (number)
diff --git a/modpol/modules/add_child_org.lua b/modpol/modules/add_child_org.lua
new file mode 100644
index 0000000..bad73b3
--- /dev/null
+++ b/modpol/modules/add_child_org.lua
@@ -0,0 +1,29 @@
+--- @module add_child_org
+-- Adds a child org
+
+local add_child_org = {
+ name = "Add child org",
+ slug = "add_child_org",
+ desc = "Create a child org within the current one"
+}
+add_child_org.data = {
+}
+add_child_org.config = {
+}
+
+-- @function initiate
+function add_child_org:initiate(result)
+ modpol.interactions.text_query(
+ self.initiator,"Child org name: ",
+ function(input)
+ self.org:add_org(input, self.initiator)
+ modpol.interactions.message_org(
+ self.initiator,
+ self.org.id,
+ "Child org created: "..input)
+ modpol.interactions.dashboard(self.initiator)
+ end)
+end
+
+--- (Required) Add to module table
+modpol.modules.add_child_org = add_child_org
diff --git a/modpol/modules/child_org.lua b/modpol/modules/child_org.lua
deleted file mode 100644
index 8a1631a..0000000
--- a/modpol/modules/child_org.lua
+++ /dev/null
@@ -1,32 +0,0 @@
--- CHILD_ORG
--- Module that enables user to create child in current org
-
--- Initial configuration
-modpol.modules.child_org = {}
-modpol.modules.child_org.name = "Create child org"
-
-
--- == REQUEST ==
-
--- Initialization function
--- function: modpol.modules.child_org:initialize
-
-
--- gather data from initiator: child org name, comment
-
--- function: modpol.modules.child_org:request
-
-
-
--- == CONSENT ==
-
--- function: modpol.orgs:consent(process_id, result_function)
--- the result function should begin the completion process below
-
-
-
--- == COMPLETION ==
-
--- if approved/if failed functions?
-
--- function: modpol.modules.child_org.create(initiator, parent_org, child_org)
diff --git a/modpol/modules/consent.lua b/modpol/modules/consent.lua
index e7d22b3..03983a6 100644
--- a/modpol/modules/consent.lua
+++ b/modpol/modules/consent.lua
@@ -1,42 +1,52 @@
+--- @module consent
+-- A utility module for checking consent
-
-Consent = {}
-
-Consent.setup = {
+local consent = {
name = "Consent",
slug = "consent",
desc = "Other modules can use to implement consent based decision making",
+}
+
+consent.data = {
votes = 0
}
-Consent.config = {
- prompt = "Would you like to approve this action?",
+consent.config = {
+ prompt = "Do you consent?",
votes_required = 1
}
-function Consent:initiate(result)
- self.result = result
- for id, member in pairs(self.org.members) do
- self.org:add_pending_action(self.id, member, "callback")
- end
+function consent:initiate(result)
+ self.result = result
+ -- if org is empty, consent is given automatically
+ if self.org:get_member_count() == 0 then
+ self.result()
+ self.org:wipe_pending_actions(self.id)
+ else
+ -- otherwise, create poll
+ for id, member in pairs(self.org.members) do
+ self.org:add_pending_action(self.id, member, "callback")
+ end
+ end
end
-function Consent:callback(member)
+function consent:callback(member)
modpol.interactions.binary_poll_user(
member,
self.config.prompt,
function (resp)
- if resp == "Yes" then
- self.votes = self.votes + 1
- end
+ self.org:remove_pending_action(self.id,member)
+ if resp == "Yes" then
+ self.data.votes = self.data.votes + 1
+ end
- if self.votes >= self.config.votes_required then
- self.result()
- self.org:wipe_pending_actions(self.id)
- end
+ if self.data.votes >= self.config.votes_required then
+ if self.result then self.result() end
+ self.org:wipe_pending_actions(self.id)
+ end
end
)
end
-modpol.modules.consent = Consent
+modpol.modules.consent = consent
diff --git a/modpol/modules/join_org_consent.lua b/modpol/modules/join_org_consent.lua
index d126fd5..9228dc7 100644
--- a/modpol/modules/join_org_consent.lua
+++ b/modpol/modules/join_org_consent.lua
@@ -2,14 +2,18 @@
-- A simple module that calls a consent process on an org to add a member.
-- Depends on the Consent module.
-join_org_consent = {}
-
-join_org_consent.setup = {
+local join_org_consent = {
name = "Join this org",
slug = "join_org_consent",
desc = "Adds member with consent of all members."
}
+join_org_consent.data = {
+}
+
+join_org_consent.config = {
+}
+
function join_org_consent:initiate()
self.org:call_module(
"consent",
diff --git a/modpol/modules/remove_org.lua b/modpol/modules/remove_org.lua
index ae9bbdc..590771d 100644
--- a/modpol/modules/remove_org.lua
+++ b/modpol/modules/remove_org.lua
@@ -1,22 +1,27 @@
---- Remove Org
+--- @module Remove Org
-- A simple module that calls a consent process on an org to remove it.
--- Depends on the Consent module.
-remove_org = {}
---- (Required): setup table containing name and description of the module
-remove_org.setup = {
+
+--- Main module table
+remove_org = {
name = "Remove this org",
slug = "remove_org",
desc = "Removes an org if all members consent."
}
+remove_org.config = {}
+remove_org.data = {}
+
--- Initiate function
---
self.org
(the org the module was called in),
--- self.initiator
(the user that callced the module),
--- self.id
(the process id of the module instance)
-- @function initiate
function remove_org:initiate(config, result)
-
+ modpol.interactions.message_org(
+ self.initiator,self.org.id,
+ "Removing org: "..self.org.name)
+ self.org:delete()
+ modpol.interactions.dashboard(self.initiator)
-- call result function
if result then result() end
end
+
+modpol.modules.remove_org = remove_org
diff --git a/modpol/modules/remove_org_consent.lua b/modpol/modules/remove_org_consent.lua
index 9574901..de5c305 100644
--- a/modpol/modules/remove_org_consent.lua
+++ b/modpol/modules/remove_org_consent.lua
@@ -1,31 +1,39 @@
--- Remove org (consent)
-- A simple module that calls a consent process on an org to remove it.
-- Depends on the Consent module.
-remove_org_consent = {}
-remove_org_consent.setup = {
+local remove_org_consent = {
name = "Remove this org",
- slug = "remove_org",
+ slug = "remove_org_consent",
desc = "Removes an org if all members consent."
}
+remove_org_consent.data = {
+}
+
+remove_org_consent.config = {
+}
+
function remove_org_consent:initiate()
self.org:call_module(
"consent",
self.initiator,
{
- prompt = "Remove org " .. self.org.name .. "?",
- votes_required = #self.org.members
+ prompt = "Remove org " .. self.org.name .. "?",
+ votes_required = #self.org.members
},
- function ()
- self:complete()
+ function ()
+ self:complete()
end
)
end
-function join_org_consent:complete()
- self.org:delete()
- print("Removed org " .. self.org.name .. ".")
+function remove_org_consent:complete()
+ modpol.interactions.message_org(
+ self.initiator, self.org.id,
+ "Removing org: " .. self.org.name)
+ self.org:delete()
+ modpol.interactions.dashboard(self.initiator)
end
modpol.modules.remove_org_consent = remove_org_consent
diff --git a/modpol/modules/template.lua b/modpol/modules/template.lua
index 777f8f6..7358e57 100644
--- a/modpol/modules/template.lua
+++ b/modpol/modules/template.lua
@@ -1,26 +1,31 @@
---- Template for modules
--- function initiate and table setup are required as a base.
--- @module Template
-Template = {}
+--- module_template
+-- @module module_template
---- (Required): setup table containing name and description of the module
--- @field name "Module Human-Readable Name"
--- @field slug "Template" same as module name
+--- (Required): data table containing name and description of the module
+-- @field name "Human-readable name"
+-- @field slug "Same as module class name"
-- @field desc "Description of the module"
-Template.setup = {
+local module_template = {
name = "Module Human-Readable Name",
- slug = "Template",
+ slug = "template",
desc = "Description of the module"
}
---- (Optional): config for module
+--- (Required) Data for module
+-- Variables that module uses during the course of a process
+-- Can be blank
+module_template.data = {
+}
+
+--- (Required): config for module
-- Defines the input parameters to the module initiate function.
+-- Can be blank
-- When calling a module from within another module,
-- variables not defined in config will be ignored.
-- Default values set in config can be overridden
-- @field field_1 ex: votes_required, default = 5
-- @field field_2 ex: voting_type, default = "majority"
-Template.config = {
+module_template.config = {
field_1 = 5
field_2 = "majority"
}
@@ -33,9 +38,12 @@ Template.config = {
-- @param config (optional) If user wants to override fields in the config table
-- @param result (optional) Callback if this module is embedded in other modules
-- @function initiate
-function Template:initiate(config, result)
+function module_template:initiate(config, result)
-- call interaction functions here!
-- call result function
if result then result() end
end
+
+--- (Required) Add to module table
+modpol.modules.module_template = module_template
diff --git a/modpol/orgs/base.lua b/modpol/orgs/base.lua
index 2211e6e..27acf66 100644
--- a/modpol/orgs/base.lua
+++ b/modpol/orgs/base.lua
@@ -1,3 +1,6 @@
+--- Orgs: Base
+-- Basic functions for orgs
+
modpol.orgs = modpol.orgs or
{
count = 1,
@@ -171,7 +174,8 @@ function modpol.orgs:add_org(name, user)
child_org.id = modpol.orgs.count
child_org.name = name
child_org.parent = self.id
- child_org.processes = self.processes
+ child_org.processes = {}
+ child_org.modules = self.modules
setmetatable(child_org, modpol.orgs)
diff --git a/modpol/orgs/process.lua b/modpol/orgs/process.lua
index 38c10b6..8f20761 100644
--- a/modpol/orgs/process.lua
+++ b/modpol/orgs/process.lua
@@ -1,6 +1,8 @@
-function modpol.orgs:call_module(module_name, initiator, config, result)
- if not modpol.modules[module_name] then
- modpol.ocutil.log('Error in ' .. self.name .. ':call_module -> module "' .. module_name .. '" not found')
+--- Process functions for orgs
+
+function modpol.orgs:call_module(module_slug, initiator, config, result)
+ if not modpol.modules[module_slug] then
+ modpol.ocutil.log('Error in ' .. self.name .. ':call_module -> module "' .. module_slug .. '" not found')
return
end
@@ -21,10 +23,10 @@ function modpol.orgs:call_module(module_name, initiator, config, result)
index = #self.processes + 1
end
- local module = modpol.modules[module_name]
+ local module = modpol.modules[module_slug]
-- sets default values for undeclared config variables
- if module.config then
+ if #module.config > 0 then
for k, v in pairs(module.config) do
if config[k] == nil then
config[k] = v
@@ -39,14 +41,10 @@ function modpol.orgs:call_module(module_name, initiator, config, result)
org = self,
id = index,
config = config,
- name = module_name
+ data = module.data,
+ slug = module_slug
}
- -- copying default fields from setup
- for k, v in pairs(module.setup) do
- new_process[k] = v
- end
-
setmetatable(new_process, new_process.metatable)
self.processes[index] = new_process
@@ -76,7 +74,7 @@ function modpol.orgs:wipe_pending_actions(process_id)
end
end
-function modpol.orgs:has_pending_actions()
+function modpol.orgs:has_pending_actions(user)
-- next() will return the next pair in a table
-- if next() returns nil, the table is empty
if not self.pending[user] then
@@ -91,11 +89,14 @@ function modpol.orgs:has_pending_actions()
end
function modpol.orgs:interact(process_id, user)
- local process = self.processes[process_id]
- if self.pending[user] then
- local callback = self.pending[user][process_id]
- if callback then
- process[callback](process, user)
- end
- end
+ local process = self.processes[process_id]
+ modpol.interactions.message(user,"hi!")
+ if self.pending[user] then
+ modpol.interactions.message(user,"id: "..process_id)
+ local callback = self.pending[user][process_id]
+ if callback then
+ modpol.interactions.message(user,"la!")
+ process[callback](process, user)
+ end
+ end
end
diff --git a/modpol_minetest/overrides/interactions.lua b/modpol_minetest/overrides/interactions.lua
index b109a36..5a12989 100644
--- a/modpol_minetest/overrides/interactions.lua
+++ b/modpol_minetest/overrides/interactions.lua
@@ -59,10 +59,7 @@ function modpol.interactions.dashboard(user)
"dropdown[2,2.5;5,0.8;user_orgs;"..formspec_list(user_orgs)..";;]",
"label[0.5,4;All users:]",
"dropdown[2,3.5;5,0.8;all_users;"..formspec_list(all_users)..";;]",
- "button[0.5,7;1,0.8;test_poll;Test poll]",
- "button[2,7;1,0.8;add_org;Add org]",
- "button[3.5,7;1.5,0.8;remove_org;Remove org]",
- "button[5.5,7;1.5,0.8;reset_orgs;Reset orgs]",
+ "button[0.5,7;1.5,0.8;reset_orgs;Reset orgs]",
"button_exit[8.5,7;1,0.8;close;Close]",
}
local formspec_string = table.concat(formspec, "")
@@ -75,22 +72,6 @@ minetest.register_on_player_receive_fields(function (player, formname, fields)
local pname = player:get_player_name()
if nil then
-- buttons first
- elseif fields.test_poll then
- -- FOR TESTING PURPOSES ONLY
- modpol.interactions.text_query(
- pname,"Poll question:",
- function(input)
- modpol.interactions.binary_poll_user(
- pname, input,
- function(vote)
- modpol.interactions.message(
- pname, pname .. " voted " .. vote)
- end)
- end)
- elseif fields.add_org then
- modpol.interactions.add_org(pname, 1)
- elseif fields.remove_org then
- modpol.interactions.remove_org(pname)
elseif fields.reset_orgs then
modpol.orgs.reset()
modpol.instance:add_member(pname)
@@ -144,18 +125,20 @@ function modpol.interactions.org_dashboard(user, org_name)
-- prepare modules menu
local modules = {"View..."}
if org.modules then
- for k,v in ipairs(org.modules) do
- table.insert(modules, org.modules[k].slug)
+ for k,v in pairs(org.modules) do
+ table.insert(modules, v.slug)
end
end
-- prepare actions menu
local actions = {"View..."}
+ local num_actions = 0
if org.pending[user] then
for k,v in pairs(org.pending[user]) do
local action_string = "[" .. k .. "] " ..
- org.processes[k].name
+ org.processes[k].name
table.insert(actions, action_string)
+ num_actions = num_actions + 1
end
end
@@ -177,7 +160,7 @@ function modpol.interactions.org_dashboard(user, org_name)
"dropdown[2,2.5;5,0.8;children;"..formspec_list(children)..";;]",
"label[0.5,4;Modules:]",
"dropdown[2,3.5;5,0.8;modules;"..formspec_list(modules)..";;]",
- "label[0.5,5;Actions:]",
+ "label[0.5,5;Actions ("..num_actions.."):]",
"dropdown[2,4.5;5,0.8;actions;"..formspec_list(actions)..";;]",
"button[0.5,7;1,0.8;test_poll;Test poll]",
"button[2,7;1,0.8;add_child;Add child]",
@@ -195,12 +178,7 @@ minetest.register_on_player_receive_fields(function (player, formname, fields)
local org = modpol.orgs.get_org(_contexts[pname].current_org)
if nil then
elseif fields.join then
- local new_request = {
- user = pname,
- type = "add_member",
- params = {pname}
- }
- org:make_request(new_request)
+ org:add_member(pname)
modpol.interactions.org_dashboard(pname,org.name)
elseif fields.leave then
org:remove_member(pname)
@@ -217,24 +195,19 @@ minetest.register_on_player_receive_fields(function (player, formname, fields)
elseif fields.add_child then
modpol.interactions.text_query(
pname, "Child org name:",
- function(input)
- local new_request = {
- user = pname,
- type = "add_org",
- params = {input}
- }
- org:make_request(new_request)
- modpol.interactions.message(pname,"requested")
- modpol.interactions.org_dashboard(
- pname,org.name)
+ function(input)
+ org:add_org(input,pname)
+ modpol.interactions.message_org(
+ pname,
+ org.id,
+ "Child org created: " .. input)
end)
elseif fields.remove_org then
- local new_request = {
- user = pname,
- type = "delete",
- params = {}
- }
- org:make_request(new_request)
+ modpol.interactions.message_org(
+ pname,
+ org.id,
+ "Removing org: " .. org.name)
+ org:delete()
modpol.interactions.org_dashboard(pname,org.name)
elseif fields.back then
modpol.interactions.dashboard(pname)
@@ -244,8 +217,9 @@ minetest.register_on_player_receive_fields(function (player, formname, fields)
elseif fields.modules
and fields.modules ~= "View..." then
local module = fields.modules
- org:call_module(module, user)
-
+ org:call_module(module, pname)
+ modpol.interactions.org_dashboard(pname,org.name)
+
-- Receiving actions
elseif fields.actions
and fields.actions ~= "View..." then
@@ -253,7 +227,7 @@ minetest.register_on_player_receive_fields(function (player, formname, fields)
fields.actions,"%[(%d)%]")
local process = org.processes[tonumber(action)]
if process then
- org:interact(process, user)
+ org:interact(process.id, pname)
end
-- Children
@@ -282,8 +256,8 @@ end
-- ===========================
-- Function: modpol.interactions.message
--- input: message (string)
--- output
+-- input: user (string), message (string)
+-- output: displays message to specified user
function modpol.interactions.message(user, message)
minetest.chat_send_player(user, message)
end
@@ -291,7 +265,6 @@ end
-- Function: modpol.interactions.text_query
-- Overrides function at modpol/interactions.lua
-- input: user (string), query (string), func (function)
--- func input: user input (string)
-- output: Applies "func" to user input
function modpol.interactions.text_query(user, query, func)
-- set up formspec
@@ -303,7 +276,7 @@ function modpol.interactions.text_query(user, query, func)
"button[0.5,2.5;1,0.8;yes;OK]",
}
local formspec_string = table.concat(formspec, "")
- -- present to players
+ -- present to player
minetest.show_formspec(user, "modpol:text_query", formspec_string)
-- put func in _contexts
if _contexts[user] == nil then _contexts[user] = {} end
@@ -367,10 +340,6 @@ minetest.register_on_player_receive_fields(function (player, formname, fields)
end
end)
-
--- SECONDARY INTERACTIONS
--- ======================
-
-- Function: modpol.binary_poll_user(user, question, function)
-- Overrides function at modpol/interactions.lua
-- Params: user (string), question (string), func (function)
@@ -384,8 +353,8 @@ function modpol.interactions.binary_poll_user(user, question, func)
"label[0.375,0.5;",minetest.formspec_escape(question), "]",
"button[1,1.5;1,0.8;yes;Yes]",
"button[2,1.5;1,0.8;no;No]",
- --TKTK can we enable text wrapping?
- --TKTK we could use scroll boxes to contain the text
+ --TODO can we enable text wrapping?
+ --TODO we could use scroll boxes to contain the text
}
local formspec_string = table.concat(formspec, "")
if _contexts[user] == nil then _contexts[user] = {} end
@@ -409,71 +378,3 @@ minetest.register_on_player_receive_fields(function (player, formname, fields)
minetest.close_formspec(pname, formname)
end
end)
-
--- COMPLEX INTERACTIONS
--- ====================
-
--- Function: modpol.interactions.message_org
--- input: initiator (string), org_id (number), message (string)
--- output: broadcasts message to all org members
-function modpol.interactions.message_org(initiator, org_id, message)
- local org = modpol.orgs.get_org(org_id)
- local users = org:list_members()
- for k,v in ipairs(users) do
- modpol.interactions.message(v, message)
- end
-end
-
-
--- Function: modpol.interactions.binary_poll_org
--- input: initator (user string), org_id (number)
--- output: gets question from initiator, asks all org members, broadcasts answers
--- TODO for testing. This should be implemented as a request.
-function modpol.interactions.binary_poll_org(initiator, org_id, func)
- local org = modpol.orgs.get_org(org_id)
- local users = org:list_members()
- modpol.interactions.text_query(
- initiator, "Yes/no poll question:",
- function(input)
- for k,v in ipairs(users) do
- modpol.interactions.binary_poll_user(v, input, func)
- end
- end)
-end
-
--- Function: modpol.interactions.add_org
--- input: initator (user string), base_org_id (ID)
--- output: interaction begins
--- GODMODE
-function modpol.interactions.add_org(user, base_org_id)
- modpol.interactions.text_query(
- user,"Org name:",
- function(input)
- local base_org = modpol.orgs.get_org(1)
- local result = base_org:add_org(input, user)
- local message = input .. " created"
- modpol.interactions.message(user, message)
- modpol.interactions.dashboard(user)
- end)
-end
-
--- Function: modpol.interactions.remove_org
--- input: initator (user string)
--- output: interaction begins
--- GODMODE
-function modpol.interactions.remove_org(user)
- -- start formspec
- local orgs_list = modpol.orgs.list_all()
- local label = "Choose an org to remove:"
- modpol.interactions.dropdown_query(
- user, label, orgs_list,
- function(input)
- if input then
- local target_org = modpol.orgs.get_org(input)
- local result = target_org:delete()
- local message = input .. " deleted"
- modpol.interactions.message(user, message)
- end
- modpol.interactions.dashboard(user)
- end)
-end