Add files via upload

This commit is contained in:
Gerold55 2017-12-12 21:32:17 -05:00 committed by GitHub
parent db8886ef3b
commit 0a2c8d6e37
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 208 additions and 57 deletions

16
API.md
View File

@ -8,6 +8,7 @@
- `hwdef.sequence = { "variant_1_name", "variant_2_name", "variant_3_name" }` On punch swaps sequence. the first variant is in creative inventory
- `hwdef.custom_launcer` - optional - custom launcher name
- `hwdef.custom_theme` - optional - custom initial theme name
- `hwdef.removable_capability` - optional. Table with compatible removable groups. Supported "floppy" or "usb". Default { "floppy", "usb" }
- `hwdef.node_defs = {
variant_1_name = {
hw_state = "resume", "power_on" or "power_off", -- Hardware state
@ -38,10 +39,10 @@ Usable from node functions, from apps or outsite
- `mtos:save()` - Store all app-data to nodemeta. Called mostly internally so no explicit call necessary
- `mtos:get_app(appname)`- Get the app instance
- `mtos:set_app(appname)` - Start/Enable/navigate to appname. If no appname given the launcher is called
- `mtos:receive_fields(fields, sender)` - Should be called from node.on_receive_fields to get the apps interactive
- `mtos:get_theme(theme)`- Get theme data current or requested (theme parameter is optional)
- `mtos:set_theme(theme)`- Activate theme
- `mtos:get_removable_data(media_type)` - Access to the item in node inventory (low-level). if media_type is given (item type "usb" or "floppy", or os_format) the method returns only if the type matches
- `mtos:set_removable_data()` - Store changes on low-level removable data
## App Definition
`laptop.register_app(internal_shortname, { definitiontable })` - add a new app or view
@ -52,7 +53,7 @@ Usable from node functions, from apps or outsite
- `view` - (boolean) The definition is a view. That means the app/view is not visible in launcher
- `formspec_func(app, mtos)` - Function, should return the app formspec (mandatory) During definition the "app" and the "mtos" are available
- `appwindow_formspec_func(launcher_app, app, mtos)`- Only custom launcher app: App background / Window decorations and buttons
- `receive_fields_func(app, mtos, fields, sender)` Function for input processing. The "app" and the "mtos" are available inside the call
- `receive_fields_func(app, mtos, sender, fields)` Function for input processing. The "app" and the "mtos" are available inside the call
`laptop.register_view(internal_shortname, { definitiontable })` - add a new app or view
same as register_app, but the view flag is set. app_name and app_icon not necessary
@ -78,3 +79,12 @@ Definitiontable:
`function laptop.get_theme(theme_name)`
- `theme:get_button(area, prefix, code, text)` get a themed [prefix]_button in area 'x,y;w,h' with code an text
- `theme:get_label(pos, text)` get a themed label text starting at pos 'x,y'
## Low-level Removable data
`data = mtos:get_removable_data()`
- `label` - Meda label. Item name by default
- `def` - Registered item definition (read-only)
- `inv` - node inventory
- `stack` - The item stack
- `meta` - Stack metadata
- `os_format`- The format type: "none", "OldOS", "backup", "filesystem" (read-only)

View File

@ -29,16 +29,20 @@ function app_class:get_formspec()
end
-- internally used: process input
function app_class:receive_fields(fields, sender)
function app_class:receive_data(method, reshow, sender, ...)
local ret
if self.receive_fields_func then
ret = self.receive_fields_func(self, self.os, fields, sender)
if self[method] then
ret = self[method](self, self.os, sender, ...)
end
if fields.os_back then
self:back_app()
elseif fields.os_exit then
self:exit_app()
if method == "receive_fields_func" then
local fields = ...
if fields.os_back then
self:back_app()
elseif fields.os_exit then
self:exit_app()
end
end
return ret
end

View File

@ -6,7 +6,7 @@ laptop.register_app("demo1", {
formspec_func = function(app, mtos)
return mtos.theme:get_button('5,5;3,1', 'major', 'next', 'Second screen')
end,
receive_fields_func = function(app, mtos, fields, sender)
receive_fields_func = function(app, mtos, sender, fields)
if fields.next then
mtos:set_app("demo1_view2")
end
@ -18,7 +18,7 @@ laptop.register_view("demo1_view2", {
formspec_func = function(app, mtos)
return mtos.theme:get_label('1,5', "Use the framework buttons to navigate back or cancel")
end,
receive_fields_func = function(app, mtos, fields, sender)
receive_fields_func = function(app, mtos, sender, fields)
end
})
@ -32,7 +32,7 @@ laptop.register_app("demo2", {
return 'button[3,1;5,1;count;Click: '..data.counter..']'..
'button[3,3;5,1;back;Back to launcher]'
end,
receive_fields_func = function(app, mtos, fields, sender)
receive_fields_func = function(app, mtos, sender, fields)
if fields.count then
local data = app:get_storage_ref()
data.counter = data.counter + 1

View File

@ -5,6 +5,7 @@ dofile(minetest.get_modpath('laptop')..'/app_fw.lua')
dofile(minetest.get_modpath('laptop')..'/os.lua')
dofile(minetest.get_modpath('laptop')..'/node_fw.lua')
dofile(minetest.get_modpath('laptop')..'/nodes.lua')
dofile(minetest.get_modpath('laptop')..'/items.lua')
-- uncomment this line to disable demo apps in production
--dofile(minetest.get_modpath('laptop')..'/demo_apps.lua')

14
items.lua Normal file
View File

@ -0,0 +1,14 @@
minetest.register_craftitem("laptop:floppy", {
description = 'High density floppy',
inventory_image = "laptop_diskette.png",
groups = {laptop_removable_floppy = 1},
stack_max = 1,
})
minetest.register_craftitem("laptop:usbstick", {
description = 'USB storage stick',
inventory_image = "laptop_usb.png",
groups = {laptop_removable_usb = 1},
stack_max = 1,
})

View File

@ -2,29 +2,29 @@
laptop.node_config = {}
local function after_place_node(pos, placer, itemstack, pointed_thing)
local appdata = minetest.deserialize(itemstack:get_meta():get_string("laptop_appdata"))
if appdata then
local mtos = laptop.os_get(pos)
mtos.appdata = appdata
mtos.appdata.launcher = mtos.appdata.launcher or {}
mtos.appdata.os = mtos.appdata.os or {}
mtos.appdata.os.stack = mtos.appdata.os.stack or {}
mtos:save()
local save = minetest.deserialize(itemstack:get_meta():get_string("laptop_metadata"))
if save then
local meta = minetest.get_meta(pos)
meta:from_table(save.fields)
meta:get_inventory():set_list("main", save.invlist)
end
end
local function after_dig_node(pos, oldnode, oldmetadata, digger)
local appdata = oldmetadata.fields['laptop_appdata']
if appdata then
local item_name = minetest.registered_items[oldnode.name].drop or oldnode.name
local inventory = digger:get_inventory()
for idx = inventory:get_size("main"), 1, -1 do
local stack = inventory:get_stack("main", idx)
if stack:get_name() == item_name and stack:get_meta():get_string("laptop_appdata") == "" then
stack:get_meta():set_string("laptop_appdata", appdata)
digger:get_inventory():set_stack("main", idx, stack)
break
end
local save = { fields = oldmetadata.fields, invlist = {} }
if oldmetadata.inventory and oldmetadata.inventory.main then
for _, stack in ipairs(oldmetadata.inventory.main) do
table.insert(save.invlist, stack:to_string())
end
end
local item_name = minetest.registered_items[oldnode.name].drop or oldnode.name
local inventory = digger:get_inventory()
for idx, stack in ipairs(inventory:get_list("main")) do
if stack:get_name() == item_name and stack:get_meta():get_string("laptop_metadata") == "" then
stack:get_meta():set_string("laptop_metadata", minetest.serialize(save))
digger:get_inventory():set_stack("main", idx, stack)
break
end
end
end
@ -45,6 +45,7 @@ local function on_construct(pos)
end
local function on_punch(pos, node, puncher)
-- TODO: Check if wielded item is an removable. Replace stack in this case
local mtos = laptop.os_get(pos)
local hwdef = laptop.node_config[node.name]
if hwdef.next_node then
@ -61,7 +62,47 @@ end
local function on_receive_fields(pos, formname, fields, sender)
local mtos = laptop.os_get(pos)
mtos:receive_fields(fields, sender)
mtos:pass_to_app("receive_fields_func", true, sender, fields)
end
local function allow_metadata_inventory_move(pos, from_list, from_index, to_list, to_index, count, player)
local mtos = laptop.os_get(pos)
return mtos:pass_to_app("allow_metadata_inventory_move", false, player, from_list, from_index, to_list, to_index, count) or 0
end
local function allow_metadata_inventory_put(pos, listname, index, stack, player)
local mtos = laptop.os_get(pos)
local def = stack:get_definition()
local allowed_stacksize = 0
if def then
local supported = mtos.hwdef.removable_capability or {"usb", "floppy"}
for _, cap in ipairs(supported) do
if def.groups["laptop_removable_"..cap] then
allowed_stacksize = 1
end
end
end
return mtos:pass_to_app("allow_metadata_inventory_put", false, player, listname, index, stack) or allowed_stacksize
end
local function allow_metadata_inventory_take(pos, listname, index, stack, player)
local mtos = laptop.os_get(pos)
return mtos:pass_to_app("allow_metadata_inventory_take", false, player, listname, index, stack) or 1 -- by default removal allowed
end
local function on_metadata_inventory_move(pos, from_list, from_index, to_list, to_index, count, player)
local mtos = laptop.os_get(pos)
mtos:pass_to_app("on_metadata_inventory_move", true, player, from_list, from_index, to_list, to_index, count)
end
local function on_metadata_inventory_put(pos, listname, index, stack, player)
local mtos = laptop.os_get(pos)
mtos:pass_to_app("on_metadata_inventory_put", true, player, listname, index, stack)
end
local function on_metadata_inventory_take(pos, listname, index, stack, player)
local mtos = laptop.os_get(pos)
mtos:pass_to_app("on_metadata_inventory_take", true, player, listname, index, stack)
end
function laptop.register_hardware(name, hwdef)
@ -89,6 +130,12 @@ function laptop.register_hardware(name, hwdef)
def.on_punch = on_punch
def.on_construct = on_construct
def.on_receive_fields = on_receive_fields
def.allow_metadata_inventory_move = allow_metadata_inventory_move
def.allow_metadata_inventory_put = allow_metadata_inventory_put
def.allow_metadata_inventory_take = allow_metadata_inventory_take
def.on_metadata_inventory_move = on_metadata_inventory_move
def.on_metadata_inventory_put = on_metadata_inventory_put
def.on_metadata_inventory_take = on_metadata_inventory_take
minetest.register_node(nodename, def)
-- set node configuration for hooks

122
os.lua
View File

@ -10,31 +10,30 @@ local mod_storage = minetest.get_mod_storage()
-- Swap the node
function os_class:swap_node(new_node_name)
local node = minetest.get_node(self.pos)
node.name = new_node_name
if new_node_name then
node.name = new_node_name
end
local fdir = math.floor(node.param2 % 32)
node.param2 = fdir + self.theme.node_color * 32
print("swap to", dump(node)) --TODO:remove
minetest.swap_node(self.pos, node)
end
-- Power on the system and start the launcher
function os_class:power_on(new_node_name)
if new_node_name then
self:swap_node(new_node_name)
end
self:swap_node(new_node_name)
self:set_app() --launcher
end
-- Power on the system / and resume last running app
function os_class:resume(new_node_name)
if new_node_name then
self:swap_node(new_node_name)
end
self:swap_node(new_node_name)
self:set_app(self.appdata.os.current_app)
end
-- Power off the system
function os_class:power_off(new_node_name)
if new_node_name then
self:swap_node(new_node_name)
end
self:swap_node(new_node_name)
self.meta:set_string('formspec', "")
self:save()
end
@ -44,17 +43,6 @@ function os_class:set_infotext(infotext)
self.meta:set_string('infotext', infotext)
end
-- Save the data
function os_class:save()
self.meta:set_string('laptop_appdata', minetest.serialize(self.appdata))
if self.cloud_store then
for store, value in pairs(self.cloud_store) do
mod_storage:set_string(store, minetest.serialize(value))
end
self.cloud_store = nil
end
end
-- Get given or current theme
function os_class:get_theme(theme)
local theme_sel = theme or self.appdata.os.theme
@ -67,6 +55,7 @@ function os_class:set_theme(theme)
self.appdata.os.theme = theme
self.theme = self:get_theme()
self:save()
self:swap_node()
end
end
@ -124,18 +113,65 @@ function os_class:set_app(appname)
end
-- Handle input processing
function os_class:receive_fields(fields, sender)
function os_class:pass_to_app(method, reshow, sender, ...)
local appname = self.appdata.os.current_app or self.hwdef.custom_launcher or "launcher"
local app = self:get_app(appname)
app:receive_fields(fields, sender)
local ret = app:receive_data(method, reshow, sender, ...)
self.appdata.os.last_player = sender:get_player_name()
if self.appdata.os.current_app == appname then
if self.appdata.os.current_app == appname and reshow then
local formspec = app:get_formspec()
if formspec ~= false then
self.meta:set_string('formspec', formspec)
end
end
self:save()
return ret
end
-- Get Low-Level access to inventory slot
function os_class:get_removable_data(media_type)
self.removable_data = nil
local inv = self.meta:get_inventory()
inv:set_size("main", 1) -- 1 disk supported
local stack = inv:get_stack("main", 1)
if stack then
local def = stack:get_definition()
if def and def.name ~= "" then
local stackmeta = stack:get_meta()
local os_format = stackmeta:get_string("os_format")
if os_format == "" then
os_format = "none"
end
if not media_type or -- no parameter asked
def.groups["laptop_removable_"..media_type] or --usb or floppy
media_type == os_format then -- "none", "OldOS", "backup", "filesystem"
local data = {
inv = inv,
def = def,
stack = stack,
meta = stackmeta,
os_format = os_format,
}
data.label = data.meta:get_string("description")
if not data.label or data.label == "" then
data.label = def.description
end
self.removable_data = data
return data
end
end
end
end
-- Store data to inventory slot item (low-level)
function os_class:set_removable_data()
if self.removable_data then
local data = self.removable_data
if data.label ~= data.def.description then
data.meta:set_string("description", data.label)
end
data.inv:set_stack("main", 1, data.stack)
end
end
-- Get mod storage as (=internet / cloud)
@ -146,6 +182,44 @@ function os_class:connect_to_cloud(store_name)
return self.cloud_store[store_name]
end
-- Connect to app storage on removable
function os_class:connect_to_removable(store_name)
local data = self.removable_data or self:get_removable_data("data")
if not data then
self.removable_app_data = nil
return
end
self.removable_app_data = self.removable_app_data or {}
self.removable_app_data[store_name] = self.removable_app_data[store_name] or
minetest.deserialize(data.meta:get_string(store_name)) or {}
return self.cloud_store[store_name]
end
-- Save the data
function os_class:save()
-- Nodemata (HDD)
self.meta:set_string('laptop_appdata', minetest.serialize(self.appdata))
-- Modmeta (Cloud)
if self.cloud_store then
for store, value in pairs(self.cloud_store) do
mod_storage:set_string(store, minetest.serialize(value))
end
self.cloud_store = nil
end
-- Itemstack meta (removable)
if self.removable_data then
if self.removable_app_data then
for store, value in pairs(self.removable_app_data) do
data.meta:set_string(store, minetest.serialize(value))
end
end
self:set_removable_data()
end
self.removable_data = nil
end
-----------------------------------------------------
-- Get Operating system object
-----------------------------------------------------

View File

@ -8,6 +8,7 @@ laptop.themes = {
exit_button = "laptop_theme_freedom_exit_button.png",
app_button = "laptop_theme_freedom_app_button.png",
textcolor = "#000000",
node_color = 0,
},
}