Autor | Zpráva | ||
---|---|---|---|
KryVosa Profil |
#1 · Zasláno: 5. 1. 2016, 19:28:48
V jedné nedodělané hře vytvářím možnost přidávat si vlastní 'mutátory' hry, kterými můžete různé vlastnosti hry upravovat za běhu a/nebo přidávat nové. Implementace v samotné hře vypadá nějak takto:
var functions= { // ... move:function(p, x, y) { var mut=game.mutator.move.test({functions:functions/*další a další upravovatelné atributy...*/}); mut=mut||false; if(mut.x||mut)player[p].x += x; if(mut.y||mut)player[p].y += y; }, // ... } move() se provede mutátor, kterému je funkce move() předána a on ji může zavolat, čímž pádem se provede mutátor.... Zároveň však game.mutator.test() může testovat více mutátorů, tudíž nejde přidat 'test zavolání z mutátorů', kterým by se volání stornovalo.¨
Máte-li nějaký nápad, pomocný článek, nebo kritiku kódu, napište, předem děkuji :) |
||
Chamurappi Profil |
#2 · Zasláno: 6. 1. 2016, 13:04:00
Reaguji na KryVosu:
Nejsem si jistý, jestli jsem správně pochopil, v čem spočívá problém, hodně věcí jsem si musel domyslet. „se provede mutátor, kterému je funkce move() předána a on ji může zavolat“
Můžeš mu tu funkci nepředat. Respektive předat mu místo functions jiný objekt naplněný vším, co je ve functions , s přepsanou metodou move .
Nebo můžeš do volání předávat i nějaký (s každým voláním rostoucí) výčet volaných funkcí a ověřovat, jestli v něm právě volaná funkce už jednou není. Nebo by asi šlo mít v move pojmenovanou funkci (tzn. move: function název(p, x, y) ) a pak zevnitř přes název.caller zjistit, čím je volána (a čím je volána to, co ji volá, atd.) – a tím zjistit, jestli nejsi v rekurzi. Ale nevím, jestli by to bylo proveditelné, nikdy jsem caller nepotřeboval.
|
||
KryVosa Profil |
#3 · Zasláno: 7. 1. 2016, 09:35:08
Problém jsi jako vždy pochopil na jedničku!
Caller nikdy fungovat nebude, nemá 'historii', jen 'poslední' funkci, kterou byl zavolaný. Takže i při konečné rekurzi funkce/funkcí se sám zacyklí. Šlo by to obejít přes jakýsi vlastní 'max CallStack' u caller u, jakékoliv zacyklení by bylo úplně nemožné.
Možná by šlo 'ukládat' si někam funkce, které move() zavolaly, a právě jak říkáš kontrolovat, jestli mezi nimi už není funkce, která move() už zavolala. Popřípadě určit jakýsi 'maximální počet vnoření'.
Děkuji za nakopnutí. |
||
Časová prodleva: 5 dní
|
|||
KryVosa Profil |
#4 · Zasláno: 12. 1. 2016, 11:22:37
Pro ostatní, co by měli podobný problém, sem ještě posílám hotové řešení:
var callStack=[]; function callStackTest() { caller=callStackTest.caller.caller; callStack.push(caller); var count=0; var lastIndex=-1; while((lastIndex=callStack.indexOf(caller,lastIndex+1))>=0) count++; if(count>=callStackMax) { console.error("Recursive CallStack overfilled! ("+caller.toString().replace(/\{.*\}/i,"")+")"); callStack=[]; return false; } else return true; } callStackMax=10 function a(){if( !callStackTest() ) return; b(); callStack=[];} function b(){a()} |
||
Chamurappi Profil |
#5 · Zasláno: 12. 1. 2016, 11:50:26
Reaguji na KryVosu:
„Caller nikdy fungovat nebude, nemá 'historii', jen 'poslední' funkci, kterou byl zavolaný.“ Předpokládám, že tohle tedy není pravda, když nyní používáš callStackTest.caller.caller . Takže by asi šlo projít caller y i bez pole callStack .
|
||
KryVosa Profil |
#6 · Zasláno: 12. 1. 2016, 20:40:09
Chamurappi: Není, ale v případě že budou dvě funkce v rekurzi (klidně i konečné, "ne-nekonečné"), caller se 'zacyklí'.
|
||
Časová prodleva: 7 let
|
0