init.lua 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. -- Copyright (c) raymoo 2016
  2. -- Licensed under Apache 2.0 license. See COPYING for details.
  3. -- Any documentation here are internal details, please avoid using them in your
  4. -- mod.
  5. local modpath = minetest.get_modpath(minetest.get_current_modname()) .. "/"
  6. player_monoids = {}
  7. local mon_meta = {}
  8. mon_meta.__index = mon_meta
  9. local nop = function() end
  10. -- A monoid object is a table with the following fields:
  11. -- def: The monoid definition
  12. -- player_map: A map from player names to their effect tables. Effect tables
  13. -- are maps from effect IDs to values.
  14. -- value_cache: A map from player names to the cached value for the monoid.
  15. -- next_id: The next unique ID to assign an effect.
  16. local function monoid(def)
  17. local mon = {}
  18. local actual_def = {}
  19. for k, v in pairs(def) do
  20. actual_def[k] = v
  21. end
  22. if not actual_def.apply then
  23. actual_def.apply = nop
  24. end
  25. if not actual_def.on_change then
  26. actual_def.on_change = nop
  27. end
  28. mon.def = actual_def
  29. local p_map = {}
  30. mon.player_map = p_map
  31. mon.next_id = 1
  32. local v_cache = {}
  33. mon.value_cache = v_cache
  34. setmetatable(mon, mon_meta)
  35. minetest.register_on_leaveplayer(function(player)
  36. local p_name = player:get_player_name()
  37. p_map[p_name] = nil
  38. v_cache[p_name] = nil
  39. end)
  40. return mon
  41. end
  42. player_monoids.make_monoid = monoid
  43. function mon_meta:add_change(player, value, id)
  44. local p_name = player:get_player_name()
  45. local def = self.def
  46. local p_effects = self.player_map[p_name]
  47. if p_effects == nil then
  48. p_effects = {}
  49. self.player_map[p_name] = p_effects
  50. end
  51. local actual_id
  52. if id then
  53. actual_id = id
  54. else
  55. actual_id = self.next_id
  56. self.next_id = actual_id + 1
  57. end
  58. local old_total = self.value_cache[p_name]
  59. p_effects[actual_id] = value
  60. local new_total = def.fold(p_effects)
  61. self.value_cache[p_name] = new_total
  62. def.apply(new_total, player)
  63. def.on_change(old_total, new_total, player)
  64. return actual_id
  65. end
  66. function mon_meta:del_change(player, id)
  67. local p_name = player:get_player_name()
  68. local def = self.def
  69. local p_effects = self.player_map[p_name]
  70. if p_effects == nil then return end
  71. local old_total = self.value_cache[p_name]
  72. p_effects[id] = nil
  73. local new_total = def.fold(p_effects)
  74. self.value_cache[p_name] = new_total
  75. def.apply(new_total, player)
  76. def.on_change(old_total, new_total, player)
  77. end
  78. function mon_meta:value(player)
  79. local p_name = player:get_player_name()
  80. return self.value_cache[p_name] or self.def.identity
  81. end
  82. dofile(modpath .. "standard_monoids.lua")
  83. dofile(modpath .. "test.lua")