Difference between revisions of "User:Xyz/stress"

From Minetest Developer Wiki
Jump to navigation Jump to search
 
(33 intermediate revisions by one other user not shown)
Line 2: Line 2:
  
 
http://irc.minetest.ru/minetest/2013-02-17#i_2877771
 
http://irc.minetest.ru/minetest/2013-02-17#i_2877771
 +
 +
Experimental implementation: https://github.com/xyzz/minetest-stress
  
 
== Core concepts ==
 
== Core concepts ==
 
All functions are prefixed with <code>:</code>. All properties are prefixed with <code>.</code>.
 
All functions are prefixed with <code>:</code>. All properties are prefixed with <code>.</code>.
 +
 +
What do we want:
 +
* Consistent API
 +
* Good docs (with examples)
 +
 +
* Chaining (<source enclose=none>_("default:dirt"):on("punch", func):on("something", func):on("wtf", func):craft({"default:grass"})</source>)
 +
* Events (<source enclose=none>:on("wtf", function(e) doSomething end)</source>)
 +
* Nice assignments (<source enclose=none>e.stack = "mybrand:newstack 99"</source>) instead of ugly function calls (<source enclose=none>player:set_wielded_wtf_am_i_doing(ItemStack("asd"))</source>). This is probably not a good idea though because it won't work in all places, making people confused.
 +
 +
<code>stressedNode → Stress.Node</code>
 +
 +
Same for others.
  
 
== Types ==
 
== Types ==
=== stressedPosition ===
+
All <code>stressed*</code> members should have <code>__type</code> property containing their type as a string.
Same as [[position]].
+
 
 +
<u>Underlined</u> functions return <code>self</code>, this should be used for method chaining.
 +
<source>
 +
_({0, 0, 0}):meta("first", "value"):name("default:dirt")
 +
</source>
 +
 
 +
=== Stress.Position ===
 +
Same as position. Can be created from either <code>{x = …, y = …, z = …}</code> or <code>{…, …, …}</code>
 +
 
 +
Supports -(unary), +, -, *.
 +
 
 +
Do use it as vector.
 +
<source>
 +
Stress.Position(A) === _:p(A)  -- shortcut for convenience
 +
                              -- you won't use it much anyway as we provide Stress.Position everywhere
 +
-- preferred code style:
 +
-- _:p(A) — good
 +
-- _:p{1, 2, 3} — good
 +
-- _:p{x=1, y=2, z=3} — good
 +
-- _:p({1, 2, 3}) — not as good
 +
 
 +
Stress.Position{1, 2, 3} + {4, 5, 6}
 +
Stress.Position{0, 0, 0} - Stress.Position{1, 2, 3}
 +
Stress.Position{1, 2, 3} * 5  -- {5, 10, 15}
 +
Stress.Position{1, 2, 3} * {y = 5}  --- {1, 10, 3}
 +
 +
</source>
 +
 
 +
=== stressedArea ===
 +
<code>_(pos1, pos2)</code>, <code>pos1</code>, <code>pos2</code> are stressedPositions
 +
* <code>:name("string")</code>
 +
* <code>:meta("name", "value")</code>
 +
* <code>:each(function(node))</code> — <code>node</code> is stressedNode
  
=== stressedNode ===
+
=== Stress.Node ===
 
Created via <code>_(position)</code>
 
Created via <code>_(position)</code>
  
 
Implements:
 
Implements:
* <code>:value()</code> — get node name
+
* <code>:name()</code> — get node name
* <code>:value("string")</code> — set node name (like <source enclose="none">minetest.env:set_node()</source>)
+
* <u><code>:name("string")</code></u> — set node name (like <source enclose="none">minetest.env:set_node()</source>)
* something with meta?
+
* <u><code>:set("string")</code></u> — same as <code>:name("string")</code>
 +
* <code>:meta()</code> — returns all meta as a table
 +
* <u><code>:meta(table)</code></u> — overwrites meta with the table (or should it rather update values instead of deleting all that are not present in the table?)
 +
* <code>:meta("name")</code> — get single meta value
 +
* <u><code>:meta("name", "value")</code></u> — set meta
 +
* <code>:inventory("name")</code> — returns Stress.Inventory (name is actually listname)
 +
 
 +
=== Stress.NodeDef ===
 +
(needs better name)
  
=== stressedNodeDef (what a weird name! better think of another one) ===
 
 
Created via <code>_("name")</code>, i.e. <code>_("default:dirt")</code>
 
Created via <code>_("name")</code>, i.e. <code>_("default:dirt")</code>
  
* <code>:on("event", function())</code> — registers event, possible ones:
+
* <u><code>:on("event", function())</code></u> — registers event:
 
** <code>dig</code>
 
** <code>dig</code>
 
** <code>place</code>
 
** <code>place</code>
 
** <code>punch</code>
 
** <code>punch</code>
 
** <code>rightclick</code>
 
** <code>rightclick</code>
 +
* <code>:every</code> — registers ABM
 +
** every(time, function)
 +
** every(time, chance, function)
 +
** ??
 +
 +
=== Stress.Inventory ===
 +
* <code>:empty()</code> — returns true if inventory is empty
 +
* <u><code>:clear()</code></u> — remove everything from inventory
 +
* <code>:size()</code> — get size of an inventory
 +
* <u><code>:size(N)</code></u> — set size of an inventory
 +
* <code>:width()</code>
 +
* <u><code>:width(N)</code></u>
 +
* <code>:stack(X)</code> ­— get the Xth stack from inventory, modifiable
 +
 +
=== Stress.Stack ===
 +
Stress.Stack points to the specific slot in inventory.
 +
* <u><code>:set(value)</code></u>
 +
* <code>:name()</code>
 +
* <u><code>:name(S)</code></u>
 +
* <code>:count()</code>
 +
* <u><code>:count(N)</code></u>
 +
* <code>:wear()</code>
 +
* <u><code>:wear(N)</code></u>
 +
* <u><code>:pop([N])</code></u> — takes N items (or 1 if N is not provided)
 +
* <u><code>:push([N])</code></u> — adds N items (or 1 if N is not provided)
  
 
== Global functions ==
 
== Global functions ==
Line 32: Line 110:
 
** <code>shutdown</code>
 
** <code>shutdown</code>
 
** …
 
** …
 +
* <code>_:iterate(pos1, pos2)</code>
 +
<source>
 +
for pos in _:iterate({0, 0, 0}, {1, 1, 1}) do
 +
    _(pos):name("air")
 +
end
 +
-- same as _({0, 0, 0}, {1, 1, 1}):name("air")
 +
</source>
  
 
== Something ==
 
== Something ==
Line 37: Line 122:
 
<source>
 
<source>
 
_("default:dirt"):on("place", function(me)
 
_("default:dirt"):on("place", function(me)
     me:value("default:dirt_with_grass")
+
     me:name("default:dirt_with_grass")
 
end)
 
end)
 
</source>
 
</source>
Line 56: Line 141:
 
     if message == "/dirttograss" and not dirttograss then
 
     if message == "/dirttograss" and not dirttograss then
 
         dirttograss = _("default:dirt"):on("place", function(me)
 
         dirttograss = _("default:dirt"):on("place", function(me)
             me:value("default:dirt_with_grass")
+
             me:name("default:dirt_with_grass")
 
         end)
 
         end)
 
     elseif message == "/nodirttograss" and dirttograss then
 
     elseif message == "/nodirttograss" and dirttograss then

Latest revision as of 19:44, 25 January 2023

_()!

http://irc.minetest.ru/minetest/2013-02-17#i_2877771

Experimental implementation: https://github.com/xyzz/minetest-stress

Core concepts

All functions are prefixed with :. All properties are prefixed with ..

What do we want:

  • Consistent API
  • Good docs (with examples)
  • Chaining (_("default:dirt"):on("punch", func):on("something", func):on("wtf", func):craft({"default:grass"}))
  • Events (:on("wtf", function(e) doSomething end))
  • Nice assignments (e.stack = "mybrand:newstack 99") instead of ugly function calls (player:set_wielded_wtf_am_i_doing(ItemStack("asd"))). This is probably not a good idea though because it won't work in all places, making people confused.

stressedNode → Stress.Node

Same for others.

Types

All stressed* members should have __type property containing their type as a string.

Underlined functions return self, this should be used for method chaining.

_({0, 0, 0}):meta("first", "value"):name("default:dirt")

Stress.Position

Same as position. Can be created from either {x = …, y = …, z = …} or {…, …, …}

Supports -(unary), +, -, *.

Do use it as vector.

Stress.Position(A) === _:p(A)  -- shortcut for convenience
                               -- you won't use it much anyway as we provide Stress.Position everywhere
-- preferred code style:
-- _:p(A) — good
-- _:p{1, 2, 3} — good
-- _:p{x=1, y=2, z=3} — good
-- _:p({1, 2, 3}) — not as good

Stress.Position{1, 2, 3} + {4, 5, 6}
Stress.Position{0, 0, 0} - Stress.Position{1, 2, 3}
Stress.Position{1, 2, 3} * 5  -- {5, 10, 15}
Stress.Position{1, 2, 3} * {y = 5}  --- {1, 10, 3}
…

stressedArea

_(pos1, pos2), pos1, pos2 are stressedPositions

  • :name("string")
  • :meta("name", "value")
  • :each(function(node))node is stressedNode

Stress.Node

Created via _(position)

Implements:

  • :name() — get node name
  • :name("string") — set node name (like minetest.env:set_node())
  • :set("string") — same as :name("string")
  • :meta() — returns all meta as a table
  • :meta(table) — overwrites meta with the table (or should it rather update values instead of deleting all that are not present in the table?)
  • :meta("name") — get single meta value
  • :meta("name", "value") — set meta
  • :inventory("name") — returns Stress.Inventory (name is actually listname)

Stress.NodeDef

(needs better name)

Created via _("name"), i.e. _("default:dirt")

  • :on("event", function()) — registers event:
    • dig
    • place
    • punch
    • rightclick
  • :every — registers ABM
    • every(time, function)
    • every(time, chance, function)
    • ??

Stress.Inventory

  • :empty() — returns true if inventory is empty
  • :clear() — remove everything from inventory
  • :size() — get size of an inventory
  • :size(N) — set size of an inventory
  • :width()
  • :width(N)
  • :stack(X) ­— get the Xth stack from inventory, modifiable

Stress.Stack

Stress.Stack points to the specific slot in inventory.

  • :set(value)
  • :name()
  • :name(S)
  • :count()
  • :count(N)
  • :wear()
  • :wear(N)
  • :pop([N]) — takes N items (or 1 if N is not provided)
  • :push([N]) — adds N items (or 1 if N is not provided)

Global functions

  • _:on("event", function())
    • generated
    • shutdown
  • _:iterate(pos1, pos2)
for pos in _:iterate({0, 0, 0}, {1, 1, 1}) do
    _(pos):name("air")
end
-- same as _({0, 0, 0}, {1, 1, 1}):name("air")

Something

An example of code in stress:

_("default:dirt"):on("place", function(me)
    me:name("default:dirt_with_grass")
end)

same without stress

minetest.register_on_placenode(function(pos, newnode)
    if newnode.name == "default:dirt" then
        minetest.env:set_node(pos, {name="default:dirt_with_grass"})
    end
end)

Something more?

dirttograss = nil
_:on("chat", function(message)
    if message == "/dirttograss" and not dirttograss then
        dirttograss = _("default:dirt"):on("place", function(me)
            me:name("default:dirt_with_grass")
        end)
    elseif message == "/nodirttograss" and dirttograss then
        _(dirttograss):clear()
    end
end)