Advertisement
salahzar

important Lezione Propedeutica 01032008

Feb 16th, 2020
534
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 14.94 KB | None | 0 0
  1. Lezione propedeutica.
  2.  
  3. Facciamo un riassunto delle informazioni minime che dovreste già sapere per poter scriptare. E' una carrellata sulle cose fondamentali:
  4. (il simbolo § indica argomenti avanzati)
  5.  
  6. 1. Gestione degli script
  7.  
  8. 1.1 Come si crea uno script "New Script"
  9. 1.2 Come si edita uno script
  10. 1.3 Running/Reset degli script
  11. 1.4 Come si debugga uno script
  12. 1.5 Impostazione delle permissions
  13.  
  14. 2. Sintassi del linguaggio lsl2
  15.  
  16. 2.1 tipo variabili
  17. 2.2 variabili globali e locali
  18. 2.3 funzioni
  19. 2.4 struttura a stati
  20. 2.5 costrutti elementari (for, while, if, jump)
  21.  
  22. 3. Libreria lsl
  23.  
  24. 3.1 funzioni di gestione stringhe
  25. 3.2 funzioni di gestione matematica
  26. 3.3 funzioni di gestione liste
  27. 3.4 funzioni di gestione eventi listen
  28. 3.5 funzioni timer
  29. 3.6 funzioni touch
  30. 3.7 uso di lldialog
  31.  
  32.  
  33. 1.1 Come si crea uno script
  34.  
  35. Avete due sistemi:
  36. a) lo create dall'inventory (create new script) e poi lo trascinate nel content (questo è l'unico modo che funziona con opensim).
  37. b) dal content di un oggetto fate "New Script" e vi verrà creato uno script che poi andrete a rinominare
  38.  
  39. 1.2. Come si edita uno script
  40.  
  41. Cliccate sullo script nell'inventory dell'oggetto (oppure tasto destro/open) vi si apre un "editor" dove potete fare le cose tipiche che si fanno in ambiente word:
  42. * ctrl-c ctrl-v, funzionano
  43. * shift-canc NON funziona, quindi dovete fare invece ctrl-c e poi shift-canc altrimenti perdete il testo precedente.
  44. * ctrl-z funziona
  45. Potete fare ctrl-f per fare ricerca e sostituzioni. Ricordatevi di mettere "case insensitive".
  46.  
  47. Syntax Highlighting ed help.
  48. * Le funzioni speciali del linguaggio sono rappresentate in "rosso". se ci passate sopra con il mouse avete un aiuto sulla sintassi (moolto utile).
  49. * in verde e blu i "verbi" del linguaggio. anche qui si passa sopra per info
  50.  
  51. Quando salvate lo script vi segnala gli errori e la riga dove andare per correggerli. Se vi sono errori lo script viene salvato lo stesso ma NON è running (non fa niente!!).
  52.  
  53. 1.3 Running reset degli script.
  54.  
  55. Potete in ogni momento sospendere uno script cliccando sul box di "Running" e rimetterlo running successivamente. Utile per stoppare uno script che sta dando di testa.
  56.  
  57. Analogamente per il reset. Il reset fa ripartire lo script da zero, PERDENDO tutti i dati che stava usando. Utile per correggere uno script che ha dato stack/collision.
  58.  
  59. Le stesse operazioni possono essere fatte da Tools->Set Script running/not running in selection oppure Tools->Reset Scripts in selection.
  60.  
  61. 1.4. Come si debugga uno script
  62.  
  63. Ci sono virtualmente infiniti modi di verificare se uno script sta facendo quello che deve, visto che la maggior parte del tempo fa cose strane :(
  64.  
  65. * Mettete scritte di debug. La cosa più semplice è di usare llOwnerSay(str), llSay(0, ""), oppure llSay(10,""). Da preferirsi la terza perchè la potete utilizzare senza disturbare la chat pubblica.
  66.  
  67. E' facile scriptare un oggetto perchè ascolti sulla porta 10 e ve la rilanci come llOwnerSay.
  68.  
  69. § 1.4.1 Debug avanzato
  70. Altri sistemi sono meno semplici da strutturare e di solito non si usano spesso:
  71. * http di log su un sito esterno, (lo vedremo meglio nella lezione su httprequest)
  72. * colorazione di prim (utile per segnalare lo stato di busy)
  73. * llSetText in cima all'oggetto
  74. * Invio di IM
  75.  
  76. § Visto che le chat possono essere difficili da consultare, ho preparato un logging su un sito esterno (httplog) che potete usare per i vostri test (si vedrà meglio nella lezione httprequest).
  77.  
  78. scrivete il seguente in cima al vostro script:
  79. string sURL="http://www.salahzar.info/lsl/httplog.php?pass=PASS";
  80. debug(string k,string action,string str)
  81. {
  82. string s=sURL+"&key="+llEscapeURL(k)+"&action="+action+"&text="+llEscapeURL(str);
  83. llOwnerSay(s);
  84. llHTTPRequest(s,[],"");
  85. }
  86.  
  87. 1.5 IMPOSTAZIONE DELLE PERMISSIONS
  88.  
  89. Vi sono svariate tipologie di permissions per gli oggetti:
  90. * COPY (potete avere diverse copie)
  91. * MODIFY (potete modificare le caratteristiche)
  92. * TRANSFER (potete trasferirlo, spesso sinonimo di venderlo ad altri)
  93.  
  94. Per gli script:
  95. * COPY lo script può essere ricopiato
  96. * MODIFY lo script può essere visto
  97. * TRANSFER venduto
  98.  
  99. Anche le texture hanno le loro permissions.
  100.  
  101. Permissions più diffuse:
  102. Un oggetto "FULL-PERMISSIONS" può essere visto, aperto, modificato, trasferito.
  103. "COPY-MODIFY" è vostro lo potete modificare ma non trasferire
  104. "MODIFY-TRANSFER" modificare, trasferire ma non copiare
  105.  
  106. Per gli script le combinazioni più diffuse sono:
  107. * FULL-PERMISSIONS script "open source"
  108. * COPY (no modify) i più diffusi se volete proteggere la proprietà intellettuale
  109. * NO-PERMISSIONS sconsigliato perchè impedisce anche il copy degli oggetti in cui è contenuto
  110.  
  111. 2 SINTASSI del linguaggio lsl2
  112.  
  113. 2.1 Tipo delle variabili
  114.  
  115. * integer (numeri, canali, contatori, flag, handle, importi in L$).
  116. § 32bit con segno. da −2,147,483,648 a +2,147,483,647
  117.  
  118. * float (contiene valori in virgola mobile). Es. 3.1415 (o PI)
  119. § 32 bit, circa 10 cifre significative, da 10E-38 a 10E38 circa.
  120.  
  121. * string (array di "bytes" gestiti normalmente in una sorta di UTF-8, simile all'ascii), dimensione massima normalmente 4000 bytes
  122. § (che possono essere anche molti meno se utf-8 di lingue strane). Esempio "città" 5 caratteri utf-8, ma 6 bytes.
  123.  
  124. * key (rappresentano le UUID di oggetti, texture, avatar ecc), sono "stringhe" lunghe 34 bytes esempio 39941cda-47c1-f928-30e0-5cc9ce9632a7
  125.  
  126. * vector (sono 3 float, rappresenta posizioni, velocità, colori..), esempio <x,y,z>, <r,g,b> dove r,g,b compresi fra 0 e 1 per i colori.
  127.  
  128. * rotation (sono 4 float), anche rappresentabili con 3 float. esempio <x,y,z,w>
  129.  
  130. * list. Liste eterogenee di dati. Esempio [ "Alpha", 5, <1,0,0> ]
  131.  
  132.  
  133.  
  134. 2.2 variabili globali e locali
  135.  
  136. All'inizio di un programma si specificano le variabili viste globalmente ovunque. Una variabile globale quando viene modificata in un punto dello script appare modificata ovunque. Le variabili globali vengono allocate in un'area chiamata "statics".
  137.  
  138. Le variabili globali vanno dichiarate PRIMA della dichiarazione degli stati
  139.  
  140. Ogni funzione / stato alloca le variabili locali sullo stack. Le variabili locali usate all'interno di una funzione od evento vengono rilasciate al termine dell'evento o della funzione.
  141.  
  142. E' importante distinguere fra variabili locali e globali. Confonderle può condurre ai seguenti problemi:
  143.  
  144. * pensi di scrivere su una variabile globale ma invece scrivi su una variabile locale che sparisce
  145. * scrivi su una variabile globale pensando di scrivere su una locale provocando il malfunzionamento di un altro pezzo di programma
  146.  
  147. Per evitare confusioni, io suggerisco di usare una nomenclatura chiara, prefissando le variabili gloabli con una lettera che indica il loro tipo e mettendole tutte in maiuscolo.
  148.  
  149. iNOTECARD ad esempio, vPOS, lLISTA....
  150.  
  151. 2.3 funzioni
  152.  
  153. Le funzioni vanno messe prima degli stati e possono essere mischiate con le dichiarazioni di globals.
  154.  
  155. Servono a rendere facilmente utilizzabile pezzi di codice che si ripete sempre uguale oppure per rendere "riciclabile" pezzi di codice che avete già fatto in altri oggetti.
  156.  
  157. E' raccomandabile usare molte funzioni nel vostro codice, anche se a causa della struttura primordiale di questo linguaggio le funzioni possono rallentare e/o aumentare il consumo di memoria.
  158.  
  159. In particolare ricordate che ogni volta che passate dei parametri ad una funzione, questi parametri vengono ricopiati e quindi occupano uno spazio almeno doppio. In quei casi anche se brutto, è meglio ricorrere alle variabili globali.
  160.  
  161. Questo vale in particolare se avete bisogno di passare delle liste o delle stringhe molto grosse.
  162.  
  163.  
  164. 2.4 struttura a stati e code di eventi
  165.  
  166. Il programma lsl quando entra in esecuzione è sempre in uno stato, come minimo il default state. Tutti gli eventi sono associati a quello stato se cambiate stato le code di eventi VENGONO cancellate!
  167.  
  168. Per ogni evento c'è una "coda di eventi" per registrare le attività che devono essere eseguite dall'oggetto (task). La coda di eventi è limitata.
  169.  
  170. § Notizia curiosa: se siete in una zona noscript il vostro programma NON è in esecuzione, ma le code di eventi continuano ad essere aggiornate (fino al loro limite).
  171.  
  172. Gli eventi più importanti sono:
  173.  
  174. - touch_start(integer count) (da non confondere con touch(integer count)).
  175. - on_rez(integer parm)
  176. - state_entry()
  177. - listen()
  178. - timer()
  179.  
  180. 2.5 costrutti elementari
  181.  
  182. - for(integer i=0;i<10;i++){}
  183. - do {} while (<test>) ;
  184. - while (<test> ) {}
  185. - if(<test>) {}
  186. - if(<test>) {} else {}
  187. - @label ....... jump label
  188. - chiamata di funzione
  189.  
  190. 3. Libreria lsl
  191.  
  192. 3.1 gestione stringhe
  193.  
  194. Fondamentali!!!
  195.  
  196. - x="string"
  197. - llStringLength(x) per ottenere la sua lunghezza in caratteri (non bytes!)
  198. § L'occupazione effettiva dipende dall'uso di caratteri UTF-8 estesi.
  199. - llStringTrim(x,STRING_TRIM) per togliere spazi in testa e in coda
  200. - llGetSubString(x,start,end) per ottenere un pezzo di una stringa. Nota l'uso di indici negativi per riferire agli ultimi elementi della stringa. Nota la partenza da 0
  201. - llDeleteSubString(x,start,end) per cancellare pezzi di stringa
  202. - llSubStringIndex(src,pattern) cerca una stringa in un'altra
  203. - llInsertString(dst,pos,src) inserisce una stringa dentro un'altra
  204. § - llMD5String(str,nonce) "firma" una stringa per sicurezza
  205. § - llXorBase64Strings(s1,s2) "cripta" una stringa con una password
  206. § - llEscapeURL(s) trasforma una stringa in modo che sia utilizzabile su internet
  207. § - llUnescapeURL(s) ritrasforma una stringa internet in formato normale
  208.  
  209. Trucco: usate s=(s="")+s+x; invece di s+=x per ridurre l'uso di memoria
  210.  
  211. 3.2 funzioni matematiche
  212.  
  213. Le più importanti:
  214.  
  215. - llFrand(maxnum) per la generazione causale di canali, password etc
  216. - llFabs()
  217. - llRound()
  218. § - llSin/llCos (in radianti) per la costruzione di strutture circolari
  219.  
  220. Rotazioni, visto che sono fra le più difficili :)
  221.  
  222. §- llEuler2Rot (converte un vettore euleriano in una rotazione) e llRot2Euler
  223. §- llAxes2Rot (fwd, left, fwd % left) dati due vettori determina la rotazione implicita
  224.  
  225.  
  226. 3.3 funzioni di gestione liste
  227.  
  228. Ricordatevi che le funzioni di liste non modificano MAI la lista ma ritornano sempre nel caso una lista modificata! (Questo aumenta l'uso della memoria)
  229.  
  230.  
  231. - llDeleteSubList(src,start,end) toglie un pezzo di lista
  232.  
  233. - llGetListLength(lst)
  234. - llList2<Type>(lst,index) estrae un elemento tipato
  235. § attenzione se è un vettore conviene estrarlo in genere con
  236. (vector)llList2String(lst,index)
  237. - llList2List(src,start,end) estrae una sottolista
  238. - llListFindList(src, lst) cerca un insieme di elementi nella lista
  239. - llListInsertList(dst,src,pos) inserisce una lista
  240. - llListRandomize(lst,stride) mette una lista in ordine casuale
  241. - llListReplaceList(dst,src,start,end)
  242.  
  243. § Funzioni avanzate
  244.  
  245. §- llGetListEntryType(lst,index) tipo dell'elemento della lista
  246. §- llList2ListStrided(src,start,end,stride) estrae una "lista intervallata"
  247. §- llList2CSV(lst) salva una lista in una stringa
  248. §- llDumpList2String(list,separator) salva una lista in una stringa
  249. §- llCSV2List(string) ripristina una lista da una stringa
  250. §- llListSort(src,stride,ascending)
  251. §- llListStatistics
  252. §- llParseString2List(src,sep,spacers)
  253. §- llParseStringKeepNulls(src,sep,spacers)
  254.  
  255. § Trucco: usate lst=(lst=[])+lst+x invece di lst+=x per ridurre l'uso di memoria
  256.  
  257. 3.4 Funzioni di gestione eventi listen
  258.  
  259. integer handle=llListen(channel,name,id,string) => apre l'ascolto su un canale
  260.  
  261. channel:0 è quello dove gli avatar parlano
  262. channel:>0 ogni avatar può parlare su quel canale facendo /x parlo
  263. § channel:<0 solo gli oggetti possono parlare su quel canale
  264. § channel:DEBUG_CHANNEL usato dagli oggetti per segnalare stati strani (script con triangolino giallo)
  265.  
  266. il canale è usato anche dalla funzione llDialog (che quindi non funziona se parallelamente non è stato fatto un llListen)
  267.  
  268. NB: se non si fa la llListen, l'oggetto NON gestirà l'evento listen() anche se definito!!
  269. § NB: i listeners creano lag, specie quelli sul canale 0
  270. § NB: listener su canali negativi generano MENO lag
  271.  
  272. § In generale occorre limitare il numero di listeners al minimo possibile e rimuovere l'handle non appena possibile con la funzione llListenRemove(handle).
  273.  
  274. Usate sempre dei debug per essere sicuri di cosa state ricevendo e di come avete impostato il listener. Molti oggetti funzionano male perchè:
  275.  
  276. - non avete impostato il listener
  277. - l'avete impostato male (sul canale sbagliato, specificando un id sbagliato, di solito si imposta NULL_KEY, ma se state facendo un llDialog potete mettere la key di chi vi ha toccato) ecc.
  278. § - è stato disattivato l'handle con una llListenRemove
  279.  
  280. § La id può essere impostata a llGetOwner () in modo che l'oggetto risponda solo all'owner. Per farla rispondere al gruppo basta inserire un test nell'evento:
  281. if(llSameGroup(id)) ....
  282.  
  283. 3.5 funzioni timer
  284.  
  285. llSetTimerEvent(seconds) se 0 viene disabilitato
  286.  
  287. Si usa per moltissimi casi, fra cui:
  288.  
  289. * fare una cosa ogni tot secondi (es. cambiare foto)
  290. § * gestire un "timeout" esempio mantenere acceso un listener solo per 30 secondi per ridurre il lag
  291. § * gestire timer multipli
  292. § * produrre un evento concordato (llSetTimerEvent(0.1) fa scattare l'evento)
  293.  
  294. Ricordate che llSetTimerEvent imposta l'evento in modo RIPETUTO, quindi se non lo spegnete l'evento si manifesta di nuovo ogni tot secondi.
  295.  
  296. 3.6 Funzioni di touch
  297.  
  298. touch_start(integer count)
  299.  
  300. Sono lo strumento principale per gestire l'interazione con gli avatar (ce ne sono altri, mq il touch è quello che produce la MINORE quantità di lag).
  301.  
  302. E' importante distinguere fra touch_start e touch. Il primo scatta solo una volta quando l'oggetto viene toccato.
  303. Touch invece continua a scattare per tutto l'intervallo di tempo in cui l'avatar mantiene cliccato il tasto sinistro del mouse.
  304.  
  305. Cos'è il parametro count? Dice QUANTI avatar stanno toccando l'oggetto. In generale possiamo supporre per semplicità che ce ne sia uno soltanto e per ottenerne l'identità
  306. scriviamo
  307. key avkey=llDetectedKey(0)
  308.  
  309. § ma se volessimo essere precisi dovremmo fare:
  310.  
  311. for(integer i=0;i<count;i++)
  312. {
  313. key avkey=llDetectedKey(i);
  314. ...
  315. }
  316.  
  317.  
  318.  
  319. § Altre interazioni possibili:
  320.  
  321. * la listen precedentemente citata (ma è considerata spesso scomoda)
  322. * le funzioni di collisione (ma l'avatar deve esplicitamente andare addosso all'oggetto)
  323. * sensor (l'avatar è vicino all'oggetto)
  324.  
  325.  
  326.  
  327. 3.7 llDialog
  328.  
  329. funziona in pieno accordo con il touch: ecco il framework indicativo per usarlo
  330.  
  331. integer iLISTEN=0;
  332. integer iCHANNEL=-3000;
  333.  
  334. default
  335. {
  336. touch_start(integer count)
  337. {
  338. key avkey=llDetectedKey(0);
  339. list options=[ "o1", "o2", "o3" ];
  340. iLISTEN=llListen(iCHANNEL,"",avKey,"");
  341. llSetTimerEvent(60); // deve rispondere entro 60 secondi
  342. llDialog(avkey, "please say something",options,iCHANNEL);
  343. }
  344. timer()
  345. {
  346. llRemoveListener(iLISTEN);
  347. llSay(0,"Timeout please touch me again for talking");
  348. llSetTimerEvent(0);
  349. }
  350. listen(integer channel, string name, key id, string str)
  351. {
  352. llSay(0,"you told me "+str);
  353. llSetTimerEvent(0);
  354. llRemoveListener(iLISTEN);
  355. }
  356. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement