Autor Zpráva
1Pupik1989
Profil
Zdravím, řešil někdo automatické includování tříd na styl __autoload v PHP?

Přemýšlím o tom celý den, ale jediné co mě napadá, tak všechno uzavřít třeba do funkce run, projet její obsah jako text pomocí regulárních výrazů a uložit si výskyty do pole. Ty už potom načtu jednoduše, na to mám napsanou funkci.

Momentálně mám zápis:

<script type="text/javascript" src='Module/n3d.js'></script>
<script type="text/javascript">
var load = N3D.require('Math.*','Graphics.Render','Graphics.Scene');
load.success(function(){
  //Pokud je vše úspěšně načteno
});
load.error(function(){
 //Pokud vznikla chyba
});
load.complete(function(){
 //Proveď bez ohledu na chyby
});
</script>

No a mým cílem je, aby uživatel nemusel zapisovat ten vršek.
var load = N3D.require('Math.*','Graphics.Render','Graphics.Scene');

Spoustu Tříd je závislá na dalších. Příklad Geometry.Shapes je závislý na Math.Vector2, Math.Vector3, Math.Vector4 a Math.Matrix4.

Nemá někdo nějak radu nebo typ? Ty závislosti bych asi dokázal vychytat, spíš mi jde o ten autoloader.

Napadlo mě i cyklem vytvořit prázdné funkce, který by načítání volaly. Problém je, že by načítání nemohlo být asynchronní.

Děkuji za jakékoliv reakce.
joe
Profil
1Pupik1989:
Momentálně mám zápis:
A proč nemáš ty požadované třídy přímo v tom modulu Module/n3d.js?

Já bych je vyjmenoval tam a udělal si funkci například run, která by mohla být volána:

N3D.run(function () {
    // teprve před zavoláním této funkce by se načetly požadované knihovny, pokud už načtené nebyly (je třeba si někde držet seznam již načtených knihoven)
    // volání mus
});

V jQuery by takové načítání mohlo využívat $.when
1Pupik1989
Profil
joe:
Mám je zvlášť, protože není potřeba vše a dohromady by to ve finále bylo přes 500Kb (hrubý odhad), už teď to má 154Kb. JQuery do toho tahat nebudu. Engine nesmí být z žádném případě závislí na jiné knihovně, byly by z toho akorát další problémy. Navíc ladím načítání a chci maximální rychlost. Kdybych používal JQuery, tak bych rychlost rapidně poslal do kopru. Když už, tak bych využil Google Closure.

Těch tříd už tam mám spoustu

N3D.Modules.add('Help');
N3D.Modules.add('Math',["Main","Matrix3","Matrix4","Units","Vector2","Vector3","Vector4"]);
N3D.Modules.add('Audio',["Main"]);
N3D.Modules.add('Utils',["Keys","Ajax"]);
N3D.Modules.add('Graphics',["Camera","Color","Scene","Material","Render","Light","Shader"]);
N3D.Modules.add('Geometry',["Lightning","Shapes","Trees"]);
N3D.Modules.add('Game',["Main"]);
N3D.Modules.add('Files',["Main"]);

Nechce se mi to přepisovat na pole. Vlastně první parameter je skupina a druhý jsou třídy. To je jen pro představu o obsáhlosti. Navíc bych se v tom skriptu už neorientoval.
joe
Profil
1Pupik1989:
Nepsal jsem, abys použil jQuery. Psal jsem, jak by to mohlo fungovat, jednoduše zadáš seznam souborů, co se mají načíst a po načtení se zpracuje tvá funkce. Už pak záleží na tvém požadavku, jestli chceš asynchronní zpracování nebo ne.

Předpokládám tedy, že máš soubory jako Math.Main.js, Math.Matrix3.js, ... nebylo by v tomto případě lepší je sloučit do jednoho souboru Math.js a zminifikovat a použít třeba GZip kompresi? V takovém případě by pak šlo o pár kilo bajtů. Možná bych se to nebál ani dát všechno do jednoho., je lepší stáhnout jeden, sice větší soubor, než X menších.
1Pupik1989
Profil
Prakticky to samé co dělá JQuery.when, dělá i funkce N3D.require.

Do jednoho souboru bych to určitě nedával. Má to 154Kb a je hotovo tak 20%.

S načítáním problémy nevidím, je to celkem rychlé i na freehostingu s příšernou rychlostí.

Minifikací je samozřejmostí, ale až úplně ve finální verzi.

Chci soubory oddělené hlavně pro přehlednost. Já se ve svém zdrojovém kódu orientuji, ale ostatním by se nemuselo líbit těch x tisíc řádků.

Jde hlavně o autoloader. Nechci řešit jak to obejít, aby tam nemusel být. Nemusí se mi to hodit jen u této knihovny, může to být jakýkoliv jiný projekt.
joe
Profil
1Pupik1989:
Podle mě rozumné řešení neexistuje, jak by sis to představoval? Že nemáš třeba vůbec načtený soubor s třídou Math a někde v kódu zavoláš například Math.calc(); a on se ti nejprve načte soubor s danou třídou a pak se funkce vyvolá? V tom případě si myslím, že bys dopředu potřeboval vědět, jaké všechny metody v daných třídách jsou volatelné, ty si předem vytvořit, po jejich zavolání ověřit, jestli jsou jejich třídy načtené a pokud ne, tak je načíst.

Asi bych se smířil s tím, že v JavaScriptu klasický autoloader udělat nelze, ale třeba k tomu někdo napíše něco víc. Pokud by ses podíval na relativně novou službu rdio.com, taky načítá hromadu souborů, funguje to na známém JS frameworku (teď si ale nevzpomenu na název). Pravděpodobně budou mít v kódu taky někde něco na způsob

require("Graphics.Render.js");
1Pupik1989
Profil
Já už asi na jednu z možností přišel.

<script type="text/javascript" src='module/n3d_old.js' autoload="true">
var v = new N3D.Math.Vector4(1,2,3,1); 
</script>

Vytáhnu obsah, vyparsuji třídy a nakonec vygeneruji nový skript, do kterého ten obsah vložím. Tedy teoreticky by to fungovat mělo.
1Pupik1989
Profil
Tak jsem vyzkoušel co jsem psal a funguje to parádně. Sice mám jednodušší regexp, protože všechno začíná "N3D", nicméně by šlo vyhledat veškeré volání funkcí.

1. Vyhledat funkce uvnitř tagu.
2. Načíst všechny potřebné soubory s funkcemi.
3. Pokud je vše kompletně načteno, tak vytvořit nový script tag, vložit do něj obsah z předchozího.
4. Nový script tag vložit do stránky a starý smazat.

Dá se využít hlavně výhody, že script tag s definovaným src nespustí svůj obsah.

Vaše odpověď

Mohlo by se hodit

Neumíte-li správně určit příčinu chyby, vkládejte odkazy na živé ukázky.
Užíváte-li nějakou cizí knihovnu, ukažte odpovídajícím, kde jste ji vzali.

Užitečné odkazy:

Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: