Jump to content

návod #emit - Základy [*****]


Scydo

Recommended Posts

#emit
*****


Rád bych vás chtěl informovat, že tento topic bude čistě jen o základních informacích. Vyhnu se stránkám textů jak funguje compiler, další formy preprocesorů... jelikož to není tak extrémně podstatné.

Zdravím vás u návodu na nejtěžší látce v pawn.

CO JE TO EMIT?

Existují 2(možná víc) výborných anglických návodů na emit, ale v obou jsou asi 2 strany čisté teorie a informací, ohledně jak funguje compiler, jak vzniklo PAWN, jak funguje amxing, co je to opkód... takže najít tam prostě smysluplnou větu a odpověď na tuhle otázku tam není jednoduché, ale rád vám na ní odpovím já: emit nejsou nic více než jen pointery(jestliže nevíte, co je to pointer, budete se muset naučit teorii C++ především v oblasti pointerů, jelikož bez toho emit nepochopíte). Každá proměnná, kterou deklarujete má relevantní informace a to jméno, údaj a především adresu:




new
	Promenna = 3;

Vy vidíte pouze 2 informace a to jméno proměnné(Promenna) a údaj(3). Ale adresu ne. A s ní můžeme pracovat pomocí emitu.

EMIT A PAWN

Mezitím, co v C++ můžete pracovat s kolika pointery se vám zlíbí, v pawn na to máte pouze 2 pointery a to PRI(primární aka první) a ALT(alterantivní aka druhé). Obou můžete přiřadit hodnoty jak z lokálních tak i globálních proměnných(ano, skutečně emit potřebuje vědět, jestliže vkládáte údaje z globální či lokální), a jenom těmto 2 se mohou dít dané "operace"(sečtení, negace, odečtení aj).

Určitě se někteří tedy ptáte k čemu je mi emit, když můžu jednoduše přiřaďovat a měnit hodnoty pomocí rovnítka? Ano, můžete ale pointery zjistí adresu proměnné. Najde její adresu, kde je přesně a přepíše údaj. Rovnítko "hledá", jak se jmenuje proměnná a přepíše údaj. Proto je taky emit rychlejší než operace. Nechápeme? Vysvětlím: V případě, že hledáte text(nebo-li jméno proměnné) tak je to pomalejší, jelikož se musí zjistit přesné jméno do poslední znaku, aby jsme neměli například proměnnou ahoj a Ahoj a nebral to jako 1 a tu samou. Ale, pod adresou si můžeme představit jako "id" té proměnné, a číslo se hledá podstatně jednodušeji, protože jediný způsob jak najít číslo je řádově počítat(0, 1, 2, 3, 4, 5...), a protože emit zná adresu proměnné(což neni nic více než číslo), proto je také rychlejší.

UKÁZKA EMITU

Emit se značí preprocesorovým znamínkem # a slovem emit:



#emit

Pro představuj tu je jednoduchá operace a to sečtení 2 proměnných a výsledek vložený do 3 proměnné:



	new
		Cislo1 = 11,
		Cislo2 = 22,
		Vysledek;
		
	#emit LOAD.S.PRI Cislo1
	#emit LOAD.S.ALT Cislo2
	#emit ADD
	#emit STOR.S.PRI Vysledek
	printf("%i", Vysledek); // 33

Teď si to postupně rozebereme:



	#emit LOAD.S.PRI Cislo1

Do primárního(prvního) pointeru načte a připíše hodnotu proměnné Cislo1



	#emit LOAD.S.ALT Cislo2

Do alternativního(druhého) pointeru načte a připíše hodnotu proměnné Cislo2



	#emit ADD

Vezme hodnoty z primárního a alternativního a sečte je.



	#emit STOR.S.PRI Vysledek

Výsledný údaj ze primární(jelikož add sečte a vepíše do primárního) a připíše jí do proměnné Vysledek.

Pro uživatele, co ovládají C++, tak je to stejné(spíše podobné) jako:



int Cislo1 = 11;
int Cislo2 = 22;
int Vysledek;
int * p1 = &Cislo1; /* 0000 */
int * p2 = &Cislo2; /* 0004 */

Vysledek = *p1 + *p2;

Tady bych to rád zakončil, jelikož jsem vám chtěl ukázat jen základy k emitu. Samozřejmě, emit jak píše Misiur v návodě http://forum.sa-mp.com/showthread.php?p=3430898 v případě tvorby filterscriptu či gamemodu ho vůbec nepotřebujete. Spíše se hodí pro tvorbu includů a knihoven kvůli rychlost.

TEST RYCHLOSTI

#emit vs konstantní #emit vs obyč. operace


 



[	new
		promenna1 = 1000000,
		promenna2 = 500000,
		Vysledek;
/* ---------------- | Emit | ---------------- */
	new count1 = GetTickCount();
	for(new i; i < 300000; i++) {
	
		#emit LOAD.S.PRI promenna1
		#emit LOAD.S.ALT promenna2
		#emit ADD
		#emit STOR.S.PRI Vysledek
	}
	printf("Emit %d", GetTickCount() - count1);

/* ---------------- | Konstantni emit | ---------------- */
	new count2 = GetTickCount();
	for(new i; i < 300000; i++) {
	
		#emit CONST.PRI 1000000
		#emit CONST.ALT 500000
		#emit ADD
		#emit STOR.S.PRI Vysledek
	}
	printf("kons. emit %d", GetTickCount() - count2);

/* ---------------- | Operace | ---------------- */
	new count3 = GetTickCount();
	for(new i; i < 300000; i++) {
	
		Vysledek = promenna1 + promenna2;
	}
	printf("Operace %d", GetTickCount() - count3);

 



#emit: 13
Konstantní emit: 13
Operace: 26

Edited by vEnd
Validácia
  • Líbí se mi to! (+1) 3
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...