GetHelperObject nun aehnlich filter()
GetHelperObject() wurde umgebaut, um eine aehnliche
Signatur und ein aehnliches Verhalten wie ein
filter() ueber die jeweilige P_*_HELPER Property zu
haben.
Change-Id: I43da08835fcfba0a20716d027ee8bd123d682a02
diff --git a/doc/sphinx/lfun/GetHelperObject.rst b/doc/sphinx/lfun/GetHelperObject.rst
index cf9baab..b50dc2b 100644
--- a/doc/sphinx/lfun/GetHelperObject.rst
+++ b/doc/sphinx/lfun/GetHelperObject.rst
@@ -4,7 +4,8 @@
FUNKTION
--------
- public varargs object GetHelperObject(int type, int|closure strength)
+ public varargs object GetHelperObject(int type, int|closure strength
+ varargs mixed* extra)
DEFINIERT IN
------------
@@ -14,12 +15,11 @@
ARGUMENTE
---------
- * type: Eine der in helpers.h definierten Konstanten
- * strength: Staerke des Helfers
- (Rueckgabewert der Callback-Methode, siehe :doc:`RegisterHelperObject`.)
- oder Closure, die als Argumente das Living und die Callback-Closure des
- Helpers uebergeben bekommt. Gibt die an GetHelperObject() uebergebe
- Closure 1 zurueck, wird das aktuelle Objekt zurueckgegeben.
+ type:
+ Eine der in helpers.h definierten Konstanten
+ strength:
+ minimal geforderte Staerke des Helfers oder Closure zum Filtern der
+ Helferobjekte.
BESCHREIBUNG
------------
@@ -27,15 +27,60 @@
Gibt das zuerst gefundene als Helfer registrierte Objekt zurueck, welches
die Anforderungen erfuellt.
+ Ist <strength> ein int, muss die Staerke/Guete des Helfers (Rueckgabewert
+ der Callback-Methode, siehe :doc:`RegisterHelperObject`) mindestens so gross
+ sein wie der als <strength> uebergebene Wert.
+
+ Ist <strength> eine Closure, wird diese fuer jeden Helfer ausgewertet und
+ entscheidet, ob der Helfer akzeptiert wird. Die Closure bekommt hierbei das
+ Helferobjekt, die vom Helfer angegebene Staerke/Guete und etwaige hier als
+ <extra> uebergebene Argument uebergeben. Ist der Rueckgabewert von
+ <strength> != 0, wird der Helfer akzeptiert und von GetHelperObject
+ zurueckgegeben (ohne weitere Helfer zu pruefen).
+
+
RUECKGABEWERT
-------------
Objekt welches den uebergebenen Anforderungen entspricht.
+
+BEISPIELE
+---------
+
+.. code-block:: pike
+
+ // Es wird ein Helfer zum Tauchen mit der Staerke 4 gesucht
+ PL->GetHelperObject(HELPER_TYPE_AQUATIC, 4);
+
+.. code-block:: pike
+
+ // Es wird ein Helfer zum Fliegen mit der Staerke 4 gesucht, welcher aber
+ // mindestens 60 cm gross und maximal 900 g schwer ist.
+ PL->GetHelperObject(HELPER_TYPE_AERIAL, function int (object h, int s)
+ { return s >= 4
+ && h->QueryProp(P_SIZE) >= 60 && h->QueryProp(P_WEIGHT) <= 900;
+ }
+ );
+
+.. code-block:: pike
+
+ // Es wird ein Helfer zum Fliegen mit der Staerke 4 gesucht, welcher aber
+ // mindestens 60 cm gross und maximal 900 g schwer ist, aber diese Grenzen
+ // werden nicht in der Funktion festgelegt, sondern als <extra> uebergeben.
+ PL->GetHelperObject(HELPER_TYPE_AERIAL,
+ function int (object h, int s, int min_s, int minsize, int maxweight)
+ { return s >= min_s
+ && h->QueryProp(P_SIZE) >= minsize
+ && h->QueryProp(P_WEIGHT) <= maxweight;
+ },
+ 4, 60, 900);
+
+
SIEHE AUCH
----------
:doc:`RegisterHelperObject`, :doc:ÙnregisterHelperObject`
:doc:`../props/P_AERIAL_HELPERS`, :doc:`../props/P_AQUATIC_HELPERS`, :doc:`../props/P_HELPER_OBJECTS`
-Letzte Aenderung: 27.02.2018, Bugfix
+Letzte Aenderung: 9.3.2018, Zesstra
diff --git a/std/living/helpers.c b/std/living/helpers.c
index 26c94e5..e029827 100644
--- a/std/living/helpers.c
+++ b/std/living/helpers.c
@@ -147,23 +147,36 @@
return deep_copy(Query(P_HELPER_OBJECTS,F_VALUE));
}
-public varargs object GetHelperObject(int type, int|closure strength)
+public varargs object GetHelperObject(int type, int|closure strength,
+ varargs mixed* extra)
{
object ob;
- // Wir brauchen strength als kleineren Wert, als den minimal akzeptierten,
- // damit wir mit > arbeiten koennen, ist meistens egal, aber wenn kein
- // Wert uebergeben wird ist strength = 0, in dem Fall duerfte aber
- // mehrheitlich 1 gemeint sein.
- --strength;
- foreach(closure cl : Query(P_HELPER_OBJECTS)[type]-({0}))
+ // Wenn kein Wert uebergeben wird ist strength 0, in dem Fall duerfte aber
+ // mehrheitlich 1 gemeint sein. Daher auf 1 setzen, wenn 0 uebergeben wurde.
+ strength ||= 1;
+
+ if (intp(strength))
{
- if((intp(strength) &&
- funcall(cl,this_object(),previous_object())>strength) ||
- (closurep(strength) && funcall(strength,this_object(),cl)))
+ foreach(closure cl : Query(P_HELPER_OBJECTS)[type]-({0}))
{
- ob=get_type_info(cl,2);
- break;
+ if(funcall(cl, this_object(), previous_object()) >= strength)
+ {
+ return get_type_info(cl,2);
+ }
}
}
- return ob;
+ else
+ {
+ foreach(closure cl : Query(P_HELPER_OBJECTS)[type]-({0}))
+ {
+ ob=get_type_info(cl,2);
+ if(apply(strength, ob, funcall(cl, this_object(), previous_object()),
+ extra) )
+ {
+ return ob;
+ }
+ }
+ }
+
+ return 0;
}