<doctitle>Scripting language syntax : objects</doctitle>
<docbody>
<hr>

<docsubtitle>Introduction</docsubtitle>
<blockquote>
<p>
The KVIrc scripting language is not object oriented in nature.
Anyway , objects are a highlevel abstraction that allow
to write complex code in a "clean" way.
So I've added at least some pseudo-object support.
</p>
</blockquote>

<docsubtitle>Generalities</docsubtitle>
<blockquote>
<p>
Objects are arranged in tree structures.<br>
Each object that you create is a children
of the builtin toplevel (root) object.<br>
The root object is created and "mantained" by KVIrc itself.<br>
Obviously all objects can have children objects.<br>
When an object is destroyed , all its children are also destroyed.<br>
The toplevel objects are destroyed when the server window
(in that the objects were created) is closed.<br>
</p>
<p>
Each server window has its indipendent tree of objects , so obviously there is
a root object available for each server window.<br>
Please note that this is different from global variables , that are
shared between server windows too.<br>
</p>
<p>
Each object is an instance of a class that defines its features.<br>
Each object has also a name , that is not necessary unique and is assigned
by the programmer; the name is just a mnemonic expedient, and
you may also not need it.<br>
Each object is identified by an <b>OPAQUE UNIQUE ID</b>.<br>
The ID is assigned by KVIrc and can be held in any variable.<br>
You can think the object id as a "handle for the object" or the object's pointer.<br>
Any action performed on the object will require its ID.<br>
The root object ID of the current server window is always available through the
<a href="s_root.kvihelp">$root</a> identifier.<br>
</p>
<p>
In any moment you can take a look at the tree of the objects
by using the "<a href="debug.kvihelp">debug</a> dump_script_objects" command.<br>
</blockquote>

<docsubtitle>Creation and destruction</docsubtitle>
<blockquote>
<p>
To create an object you must use the <a href="s_new.kvihelp">$new()</a>
function. <a href="s_new.kvihelp">$new()</a> requires at least three parameters:<br>
- The object class (more about object classes later in this document)<br>
- The ID of the parent object , (that obviously can be also <a href="s_root.kvihelp">$root</a>.<br>
- The object name<br>
</p>
<example>
%myobject = <a href="s_new.kvihelp">$new</a>(object,<a href="s_root.kvihelp">$root</a>,theName)
</example>
<p>
<a href="s_new.kvihelp">$new()</a> returns the ID of the newly created object, or
the STRING "0" if the object creation fails.<br>
In well written scripts it is not common that the object creation fails, anyway
you can check if the creation has failed by comparing the returned ID with the string "0":<br>
</p>
<example>
<a href="if.kvihelp">if</a>("%myobject" == "0")<a href="echo.kvihelp">echo</a> failed!
</example>
<p>
The object name is optional , but it may help you later in finding the object.<br>
</p>
<p>
To destroy an object use the <a href="destroy.kvihelp">DESTROY</a> command.<br>
</p>
<example>
<a href="destroy.kvihelp">destroy</a> %myobject
</example>
<p>
If the destroyed object has children objects , these are destroyed too.<br>
</p>
</blockquote>


<docsubtitle>Fields : objects as pseudo-structures</docsubtitle>
<blockquote>
<p>
All the objects can contain variable fields.<br>
You can set an object's field by using the object scope operator "-&gt;":<br>
</p>
<example>
%myobject-&gt;%fieldVariable = dataString
</example>
<p>
To unset a field set it with empty data string (just like with a normal variable).<br>
</p>
<p>
To retrieve the field data use the object scope operator in the same way:<br>
</p>
<example>
<a href="echo.kvihelp">echo</a> %myobject-&gt;%fieldVariable
</example>
<p>
The '-&gt;' operator was stolen from C.<br>
In the KVIrc scripting language it switches from the global namespace
to the object's one.<br>
So in the above example %fieldVariable is owned by the object.<br>
The first character of the variable name has no special meaning in the
object namespace (in the global namespace the variables starting
with an uppercase letter are global to the application , the other ones are local
to the command sequence).<br>
The variable names are completly case insensitive.<br>
</p>
<p>
Any <a href="operators.kvihelp">operator</a> can be used with the object field variables:<br>
</p>
<example>
%myobject-&gt;%fieldVariable = 0
%myobject-&gt;%fieldVarialbe <a href="operators.kvihelp">++</a>
<a href="if.kvihelp">if</a>(%myobject-&gt;%fieldVariable != 1)<a href="echo.kvihelp">echo</a> KVIrc is drunk , maybe a reboot will help ?
</example>
<p>
You can simulate C structures "on the fly" by using objects and fields:<br>
</p>
<example>
# Create an user description on the fly
%myobj = <a href="s_new.kvihelp">$new</a>(object,<a href="s_root.kvihelp">$root</a>,userDescription)
# Set the fields
%myobj-&gt;%nickname = Pragma
%myobj-&gt;%username = daemon
%myobj-&gt;%hostname = pippo.pragma.org
%myobj-&gt;%info = Pragma goes always sleep too late
%myobj-&gt;%info <a href="operators.kvihelp">&lt;&lt;</a> and wakes up too late too!
# Call an (user defined) alias that stores the data to a file
storetofile %myobj
# Destroy the object
<a href="destroy.kvihelp">destroy</a> %myobj
</example>
<p>
The field variables can be also dictionaries:
</p>
<example>
%theobj-&gt;%field[key] = something
</example>
<p>
Unlike in C , there is no need to declare object fields.<br>
Any object can have any field variable ; an "unset" field is equivalent to an "empty" field.<br>
</p>
Note:<br>
<blockquote>
The KVIrc scripting language is not typed.<br>
Any object class (be patient...I'll explain classes in a while) identifier can be stored in any KVIrc variable:
it is not possible to find out the object features by "examining" its identifier.<br>
This may make the usage of objects a bit "unclear";
Howewer , with some experience you will be able to use the objects in a very powerful way.<br>
The type-safety can be also simulated by a careful usage of object names;
in the above example , the %myobj object was created with the "userDescription" name.<br>
The storetofile alias could check the passed object's name and refuse to work
if that does not match "userDescription".<br>
</blockquote>
<p>
A more complex use of fields will be described later in this document.<br>
</p>
</blockquote>


<docsubtitle><a name="events">Events (aka callbacks)</a></docsubtitle>
<blockquote>
<p>
The objects have a built in support for events.<br>
An object triggers an event for example to signal a change in its state.<br>
All the objects trigger the OnDestroy event when they are destroyed.<br>
You can set the event handler by using the <a href="obj_setevent.kvihelp">OBJ_SETEVENT</a> command.<br>
</p>
<example>
%tmp = <a href="s_new.kvihelp">$new</a>(object,<a href="s_root.kvihelp">$root</a>,myobject)
<a href="obj_setevent.kvihelp">obj_setevent</a>(%tmp,OnDestroy){ <a href="echo.kvihelp">echo</a> Object with id <a href="s_this.kvihelp">$this</a> destroyed; }
<a href="destroy.kvihelp">destroy</a> %tmp
</example>
<p>
The <a href="s_this.kvihelp">$this</a> identifier evaluates to the ID of the
object that has triggered the event.
Event names are case insensitive.
You can clear an event handler by using the <a href="obj_clearevent.kvihelp">OBJ_CLEAREVENT</a> command.<br>
You can check if an event handler has been set by using the <a href="s_haseventhandler.kvihelp">$haseventhandler()</a> function.<br>
</p>
<p>
The OnDestroy event is triggered by the object , but you can also trigger it by yourself by using the <a href="obj_triggerevent.kvihelp">OBJ_TRIGGEREVENT</a> command.<br>
You can even define events that are not triggered by the object and then trigger them yourself.<br>
</p>
<example>
%tmp = <a href="s_new.kvihelp">$new</a>(object,<a href="s_root.kvihelp">$root</a>,myobject)
<a href="obj_setevent.kvihelp">obj_setevent</a>(%tmp,MyPersonalEvent){ <a href="echo.kvihelp">echo</a> Inside my personal event handler; (You have passed $# parameters  : $1- }
<a href="obj_triggerevent.kvihelp">obj_triggerevent</a> %tmp MyPersonalEvent 1 2 3 4 5
<a href="destroy.kvihelp">destroy</a> %tmp
</example>
<p>
All the events are triggered in the console window.<br>
</p>
</blockquote>


<docsubtitle><a name="functions">Member functions</a></docsubtitle>
<blockquote>
<p>
Just like in C++ , the objects have member functions.<br>
For example , the "object" class (again...read on) objects export the $name() and $class() functions.<br>
</p>
<example>
%tmp = <a href="s_new.kvihelp">$new</a>(object,<a href="s_root.kvihelp">$root</a>,myobject)
<a href="echo.kvihelp">echo</a> The object's name is %tmp-&gt;$name() , the class name is %tmp-&gt;$class()
# Destroy the object
<a href="destroy.kvihelp">destroy</a> %tmp
</example>
<p>
Another cool function exported by the "object" class is the $children() function.<br>
It returns a comma separated list of children identifiers.<br>
</p>
<example>
%tmp = <a href="s_new.kvihelp">$new</a>(object,<a href="s_root.kvihelp">$reet</a>,myobject)
%tmpchild = <a href="s_new.kvihelp">$new</a>(object,%tmp,child1)
%tmpchild = <a href="s_new.kvihelp">$new</a>(object,%tmp,child2)
%tmpchild = <a href="s_new.kvihelp">$new</a>(object,%tmp,child3)
<a href="echo.kvihelp">echo</a> The object's children list is : %tmp-&gt;$children()
# Destroy the object and the children
<a href="destroy.kvihelp">destroy</a> %tmp
</example>
<p>
A more complex example
</p>
<example>
%tmp = <a href="s_new.kvihelp">$new</a>(object,<a href="s_root.kvihelp">$root</a>,myobject)
%tmpchild = <a href="s_new.kvihelp">$new</a>(object,%tmp,child1)
obj_setevent(%tmpchild,OnDestroy){ <a href="echo.kvihelp">echo</a> Object <a href="s_this.kvihelp">$this</a> (<a href="s_this.kvihelp">$this</a>-&gt;$name()) destroyed; }
%tmpchild = <a href="s_new.kvihelp">$new</a>(object,%tmp,child2)
obj_setevent(%tmpchild,OnDestroy){ <a href="echo.kvihelp">echo</a> Object <a href="s_this.kvihelp">$this</a> (<a href="s_this.kvihelp">$this</a>-&gt;$name()) destroyed; }
%tmpchild = <a href="s_new.kvihelp">$new</a>(object,%tmp,child3)
obj_setevent(%tmpchild,OnDestroy){ <a href="echo.kvihelp">echo</a> Object <a href="s_this.kvihelp">$this</a> (<a href="s_this.kvihelp">$this</a>-&gt;$name()) destroyed; }
obj_setevent(%tmp,OnDestroy){
&nbsp;&nbsp;%count = 0;
&nbsp;&nbsp;<a href="foreach.kvihelp">foreach</a>(%t,<a href="s_this.kvihelp">$this</a>-&gt;$children()){
&nbsp;&nbsp;&nbsp;&nbsp;<a href="echo.kvihelp">echo</a> Children : %t-&gt;$name() with class %t-&gt;$class()
&nbsp;&nbsp;&nbsp;&nbsp;%count++
&nbsp;&nbsp;}
&nbsp;&nbsp;<a href="echo.kvihelp">echo</a> Just before destroying my %count children.
}
# Destroy the object and the children
<a href="destroy.kvihelp">destroy</a> %tmp
</example>
<p>
In the example above four objects have been created.<br>
A "parent" object named "myobject" , and three children objects.<br>
The OnDestroy event has been set for each child object,
to make it "say" its name (Please note the usage of <a href="s_this.kvihelp">$this</a>).<br>
In the parent OnDestroy event the children have been counted and listed.<br>
Then the parent object is destroyed causing to:<br>
- trigger the parent OnDestroy event.<br>
- destroy all the children (and conseguently trigger all the "individual" OnDestroy events).<br>
</p>
<p>
Not all the functions must return a value.<br>
If a function does not return a meaningful value , or you just want to ignore it , you can call it in the following way:<br>
</p>
<example>
%anyobject-&gt;$functionname()
</example>
</blockquote>

<docsubtitle><a name="classes">Classes</a></docsubtitle>
<blockquote>
<p>
As said before , all objects are instances of a specific class.<br>
This concept is common to almost all object oriented languages.<br>
A class is a collection of methods that define an object's behaviour.<br>
Hehe...it is not easy to explain it , so I'll try with an example:<br>
</p>
<example>
class HostAddress
{
&nbsp;&nbsp;field hostname
&nbsp;&nbsp;function ipnumber()
&nbsp;&nbsp;function isLocalhost()
}
</example>
<p>
The above class is a rappresentation of a host address.<br>
You create an <b>instance of this class</b> and set the hostname field, for example,
to www.kernel.org.<br>
The object is now able to give you informations about the hostname in a transparent way:<br>
You can call the ipnumber() function, and the object will return you the
digits and dots rappresentation of www.kernel.org.<br>
The isLocalhost() function will return true if the hostname refers to the local machine<br>
The object internal job is hidden from the user , but probably it will be a huge job.<br>
To obtain the IP number from the hostname , the object will probably have to perform a DNS call (usually a complex task).<br>
To check if the hostname references the local machine , the object will have to obtain the local hostname
from the system (in some "unspecified" way) and then compare it with the given "hostname" field.<br>
</p>
<p>
The internal job of the object is defined by the "implementation of the class".<br>
Obviously , the programmer that creates the class has to write that implementation.<br>
</p>
<example>
class HostAddress
{
&nbsp;&nbsp;field hostname
&nbsp;&nbsp;function ipnumber(){
&nbsp;&nbsp;&nbsp;&nbsp;find the nearest DNS server
&nbsp;&nbsp;&nbsp;&nbsp;make the dns call
&nbsp;&nbsp;&nbsp;&nbsp;wait for the response
&nbsp;&nbsp;&nbsp;&nbsp;decode the response
&nbsp;&nbsp;}
&nbsp;&nbsp;function isLocalhost(){
&nbsp;&nbsp;&nbsp;&nbsp;query the kernel for the local hostname
&nbsp;&nbsp;&nbsp;&nbsp;compare the obtained hostname with the hostname field
&nbsp;&nbsp;}
</example>
<p>
In the above example I have "implemented" (in a "fantasy" way) the two functions.<br>
</p>
<p>
Let's back to real world.<br>
KVirc contains a <a href="classes.kvihelp">set of built-in ready-to-use classes</a>.<br>
The basic class is "object" , that in fact does nothing other than being an object,
having an unlimited number of fields, trigger the OnDestroy event.<br>
Another available class is "socket" that is an interface to the real system sockets.<br>
An instance of the "socket" class can connect and communicate with other hosts on the net.<br>
The <b>class definitions are GLOBAL to the entire application</b> : all server windows share them.<br>
In any moment you can take a look at the tree of defined classes by using the
"<a href="debug.kvihelp">debug</a> dump_classes" command.<br>
</p>
<p>
So now we can say that in KVIrc<br>
<b>
a CLASS is a collection of features that define the behaviour of an object.<br>
The user interface to the class are the member functions and the events.<br>
</b>
</p>
</blockquote>


<docsubtitle><a name="inheritance">Inheritance</a></docsubtitle>
<blockquote>
<p>
Someone asked for derived classes ?<br>
Here we go:<br>
The <a href="class.kvihelp">CLASS</a> command allows you to define new object classes.<br>
In KVIrc , a new class must be always derived from some other class.<br>
</p>
<example>
<a href="class.kvihelp">class</a>(helloworld,object)
{
&nbsp;&nbsp;function(sayhello){
&nbsp;&nbsp;&nbsp;&nbsp;<a href="echo.kvihelp">echo</a> Hello world!
&nbsp;&nbsp;}
}
</example>
<p>
The above class is named "helloworld".<br>
It inherits the "object" class.<br>
This means that it acquires all the "object" class functions: $name() , $class() , $children()...<br>
Additionally , it has the $sayhello() function, that "echoes Hello world" to the console.<br>
Now you can create an instance of this class:<br>
</p>
<example>
%instance = <a href="s_new.kvihelp">$new</a>(helloworld,<a href="s_root.kvihelp">$root</a>,myhelloworldinstance)
%instance-&gt;$sayhello()
</example>
<p>
You should see "Hello world" printed in the console.<br>
Easy job...let's make the things a bit more complex now:
Derive another class from helloworld and make it say "hello" in two different languages:<br>
</p>
<example>
<a href="class.kvihelp">class</a>(localizedhelloworld,helloworld)
{
&nbsp;&nbsp;function(setlanguage){
&nbsp;&nbsp;&nbsp;&nbsp;<a href="if.kvihelp">if</a>(("$1"=="english") || ("$1" == "italian")){
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="s_this.kvihelp">$this</a>->%language = $1
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;setreturn 1
&nbsp;&nbsp;&nbsp;&nbsp;} else {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="echo.kvihelp">echo</a> I don't know that language ($1)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="s_this.kvihelp">$this</a>->%language = english
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;setreturn 0
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;}
&nbsp;&nbsp;function(sayhello){
&nbsp;&nbsp;&nbsp;&nbsp;<a href="if.kvihelp">if</a>("<a href="s_this.kvihelp">$this</a>->%language" == "italian")<a href="echo.kvihelp">echo</a> Ciao mondo!
&nbsp;&nbsp;&nbsp;&nbsp;else <a href="s_this.kvihelp">$this</a>-&gt;$helloworld:sayhello()
&nbsp;&nbsp;}
}
</example>
<p>
Now you can call:<br>
</p>
<example>
%myobj = <a href="s_new.kvihelp">$new</a>(localizedhelloworld,<a href="s_root.kvihelp">$root</a>,myobj)
%myobj-&gt;setLanguage(italian)
%myobj-&gt;sayhello()
%myobj-&gt;setLanguage(english)
%myobj-&gt;sayhello()
%myobj-&gt;setLanguage(turkish)
%myobj-&gt;sayhello()
<a href="destroy.kvihelp">destroy</a> %myobj
</example>
<p>
The class defined above is inherited from the previously defined helloworld class:
so it inherits the "object" class functions and events and the sayhello function from "helloworld".<br>
In addition a setlanguage function is defined that stores in a variable the language name passed
as a parameter (after checking its validity).<br>
($1 evaluates to the first parameter passed)<br>
If the language is unknown the setlanguage function will return 0 (false).<br>
Now we want to be able to say "hello world" in italian and english.<br>
So we <b>override</b> the inherited sayhello function.<br>
"To override" means "to reimplement" : if you call %object->$sayhello() and %object
contains the ID of an instance of class "localizedhelloworld" , the new implementation of that function willl be called (executed).<br>
The inherited sayhello was able to say "hello world" only in english , so we can still use it in the new implementation
without rewriting its contents. So if the language set is "not italian" we assume that it is english and
call the <b>base class implementation</b>:
</p>
<example>
<a href="s_this.kvihelp">$this</a>-&gt;$helloworld:sayhello()
</example>
<p>
otherwise the language is italian and we say "hello" in italian :).<br>
So , to call a base class implementation of a function we "prepend" the base class name before the function name in the call.<br>
The base class name could be also "object" in this case , but the "object" class has no "sayhello" function defined
so it would result in an error.<br>
In the above example , all the values of <a href="s_this.kvihelp">$this</a>-&gt;%language
that are not equal to "italian" are assumed to be "english".<br>
This is not always true , for example , just after the object creation the %language variable field
is effectively empty.<br>
The above class works correctly in this case , but we might want to have always
a coherent state of the field variables , so we need another concept: the class <b>constructor</b>
that will be discussed in the next paragraph.<br>
</p>
<p>
Note: multiple inheritance (inheritance from more than one base class) is not implemented , KVIrc is not a compiler :)<br>
</p>
<p>
Objects are much more powerful....<br>
Do a <a href="clearobjects.kvihelp">clearobjects</a> to cleanup the old class definitions , and read on.<br>
</p>
</blockquote>

<docsubtitle><a name="constructors">Constructors and destructors</a></docsubtitle>
<blockquote>
The class constructor is a <b>function</b> that is called automatically just after the object
has been created internally by KVIrc and just before the <a href="s_new.kvihelp">$new</a>
function returns.<br>
It should be used to setup the internal object state.<br>
Unlike in C++ , in KVIrc , the constructor should return a value:<br>
If it returns the string "0" it signals the object creation failure : the object
is immediately destroyed and <a href="s_new.kvihelp">$new()</a>
returns <b>the string "0"</b> to the caller (It is a string , NOT a numeric value!).<br>
Any other return value is treated as success , so the object is effectively
created and <a href="s_new.kvihelp">$new()</a> returns its ID to the caller.<br>
All the builtin classes have a constructor defined that will almost never fail (only if we run out of memory),
so you can avoid to check the <a href="s_new.kvihelp">$new()</a> return value
when creating the instances of the built-in classes.<br>
In derived classes you can override the constructor to setup your object's state.<br>
You should always call the base class constructor in your overridden one , to setup
the base class state , and propagate its return value (eventually modified if the base class
constructor is succesfull but your derived class initialization fails).<br>
In practice , the builtin class constructors do nothing other than setting the return
value to 1 so you can even avoid to call them in directly inherited classes.<br>
</blockquote>

<docsubtitle><a name="signals">Signals and slots</a></docsubtitle>
<blockquote>
<p>
The signals and slots are a powerful mean of inter-object communication.<br>
A signal is emitted by an object to notify a change in its state.<br>
For example , the <a href="class_button.kvihelp">button class</a> emits the
<a href="class_button.kvihelp#clicked">clicked</a> signal when the user clicks the button.<br>
This behaviour is similar to the object events.<br>
The main difference is that the events have a single callback function associated
and it is executed in the triggerer object scope.<br>
A signal is emitted by an object and can be received and handled by any other existing object
(including the object that emits the signal).<br>
The handler function for a signal is called "slot".<br>
It is just a convention : in fact , a slot is a normal object function (and any object function can be a slot).<br>
More than one slot can be connected to a single signal , and more signals can be connected to a single slot.<br>
In this way , many objects can be notified of a change in a single object , as well as a single object
can easily handle state-changes for many objects.<br>
</p>
<p>
The signal / slot behaviour could be easily implemented by a careful usage of object events.<br>
<b>So why signals and slots ?</b><br>
Because signals are much more powerful in many situations.<br>
Events are KVI++ equivalent of C/C++ "virtual functions" , and are useful in implementing derived
classes , to change the behaviour of the derived class itself.<br>
The signals have no equivalent in C/C++...but they have been implemented in many highlevel
C/C++ libraries and developement kits (including the system-wide signal/handler mechanism implemented
by all the modern kernels and used in inter-process communication).<br>
</p>

</blockquote>


<docsubtitle>Related functions, identifiers and commands</docsubtitle>
<blockquote>
<p>
<a href="s_new.kvihelp">$new()</a><br>
<a href="destroy.kvihelp">DESTROY</a><br>
<a href="s_root.kvihelp">$root</a><br>
<a href="s_this.kvihelp">$this</a><br>
<a href="obj_setevent.kvihelp">OBJ_SETEVENT</a><br>
<a href="obj_clearevent.kvihelp">OBJ_CLEAREVENT</a><br>
<a href="s_haseventhandler.kvihelp">$haseventhandler()</a><br>
<a href="obj_triggerevent.kvihelp">OBJ_TRIGGEREVENT</a><br>
<a href="class.kvihelp">CLASS</a><br>
<a href="clearobjects.kvihelp">clearobjects</a><br>
<a href="s_classdefined.kvihelo">$classDefined</a><br>
</p>
</blockquote>

<hr>
<a href="index.kvihelp">Main index</a> , <a href="syntax.kvihelp">Syntax index</a> , <a href="classes.kvihelp">Index of builtin classes</a>
</docbody>


</docbody>
