GetMenuItemState - vyhodnocení stavu vyžaduje hodně času

Podpora vývojářů nových pluginů, oznámení o nových pluginech nezávislých autorů a diskuse o nich.
User avatar
stepand76
Plugin Developer
Plugin Developer
Posts: 455
Joined: 16 Apr 2007, 21:22
Location: Pardubice, Czech Republic

GetMenuItemState - vyhodnocení stavu vyžaduje hodně času

Post by stepand76 »

Ahoj, metoda PluginInterfaceForMenuExtAbstract.GetMenuItemState se vyvolává pro každou položku menu pluginu aby bylo možné určit její stav (viditelná, povolená). To je v pořádku a funguje to perfektně. Trochu nešikovné je pokud vyhodnocení stavu více položek vyžaduje vykonat nějakou časově náročnou operaci. Ta se pak musí provádět vícekrát pro každou položku. Rozbalení menu může trvat poměrně dlouho.

Napadají mě 2 řešení:

1. Doplnit metodu (s charakterem události), která by se vyvolala těsně před rozbalením menu pluginu. Tam by bylo možné si stav položek určit (stačila by jedna čas. náročná operace) a poznamenat do nějaké proměnné a poté již položky nastavovat v GetMenuItemState podle poznamenaného stavu.
2. Doplnit metodu (s charakterem události), ve které by bylo možné nastavit stav více položkám menu současně.

Ve stávajícím SDK mě napadá pouze stav určit v GetMenuItemState první položky a pro další ho už jen používat, ale to je krajně nepěkné.

Co vy na to? Nedalo by se s tím něco udělat?
Petr Solin
ALTAP Staff
ALTAP Staff
Posts: 1112
Joined: 08 Dec 2005, 09:13
Location: Novy Bor, Czech Republic
Contact:

Post by Petr Solin »

Zatim si neuvedomuju, ze by tohle nekoho trapilo, takze jsme to proste neresili. Urcite by se s tim dalo neco delat, ale prozatim mam dojem, ze bude rozumnejsi to obejit tim nepeknym zpusobem, o kterem jste psal. Pro Vas mala komplikace, pro nas zadna prace. ;-)

Proste pri dotazu na prvni IDcko si napocitat vse potrebne, dat to do globalky (rusit pri poslednim IDcku nebo pri unloadu pluginu, posudte sam) a pro mezilehla IDcka to jen pouzivat.

EDIT: Takhle jednoduse to buhuzel nejde, viz dale...
Last edited by Petr Solin on 16 Mar 2009, 16:01, edited 1 time in total.
User avatar
stepand76
Plugin Developer
Plugin Developer
Posts: 455
Joined: 16 Apr 2007, 21:22
Location: Pardubice, Czech Republic

Post by stepand76 »

Petr Solin wrote:Zatim si neuvedomuju, ze by tohle nekoho trapilo, takze jsme to proste neresili. Urcite by se s tim dalo neco delat, ale prozatim mam dojem, ze bude rozumnejsi to obejit tim nepeknym zpusobem, o kterem jste psal. Pro Vas mala komplikace, pro nas zadna prace. ;-)

Proste pri dotazu na prvni IDcko si napocitat vse potrebne, dat to do globalky (rusit pri poslednim IDcku nebo pri unloadu pluginu, posudte sam) a pro mezilehla IDcka to jen pouzivat.
No dobře, pořádně si to okomentuju, že jste mi to poradil :-)
Jen bych se chtěl ujistit, že pořadí volání GetMenuItemState je shodné jako registrace položek v AddMenuItem. Je to tak?
User avatar
zarevak
Plugin Developer
Plugin Developer
Posts: 789
Joined: 04 Feb 2006, 16:49
Location: Prague, Czech Republic

Post by zarevak »

Nevím, zda je rozumné spoléhat na pořadí IDček, ale pokud vytvoříte nějakou cache a budete si pamatovat, pro jaké zadané parametry je výsledek platný a jak dlouho, tak by to mohlo fungovat obecně.

Tedy něco na způsob:

Code: Select all

If (GetTime - cache.time < 1sec)   //pokud nedavno spocteno
    return cache.menu.enabled[IDM_xxx]; 

if (cache.GetState == GetCurrentState)   //pokud jsou vnejsi paramtery shodne
    return cache.menu.enabled[IDM_xxx]; 

DoCalculations(); //vytvori novou cache pro cele menu

return cache.menu.enabled[IDM_xxx];  //cache byla prave spoctena, takze je platna
User avatar
stepand76
Plugin Developer
Plugin Developer
Posts: 455
Joined: 16 Apr 2007, 21:22
Location: Pardubice, Czech Republic

Post by stepand76 »

zarevak wrote:Nevím, zda je rozumné spoléhat na pořadí IDček, ale pokud vytvoříte nějakou cache a budete si pamatovat, pro jaké zadané parametry je výsledek platný a jak dlouho, tak by to mohlo fungovat obecně.
Tohle mě taky napadlo, ale nepřišlo mi to (při vší úctě) úplně šťastné. Totiž zjištění toho stavu té položky může trvat i několik vteřin a nebo může být prakticky okamžité. Jak potom určit tu prodlevu?
Petr Solin
ALTAP Staff
ALTAP Staff
Posts: 1112
Joined: 08 Dec 2005, 09:13
Location: Novy Bor, Czech Republic
Contact:

Post by Petr Solin »

Tak cela vec se komplikuje, GetMenuItemState se taky vola pred spustenim prikazu z menu (aby se nepoustel disablovany command) a pro Last Command (Ctrl+I) polozku Plugins menu. Takze co jsem poradil bylo bohuzel ukvapene. Zbyva tedy zavest nejaky ten casovy limit pro platnost ziskanych dat (jde o to co je to za data, platnost muze byt klidne nekolik vterin, coz jiste pokryje stavbu menu + v nejhorsim se to ziska znovu).

Co je to za data? At mame predstavu o cem se tu vubec bavime.
User avatar
zarevak
Plugin Developer
Plugin Developer
Posts: 789
Joined: 04 Feb 2006, 16:49
Location: Prague, Czech Republic

Post by zarevak »

Petr mne předběhl... také mne zajímalo, co způsobuje to zpomalení? Procesorově náročný výpočet? Velké IO? Síť? Databáze? Jiný proces?

Asi jsme si nerozumněli s tou prodlevou - Čas cache měl být čas dokončení výpočtu. Pak by se jednalo o to, zda se nové GetMenuItemState stihlo zavolat do časové prodlevy od posledního výpočtu nebo ne.
Pro vylistování menu by to určitě stačilo. Zda se stihne zobrazit Last Command (spustí DoCalculations()) a pak vylistovat menu pluginu (to nastane až ve chvíli, kdy uživatel najede na položku pluginu v Plugins mneu); nebo zda se stihne vylistovat menu pluginu a zároveň spustit jedna z položek je otázka chování uživatele a délka této prodlevy.


Osobně si myslím, že jakékoliv menu by se mělo zobrazit do několika desetin sekundy a cokoliv trvá déle by se mělo obejít jiným způsobem. (Například nechat položku zapnutou a otestovat až po spuštění)

Stává se mi totiž, že při procházení Plugins menu někdy pomalým procházením otevřu menu jiného pluginu (prodleva ve Windows je cca 200ms) a pokud bych se zasekl u vašeho pluginu, tak bych nadával :oops:
Petr Solin
ALTAP Staff
ALTAP Staff
Posts: 1112
Joined: 08 Dec 2005, 09:13
Location: Novy Bor, Czech Republic
Contact:

Post by Petr Solin »

zarevak wrote:Osobně si myslím, že jakékoliv menu by se mělo zobrazit do několika desetin sekundy a cokoliv trvá déle by se mělo obejít jiným způsobem. (Například nechat položku zapnutou a otestovat až po spuštění)
Souhlas, dlouha prodleva bude jiste na obtiz, cekani po spusteni prikazu je v pohode.
User avatar
stepand76
Plugin Developer
Plugin Developer
Posts: 455
Joined: 16 Apr 2007, 21:22
Location: Pardubice, Czech Republic

Post by stepand76 »

Zarevaku:

1. Nevykej mi! :wink:

2. O co jde: Už nějaký čas pro svoji interní potřebu používám vlastní plugin, který funguje jako obálka TortoiseSVN. Plugin umí jednoduchým příkazem (v menu) zobrazit informace o prac. kopii (funguje jako viewer v AS), umí označit/odznačit změněné soubory, označit/odznačit verzované soubory, označit/odznačit neverzované soubory a pomalu začíná umět provádět příkazy TortoiseSVN (viz jeho shell extenze). Těch příkazů bude kolem 30 a je potřeba je povolit/zakázat/zobrazit/skrýt podle určitých podmínek. To může v případě rozsáhlé adr. struktury trvat nějaký čas. Pokud si ten čas vynásobíš třiceti, dostaneš se na vteřiny. Takže to chci řešit. Nechávat v menu povolených 30 příkazů (a testovat je až při spuštění příkazu) se mi moc nelíbí.

3. Už rozumím jak jsi to myslel s tou keší, ale nevím jestli by to šlo (je to závislé na datech a ty se mohou měnit prakticky kdykoliv) a taky nevím jetstli by se mi do toho chtělo 8)
User avatar
zarevak
Plugin Developer
Plugin Developer
Posts: 789
Joined: 04 Feb 2006, 16:49
Location: Prague, Czech Republic

Post by zarevak »

Vzhledem k tomu, že před spuštěním příkazu se zavolá znovu GetMenuItemState, tak ber 8) stavy v menu jen jako heurestiku pro uživatele. Navíc, i kdybys je měl všechny platné v době zobrazení, tak do kliku se může stát cokoliv.

Implementace časové cache by neměla být problém. Jen si pamatuj, pro který panel, na jaké cestě a kdy se dopočítal poslední výsledek. Pokud bude panel a cesta souhlasit a neuběhla dlouhá doba, pak můžeš předpokládat, že změna nenastala. Pokud bude prodleva 1 sekunda, tak se určitě stihne vylistovat menu pluginu, ale nestihne se lokální kopie moc změnit. Menu se ti sice zobrazí pomalu, ale výpočet bude jenom jeden.

Mimochodem: Zkus se spodívat, jak TortoiseSVN komunikuje se svým TSVNCache procesem. Možná by plugin mohl získávat výsledky odsud ;)
User avatar
stepand76
Plugin Developer
Plugin Developer
Posts: 455
Joined: 16 Apr 2007, 21:22
Location: Pardubice, Czech Republic

Post by stepand76 »

Jo asi mi nic jiného nezbyde. Dík.
Post Reply