diff --git a/source/tutorials/index.rst b/source/tutorials/index.rst index 9d916f0..c7d9818 100644 --- a/source/tutorials/index.rst +++ b/source/tutorials/index.rst @@ -3,6 +3,6 @@ Tutorials .. toctree:: :maxdepth: 2 - :glob: - * + programming-language + gui-programming diff --git a/source/tutorials/programming-language/main/01-00-first-program.rst b/source/tutorials/programming-language/main/01-00-first-program.rst index ce79f96..7225215 100644 --- a/source/tutorials/programming-language/main/01-00-first-program.rst +++ b/source/tutorials/programming-language/main/01-00-first-program.rst @@ -8,49 +8,62 @@ Sadly predictable, but still: .. code-block:: vala - class Demo.HelloWorld : GLib.Object { - public static int main(string[] args) { - stdout.printf("Hello, World\n"); - return 0; - } - } + void main() { + stdout.printf("Hello, World\n"); + } Of course, that is a Vala *Hello World* program. I expect you can recognise some parts of it well enough, but just to be thorough I shall go through it step by step. .. code-block:: vala - class Demo.HelloWorld : GLib.Object { + void main() { -This line identifies the beginning of a class definition. Classes in Vala are very similar in concept to other languages. A class is basically a type of object, of which instances can be created, all having the same properties. The implementation of classed types is taken care of by the *gobject* library, but details of this are not important for general usage. +This is the start of a method definition. A method is a function related to a type of object that can be executed on an object of that type. The fact that this method is called ``main`` and has the signature it does means that Vala will recognise it as the entry point for the program. ``void`` is the return type of the method, which means that the method does not return any value. -What is important to note is that this class is specifically described as being a subclass of *GLib.Object*. This is because Vala allows other types of class, but in most cases, this is the sort that you want. In fact, some language features of Vala are only allowed if your class is descended from GLib's *Object*. - -Other parts of this line show namespacing and fully qualified names, although these will be explained later. .. code-block:: vala - public static int main(string[] args) { + stdout.printf("Hello, World\n"); + +This line instructs Vala to execute the method called *printf* of the *stdout* object, with the hello string as an argument. In Vala, this is always the syntax you use to call a method on an object, or to access an object's data. ``\n`` is the escape sequence for a new line. -This is the start of a method definition. A method is a function related to a type of object that can be executed on an object of that type. The static method means that the method can be called without possessing a particular instance of the type. The fact that this method is called ``main`` and has the signature it does means that Vala will recognise it as the entry point for the program. -The *main* method doesn't have to be defined inside a class. However, if it is defined inside a class it must be ``static``. It doesn't matter if it's ``public`` or ``private``. The return type may be either ``int`` or ``void``. With a ``void`` return type the program will implicitly terminate with exit code 0. The string array parameter holding the command line arguments is optional. +--------------- + +there are several ways to write a ``main`` method in vala, here are the possible ones : .. code-block:: vala + + void main () { + } - stdout.printf("Hello, World\n"); + int main () { + return 0; + } + int main (string[] args) { + return 0; + } -*stdout* is an object in the *GLib* namespace that Vala ensures you have access to whenever required. This line instructs Vala to execute the method called *printf* of the *stdout* object, with the hello string as an argument. In Vala, this is always the syntax you use to call a method on an object, or to access an object's data. ``\n`` is the escape sequence for a new line. + void main (string[] args) { + } -.. code-block:: vala +it is possible to declare your main in a class only if it is public and static. +``int`` is the return type of the main method, which means that the method returns an integer value. The integer value returned by the main method is the exit status of the program. The exit status is a value returned by a program to the operating system. The operating system can then use this value to determine whether the program executed successfully or not. A return value of 0 indicates that the program executed successfully, while a non-zero value indicates that the program did not execute successfully. + +``string[] args`` is an array of strings that are passed to the program when it is executed. The first element of the array is the name of the program itself. The remaining elements are any arguments that are passed to the program when it is executed. The arguments are separated by spaces. For example, if you execute the program with the command ``./hello arg1 arg2``, then the array will contain the following elements: - return 0; -``return`` is to return a value to the caller and terminate the execution of the *main* method which also terminates the execution of the program. The returned value of the *main* method is then taken as the exit code of the program. +.. code-block:: vala + + public class Main { + public static void main(string[] args) { + //... + } + } -The last lines simply end the definitions of the method and class. Compile and Run --------------- diff --git a/source/tutorials/programming-language/main/02-00-basics/02-04-data-types.rst b/source/tutorials/programming-language/main/02-00-basics/02-04-data-types.rst index b91ddbc..b105d3f 100644 --- a/source/tutorials/programming-language/main/02-00-basics/02-04-data-types.rst +++ b/source/tutorials/programming-language/main/02-00-basics/02-04-data-types.rst @@ -10,16 +10,60 @@ Value Types Vala supports a set of the simple types as most other languages do. -* Byte, ``char``, ``uchar``; their names are *char* for historical reasons. -* Character, ``unichar``; a 32-bit Unicode character -* Integer, ``int``, ``uint`` -* Long Integer, ``long``, ``ulong`` -* Short Integer, ``short``, ``ushort`` -* Guaranteed-size Integer, ``int8``, ``int16``, ``int32``, ``int64`` as well as their unsigned siblings ``uint8``, ``uint16``, ``uint32``, ``uint64``. The numbers indicate the lengths in bits. -* Float number, ``float``, ``double`` -* Boolean, ``bool``; possible values are ``true`` and ``false`` -* Compound, ``struct`` -* Enumeration, ``enum``; represented by integer values, not as classes like Java's enums +.. list-table:: + :widths: 10 18 10 50 + :header-rows: 1 + + * - NameType + - Type + - Size + - Description + * - Byte + - char, uchar + - 1 byte + - Their names are "char" for historical reasons. + * - Character + - unichar + - 4 bytes + - 32-bit Unicode character + * - Integer + - int, uint + - 4 bytes + - Integer + * - Long Integer + - long, ulong + - 8 bytes + - Long integer + * - Short Integer + - short, ushort + - 2 bytes + - Short integer + * - Platform-Specific Integer + - ssize_t, size_t + - Depend on platform + - Unsigned integer type, the size of which is platform-dependent + * - Guaranteed-size Integer + - int8, uint8, int16, uint16, int32, uint32, int64, uint64 + - 1, 2, 4, 8 bytes + - Integers of guaranteed sizes (8, 16, 32, 64 bits) and their unsigned versions + * - Float number + - float, double + - 4, 8 bytes + - Floating-point number + * - Boolean + - bool + - 1 byte + - Possible values: true and false + * - Compound + - struct + - Varies + - Compound type + * - Enumeration + - enum + - 4 bytes (int) + - Represented by integer values, not as classes like Java's enums + +For more information on structs and enums, please refer to :doc:`02-07-language-elements` Here are some examples. @@ -85,11 +129,14 @@ You can slice a string with ``[start:end]``. Negative values represent position string s1 = greeting[7:12]; // => "world" string s2 = greeting[-4:-2]; // => "or" -Note that indices in Vala start with 0 as in most other programming languages. Starting with Vala 0.11 you can access a single byte of a string with ``[index]``: +.. note:: + that indices in Vala start with 0 as in most other programming languages + +you can access a single byte of a string with ``[index]``: .. code-block:: vala - uint8 b = greeting[7]; // => 0x77 + uint8 b = greeting[7]; // => 119, the ASCII value of 'w' However, you cannot assign a new byte value to this position, since Vala strings are immutable. @@ -103,16 +150,9 @@ Many of the basic types have reasonable methods for parsing from and converting string s1 = true.to_string(); // => "true" string s2 = 21.to_string(); // => "21" -Two useful methods for writing and reading strings to/from the console (and for your first explorations with Vala) are *stdout.printf()* and *stdin.read_line()*: - -.. code-block:: vala - stdout.printf("Hello, world\n"); - stdout.printf("%d %g %s\n", 42, 3.1415, "Vala"); - string input = stdin.read_line(); - int number = int.parse(stdin.read_line()); +If you want learn how print your string jump it :doc:`02-09-output-input` -You already know *stdout.printf()* from the *Hello World* example. Actually, it can take an arbitrary number of arguments of different types, whereas the first argument is a *format string*, following the same rules as `C format strings `_. If you must output an error message you can use *stderr.printf()* instead of *stdout.printf()*. In addition the *in* operation can be used to determine whether one string contains another, e.g. @@ -271,7 +311,6 @@ Defining a new type is a matter of derive it from the one you need. Here is an e .. code-block:: vala /* defining an alias for a basic type (equivalent to typedef int Integer in C)*/ - [SimpleType] public struct Integer : uint { } diff --git a/source/tutorials/programming-language/main/02-00-basics/02-07-language-elements.rst b/source/tutorials/programming-language/main/02-00-basics/02-07-language-elements.rst index 8951ff0..b84111a 100644 --- a/source/tutorials/programming-language/main/02-00-basics/02-07-language-elements.rst +++ b/source/tutorials/programming-language/main/02-00-basics/02-07-language-elements.rst @@ -115,7 +115,7 @@ Delegates may also be created locally. A member method can also be assigned to a More samples in `Delegates Manual `_. -Anonymous Methods / Closures +Anonymous Methods / Closures (lambda expressions) ---------------------------- .. code-block:: vala @@ -217,14 +217,15 @@ Structs public int a; } -defines a `struct` type, i.e. a compound value type. A Vala struct may have methods in a limited way and also may have private members, meaning the explicit `public` access modifier is required. +defines a `struct` type, i.e. a compound value type. A Vala struct may have methods in a limited way and also may have private members +``public`` keyword is optional and can be omitted. however, one method can be private or public. .. code-block:: vala struct Color { - public double red; - public double green; - public double blue; + double red; + double green; + double blue; } This is how you can initialise a struct: @@ -248,10 +249,124 @@ This is how you can initialise a struct: blue = 1.0 }; +Structs can have methods: + +.. code-block:: vala + + struct Point { + public double x; + public double y; + + public double distance_to(Point other) { + return Math.sqrt((x - other.x) * (x - other.x) + (y - other.y) * (y - other.y)); + } + } + + void main() { + Point p1 = { 1.0, 2.0 }; + Point p2 = { 4.0, 6.0 }; + + p1.distance_to(p2); // returns 5.0 + } + Structs are stack/inline allocated and copied on assignment. To define an array of structs, please see the `FAQ `_ + +Enums +----- + +Enums are a way to define a set of named integer constants. They are useful for defining a set of related values that are not necessarily sequential. For example, the following code defines an enum named *EnumName* with three values: + +.. code-block:: vala + + enum EnumName { + VALUE1, + VALUE2, + VALUE3 + } + +The values of the enum are accessed by the name of the enum followed by a period and the name of the value, e.g. *EnumName.VALUE1*. + + +An enum can contains functions: + +.. code-block:: vala + + enum EnumName { + VALUE1, + VALUE2, + VALUE3; + + public unowned string to_string() { + switch (this) { + case VALUE1: return "Value 1"; + case VALUE2: return "Value 2"; + case VALUE3: return "Value 3"; + default: return "Unknown"; + } + } + } + + void main() { + print(EnumName.VALUE1.to_string()); // prints "Value 1" + print(EnumName.VALUE2.to_string()); // prints "Value 2" + print(EnumName.VALUE3.to_string()); // prints "Value 3" + } + + +.. note:: + an enum can be set in a class + +Flags +----- + +Enums can be used like flags by using the `[Flags]` attribute on the enum definition. +This allows you to combine the values using the `+` operator and check if a value is set using the `in` operator. + +For example: + +.. code-block:: vala + + [Flags] + enum MyFlags { + FLAG1, + FLAG2, + FLAG3 + } + + void main() { + MyFlags flags; + + flags = MyFlags.FLAG1 + MyFlags.FLAG3; + + if (MyFlags.FLAG1 in flags) + print("FLAG1 is set"); + if (MyFlags.FLAG2 in flags) + print("FLAG2 is set"); + if (MyFlags.FLAG3 in flags) + print("FLAG3 is set"); + } + +.. list-table:: Operators for Enumerations (Flags) + :widths: 10 70 + :header-rows: 1 + + * - Operator + - Description + * - ``+=`` + - Adds flags to this + * - ``-=`` + - Removes flags from this + * - ``+`` + - Combines two flags. + * - ``-`` + - Subtracts the flags. + * - ``in`` + - Checks if a flag is set. + + Classes ------- @@ -262,6 +377,8 @@ Classes Defines a class, i.e. a reference type. In contrast to structs, instances of classes are heap allocated. There is much more syntax related to classes, which is discussed more fully in the section about object oriented programming. +:doc:`../03-00-object-oriented-programming` and :doc:`../03-00-object-oriented-programming/03-01-basics` + Interfaces ---------- diff --git a/source/tutorials/programming-language/main/02-00-basics/02-09-output-input.rst b/source/tutorials/programming-language/main/02-00-basics/02-09-output-input.rst new file mode 100644 index 0000000..3180e18 --- /dev/null +++ b/source/tutorials/programming-language/main/02-00-basics/02-09-output-input.rst @@ -0,0 +1,121 @@ +Output / Input +================= + +Stdout +--------- + +You already know *stdout.printf()* from the *Hello World* example. Actually, it can take an arbitrary number of arguments of different types, whereas the first argument is a *format string*, following the same rules as `C format strings `_. If you must output an error message you can use *stderr.printf()* instead of *stdout.printf()*. + +To print a message to the console, you can use the *stdout.printf()* function or *print()* function. This function is similar to the *printf()* function in C. The *stdout.printf()* function takes a format string and a list of arguments. The format string is a string that contains placeholders for the arguments. The placeholders are replaced with the values of the arguments when the function is called. + +.. code-block:: vala + + stdout.printf("Hello, world\n"); + print("Hello, world\n"); + stdout.printf("%d %g %s\n", 42, 3.1415, "Vala"); + +Stderr +--------- + +To print an error message to the console, you can use *stderr.printf()* functions instead of *stdout.printf()* function. or you can use *printerr()* function. + +.. code-block:: vala + + stderr.printf("I'm an error message !"); + printerr("I'm an error message !"); + +for debugging message vala provides ``debug()``, ``message()``, ``warning()`` and ``critical()`` functions. + +.. code-block:: vala + + message("I'm a message !"); + warning("I'm a warning !"); + critical("I'm a critical message !"); + +You can change the format of the debug message with Log.set_default_handler() function. + + +Stdin +------- + +To read a line from the console, you can use the *stdin.read_line()* function. This function reads a line from the console and returns it as a string. + +.. code-block:: vala + + string? line; + while ((line = stdin.read_line()) != null) { + stdout.printf("You entered: %s\n", line); + } + +Or use *stdin.scanf()* function to read formatted input from the console. + +.. code-block:: vala + + int day, month, year; + stdout.printf("Enter your birthday (dd/mm/yyyy): "); + stdin.scanf("%d/%d/%d", out day, out month, out year); + stdout.printf("You were born on %d/%d/%d\n", day, month, year); + +.. warning:: + + if you want ``stdin.scanf()`` with %s format, you must create a buffer to store the input. + + .. code-block:: vala + + uint8 buffer[128]; + stdin.scanf("%s", out buffer); + stdout.printf("You entered: %s\n", (string)buffer); + + if you don't create a buffer or too small, you will get a segmentation fault. + + +Opening Files +--------------- + +To open a file, you can use the *FileStream.open()* function. This function takes the name of the file and the mode in which you want to open the file. The mode can be one of the following: + +.. code-block:: vala + + var fs = FileStream.open("toto.txt", "r"); + if (fs == null) { + print("Cannot open file"); + return ; + } + + string ?line = null; + while ((line = fs.read_line()) != null) { + print(line); + } + + +.. list-table:: + :widths: 5 60 + :header-rows: 1 + + * - Mode + - Description + * - `r` + - Open text file for reading. The stream is positioned at the beginning of the file. + * - `r+` + - Open for reading and writing. The stream is positioned at the beginning of the file. + * - `w` + - Truncate file to zero length or create text file for writing. The stream is positioned at the beginning of the file. + * - `w+` + - Open for reading and writing. The file is created if it does not exist, otherwise it is truncated. The stream is positioned at the beginning of the file. + * - `a` + - Open for appending (writing at end of file). The file is created if it does not exist. The stream is positioned at the end of the file. + * - `a+` + - Open for reading and appending (writing at end of file). The file is created if it does not exist. Output is always appended to the end of the file. POSIX is silent on what the initial read position is when using this mode. For glibc, the initial file position for reading is at the beginning of the file, but for Android/BSD/MacOS, the initial file position for reading is at the end of the file. + + +You can use *FileUtils.get_contents()* and *FileUtils.set_contents()* functions to read and write the content of a file. + +.. code-block:: vala + + string content; + FileUtils.get_contents("my_text.txt", out content); + // get all content of the file + + string new_content = content.replace("a", "b"); + // replace all 'a' by 'b' and set the new content to the file + FileUtils.set_contents("my_text.txt", new_content); diff --git a/source/tutorials/programming-language/main/04-00-advanced-features/04-07-the-main-loop.rst b/source/tutorials/programming-language/main/04-00-advanced-features/04-07-the-main-loop.rst index 7e26766..0c28399 100644 --- a/source/tutorials/programming-language/main/04-00-advanced-features/04-07-the-main-loop.rst +++ b/source/tutorials/programming-language/main/04-00-advanced-features/04-07-the-main-loop.rst @@ -23,6 +23,23 @@ The following program creates and starts a ``MainLoop``, and then attaches a sou loop.run(); } +since vala 0.56, you can create an async main function +async main create a main loop and run it, so you don't need to create a MainLoop object manually + +.. code-block:: vala + + async void main() { + Timeout.add(2000, () => { + stdout.printf("Time!\n"); + Idle.add(main.callback); + return false; + }); + + yield; + } + + + When using GTK+, a main loop will be created automatically, and will be started when you call the ``Gtk.main()`` method. This marks the point where the program is ready to run and start accepting events from the user or elsewhere. The code in GTK+ is equivalent to the short example above, and so you may add event sources in much the same way, although of course you need to use the GTK+ methods to control the main loop. .. code-block:: vala diff --git a/source/tutorials/programming-language/main/04-00-advanced-features/04-08-asynchronous-methods.rst b/source/tutorials/programming-language/main/04-00-advanced-features/04-08-asynchronous-methods.rst index f2cd702..7f4ddd4 100644 --- a/source/tutorials/programming-language/main/04-00-advanced-features/04-08-asynchronous-methods.rst +++ b/source/tutorials/programming-language/main/04-00-advanced-features/04-08-asynchronous-methods.rst @@ -165,6 +165,55 @@ to the called method which runs until its first ``yield`` and then drops back to the calling method, which completes the ``yield`` statement itself, and then gives back control to its own caller. +Thread with Async Methods +------------------------- + +An async method may be used to control a background thread. +the supra_calculator function execute a blocking thread just after it will use the ``yield`` keyword which makes us return to the main and it can continue to print the 'Hi !' every second. once the Thread has finished executing it uses ``Idle.add(supra_calculator.callback);`` which indicates that the program can return to the function at the time of the yield. we join the thread and retrieve the calculation and we return it to retrieve it in the main + +``yield`` keyword is like a pause in the execution of the program, it allows to execute other code and then return to the function where the ``yield`` was used. + +.. code-block:: vala + :linenos: + + async int supra_calculator (int ms) { + var thread = new Thread (null, () => { + int n = 0; + // make a hard calculation: + n = 12 * ms; + Thread.usleep(ms * 1000); + Idle.add(supra_calculator.callback); + return n; + }); + yield; + + var result = thread.join (); + return result; + } + + async void main() { + + // Every second, print "Hi !" + Timeout.add(1000, () => { + print (@"Hi !\n"); + return true; + }); + + int res = yield supra_calculator(4000); + print (@"result: $res\n"); + } + + +the output: + + Hi ! + + Hi ! + + Hi ! + + result: 48000 + Examples -------- diff --git a/source/tutorials/programming-language/main/05-00-experimental-features/05-04-with-statement.rst b/source/tutorials/programming-language/main/05-00-experimental-features/05-04-with-statement.rst new file mode 100644 index 0000000..5589abd --- /dev/null +++ b/source/tutorials/programming-language/main/05-00-experimental-features/05-04-with-statement.rst @@ -0,0 +1,34 @@ +With Statement +============== + +.. danger:: + + Experimental Feature + +The with statement creates data type scoped blocks which allow implicit member access to the given expression or declaration statement. + + with ( [ var | unowned var | type-name) identifier = ] expression ) embedded_statement + +.. code-block:: vala + + struct Color { + int red; + int green; + int blue; + } + + void main() + { + Color c = {255, 0, 0}; + + print ("red: %d, green: %d, blue: %d\n", c.red, c.green, c.blue); + with (c) { + red = 1; + green = 2; + blue = 3; + } + print ("red: %d, green: %d, blue: %d\n", c.red, c.green, c.blue); + } + + +The with statement is a convenient way to access members of a struct or class without having to prefix them with the object name. The with statement is not recommended for use in new code, as it can make the code harder to read and understand.