Abilitare JavaScript per vedere questo sito.

Tutte le dichiarazioni globali condividono lo stesso spazio dei nomi, per cui i loro nomi non possono entrare in conflitto. Questo include i tipi di dati estesi e le funzioni incorporate registrate dall'applicazione host. Inoltre, tutte le dichiarazioni sono visibili a tutti, ad esempio una funzione da chiamare non deve essere dichiarata sopra la funzione che la chiama.

Funzioni

Le funzioni globali forniscono il mezzo per implementare routine che devono operare su alcuni input e produrre un risultato.

void foo()

{

  // Do something

}

Variabili

Negli script possono essere dichiarate variabili globali, che saranno poi condivise tra tutti i contesti che accedono al modulo di script.

Le variabili dichiarate globalmente in questo modo sono accessibili da tutte le funzioni. Il valore delle variabili viene inizializzato in fase di compilazione e qualsiasi modifica viene mantenuta tra le chiamate. Se una variabile globale contiene una risorsa di memoria, ad esempio una stringa, la sua memoria viene rilasciata quando il modulo viene scartato o il motore di script viene resettato.

int MyValue = 0;

const uint Flag1 = 0x01;

Le variabili di tipo primitivo vengono inizializzate prima delle variabili di tipo non primitivo. Ciò consente ai costruttori di classe di accedere ad altre variabili globali già con il loro valore iniziale corretto. L'eccezione è se anche l'altra variabile globale è di tipo non primitivo, nel qual caso non è garantito quale variabile venga inizializzata per prima, il che può portare a lanciare eccezioni di tipo null-pointer durante l'inizializzazione.

Fate attenzione a chiamare funzioni che possono accedere a variabili globali dall'interno dell'espressione di inizializzazione delle variabili globali. Il compilatore cerca di inizializzare le variabili globali nell'ordine in cui sono necessarie, ma non è detto che ci riesca sempre. Se una funzione accede a una variabile globale non ancora inizializzata, si otterrà un comportamento imprevedibile o un'eccezione null-pointer.

Proprietà virtuali

Una proprietà virtuale è una proprietà con un comportamento speciale per la lettura e la scrittura. Possono essere dichiarate globalmente, ma di solito si trovano come membri di classi.

int prop
{
  get return SomeValue(); }
  set { UpdateValue(value); }
}

Classi di script

Le classi di script vengono normalmente utilizzate per raggruppare le funzioni con i valori che verranno utilizzati da tali funzioni. Possono esistere più istanze di una classe, dove ogni istanza ha valori diversi.

class Foo

{

  void bar() { value++; }

  int value;

}

Interfacce

Un'interfaccia funziona come un contratto: le classi che implementano un'interfaccia hanno la garanzia di implementare i metodi dichiarati nell'interfaccia. Ciò consente l'uso del polimorfismo: una funzione può specificare che vuole un handle a un oggetto che implementa una certa interfaccia. La funzione può quindi chiamare i metodi di questa interfaccia senza dover conoscere il tipo esatto dell'oggetto con cui sta lavorando.

// The interface declaration
interface MyInterface
{
  void DoSomething();
}

 
// A class that implements the interface MyInterface
class MyClass : MyInterface
{
  void DoSomething()
  {
    // Do something
  }
}

Una classe può implementare più interfacce; è sufficiente elencare tutte le interfacce separate da una virgola.

Classi Mixin

Poiché l'ereditarietà multipla non è disponibile, a volte può essere necessario implementare codice identico in più classi. Quando ciò è necessario, si consiglia di utilizzare le classi mixin per evitare di scrivere lo stesso codice in più punti.

Le classi mixin consentono a uno script di dichiarare una struttura di classe parziale che sarà inclusa in più dichiarazioni di classi diverse. Le classi mixin non sono tipi reali e non possono essere istanziate.

Enumerazioni

Le enumerazioni sono un modo comodo per registrare una famiglia di costanti intere che possono essere utilizzate in tutto lo script come letterali denominati invece che come costanti numeriche. L'uso delle enumerazioni spesso aiuta a migliorare la leggibilità del codice, in quanto il letterale nominato normalmente spiega quale sia l'intenzione senza che il lettore debba cercare il significato di un valore numerico nel manuale.

Anche se le enumerazioni elencano i valori validi, non si può fare affidamento sul fatto che una variabile di tipo enum contenga solo i valori dell'elenco dichiarato. Bisogna sempre prevedere un'azione predefinita nel caso in cui la variabile contenga un valore inaspettato.

I valori di enumerazione vengono dichiarati elencandoli in una dichiarazione enum. A meno che non venga fornito un valore specifico per una costante enum, questa assumerà il valore della costante precedente + 1. La prima costante riceverà il valore 0 e la seconda il valore 0. La prima costante riceverà il valore 0, se non diversamente specificato.

enum MyEnum
{
  eValue0,
  eValue2 = 2,
  eValue3,
  eValue200 = eValue2 * 100
}

Funcdefs

I Funcdef sono usati per definire una firma di funzione che sarà usata per memorizzare puntatori a funzioni con firme corrispondenti. In questo modo è possibile creare un puntatore a funzione, in grado di memorizzare puntatori dinamici che possono essere invocati in un secondo momento come una normale chiamata di funzione.

// Define a function signature for the function pointer
funcdef bool CALLBACK(intint);

Typedefs

I typedef sono usati per definire alias per altri tipi.

Attualmente un typedef può essere usato solo per definire un alias per i tipi primitivi, ma una versione futura avrà un supporto più completo per tutti i tipi.

typedef float  real32;
typedef double real64;

Spazi dei nomi

Gli spazi dei nomi possono essere usati per organizzare progetti di grandi dimensioni in unità logiche più facili da ricordare. Quando si usano gli spazi dei nomi, non è necessario preoccuparsi di usare nomi per entità che possono esistere in una parte diversa del progetto sotto uno spazio dei nomi diverso.

namespace A
{
  // Entities in a namespace see each other normally.
  void function() { variable++; }
  int variable;
}

 
namespace B
{
  // Entities in different namespaces don't immediately see each other and
  // can reuse the same name without causing name conflicts. By using the
  // scoping operator the entity from the desired namespace can be explicitly
  // informed.
  void function() { A::function(); }
}

Importazioni

A volte può essere utile caricare dinamicamente i moduli di script senza dover ricompilare lo script principale, ma lasciando che i moduli interagiscano tra loro. In questo caso, lo script può importare funzioni da un altro modulo. Questa dichiarazione viene scritta usando la parola chiave import, seguita dalla firma della funzione e poi specificando da quale modulo importare.

Questo permette allo script di essere compilato utilizzando le funzioni importate, senza che queste siano effettivamente disponibili in fase di compilazione. L'applicazione può quindi vincolare le funzioni in un secondo momento, e anche disimpegnarle di nuovo.

Se uno script richiama una funzione importata che non è ancora stata vincolata, lo script viene interrotto con un'eccezione di script.

import void MyFunction(int a, int b) from "Another module";

NOTA: alla versione v3.56.0-2, RDE supporta soltanto script a modulo singolo; questa situazione potrebbe cambiare in versioni future di RDE o in altri prodotti Robox SpA che supportino lo script avanzato.

 

  

Keyboard Navigation

F7 for caret browsing
Hold ALT and press letter

This Info: ALT+q
Page Header: ALT+h
Topic Header: ALT+t
Topic Body: ALT+b
Contents: ALT+c
Search: ALT+s
Exit Menu/Up: ESC