File: tutorial.ascii

package info (click to toggle)
entity 0.7.2-6
  • links: PTS
  • area: main
  • in suites: woody
  • size: 5,352 kB
  • ctags: 5,272
  • sloc: ansic: 61,707; sh: 7,921; makefile: 732; perl: 399
file content (858 lines) | stat: -rw-r--r-- 23,634 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858









				     EEnnttiittyy IInnttrroodduuccttiioonn

				       The Entity Team

				       March 10, 2001



					  AAbbssttrraacctt

	    An introduction to the use of Entity.



       _1_.  _N_o_t_e

       This tutorial was started in hopes of having it complete by the time we
       released 0.7.0.	However, I didn't want to wait on it being done, but thought
       this still might help people out.  If you would like to do some work on this,
       please email imain@gtk.org.
       _2_.  _I_n_t_r_o_d_u_c_t_i_o_n

       The road to world domination is paved with obstacles. Your users want inter-
       faces that are intuitive and flexible, but you don't have the time to tweak a
       thousand lines of C++, compilation after tweak after compilation. Or maybe your
       users want to modify the interface to their own needs?

       Perhaps what you want is an easy way to serialize your application's state, to
       save it to disk or share it across the network?

       Maybe you want your application use a rich storage format, but can't spare the
       investment to draft a format document, implement a parser, test it, maintain it
       ..

       Entity is here to minimize the effect of these obstacles on your programs.
       Entity reduces the time wasted by all these tasks, and is a real hoot to work
       with to boot!

       Entity isn't just a rapid development framework, though. Entity gives your
       applications structure and serializable representation, a simple and powerful
       component model, and the opportunity to mix and match languages as you like -
       write your application's logic in your favourite dynamic, interpreted language
       like python or javascript, use components written in perl, even optimize time-
       critical sections in C.

       Entity is not geared solely to user interface applications, but it was designed
       with this in mind, and works well in that role.	Entity is actually a program
       that takes an XML description, and turns that description into in-memory
       objects.  The scripting language of your choice is then used to manipulate
       these objects at runtime, allowing you to easily create dynamic applications.
       The objects may then be returned to an XML representation at any time.



	Entity Introduction							     1





	Entity Introduction							     2



       _3_.  _U_s_i_n_g _X_M_L

       Entity uses XML as a textual representation of an application.  XML is parsed
       by Entity into a tree in memory.  Everything is marked up from XML, including
       the user interface, code, and data that an application may use.

       Why XML ?  While XML does have its share of problems, it is the natural fit for
       a tree-like markup, and is easily human readable and editable.  It's also
       fairly fast and simple to parse.

       Entity does not use all of the XML specification - only a small subset of all
       that "XML" can entail. All you need to know about XML is a few simple things.
       We'll use an example to illustrate:


	    <element attribute="value">
	      some data belonging to the outer node
	      <child-element attribute="value"/>
	      some more data belonging to the outer node
	    </element>

       The words used in the above example name the parts of the representation they
       occupy.	An 'element' defines the type of the 'node'.  A 'node' is a single
       entry in an XML document.  An attribute is just that - an attribute of the
       node, and of course, every attribute must have a value. You will also find that
       we use the word "tag" as synonym for "element".

       You will notice from the above example that XML must be 'balanced', and that
       every tag must be properly closed.  You will notice that the second line is
       closed by using the '/>' - a special notation to allow you to close the node
       without an explicit closing tag.

       In the above example, the 'child-element' node becomes a child of the parent
       'element' node.	This is because the 'child-element' is declared within the
       'element' node - before the 'element' node was closed.

       You can also bind 'data' to a node.  This is done by having text placed after
       you start a node, and before you end it. The data will be concatenated and
       attached to its node. For example:


	    <sometag>
	    here is some data..
	      <someothertag> bananas and pineapples </someothertag>
	    here is more data
	    </sometag>

       The string "\nhere is some data..\n \nhere is more data", (\n is a way to say
       "enter" or "linebreak") will then be bound to the "sometag" node, and "bananas
       and pineapples" will be bound to the "someothertag"

       Another useful XML-ism used in Entity is CDATA.	CDATA is just a way to quote
       the data of a node, so you can use XML's special characters in your data.
       Here's what it looks like:








	Entity Introduction							     3



	    <javascript>
	    <![CDATA[

	    data goes here ...
	    <this won't confuse the parser>

	    ]]>
	    </javascript>

       This allows you to insert any kind of text in the CDATA section, without escap-
       ing it.	This is often used for code sections within Entity.

       Similar to CDATA are "processing command" nodes. The XML specification states
       that the data between <? and ?> markers should be passed straight to the pro-
       gram, without interpretation as XML. This is used to make a less ugly quoted
       tag. The example for CDATA would look like this with a processing command node
       instead:


	    <?javascript

	    data goes here
	    <this won't confuse the parser>
	    ?>

       _4_.  _D_a_t_a _S_t_r_u_c_t_u_r_e_s

       The XML tree is translated into a live tree of objects, but these objects may
       be thought of as if you were manipulating the XML tree directly.  The struc-
       tures/concepts that make up this tree are:

	  +o ENode

	    This is the basic in-memory node, it has attributes and stores the infor-
	    mation about the item it builds when it is added to the tree.  An enode is
	    displayed as 'element.name', when element is the type of node, and name is
	    the name attribute, if no name attribute is set, name will be an under-
	    score and a unique number.	ex 'button._342'.  This is mapped into a Class
	    in most languages, which you can use to bind to a node in a running Entity
	    application.  See the ENode API reference below for more details.

	  +o Attribute

	    This is an attribute of the enode, within the renderers functions are reg-
	    istered for when an attribute is set or requested.	In OO speak, these act
	    as methods of the class of the node type.

	  +o Path

	    A Path is how to describe where an enode is in the program, it starts at
	    the root and progresses down the tree of enodes, putting the element.name
	    representation seperated by '/'s until it gets the the destination enode.
	    In most languages if you print an enode it will give its path.









	Entity Introduction							     4



       _5_.  _G_e_t_t_i_n_g _S_t_a_r_t_e_d_.

       Now that we have an understanding of XML, and a general idea of how Entity
       itself works, we'll show you how to create and run simple program.

       Running entity Programs

       Entity works like a scripting languages in how it loads up its applications.
       The command:

       $ entity file.e

       will load up file.e (which contains an application marked up in XML), and begin
       interpreting it.

       Alternatively you can use what is called the 'shebang' method, in which you
       make the first line of the file:

       #!/path/to/entity

       or

       #!/usr/bin/env entity

       and set the file's permissions to include execution. This allows you to run it
       as an interpreted file directly, without having to call entity on it each time.
       The second method is preferred because it will work as long as you have
       /usr/bin/env, and Entity is in your path. Entity's XML parser knows to ignore
       shebang lines if they are present.

       A first Entity program

       Our sample file looks like this:


	    <object name="foo">
	      <window title="This app rules">
		<button label="DO NOT CLICK ME"/>
	      </window>
	      <?perl
	    ### This is where the code will go, when we write it later
	      ?>
	    </object>

       When entity parses this, it builds a tree of ENodes that can be represented
       like this:

	    /object.foo
	      /window._123
		/button._254
	      /perl._343

       The names "_123", "_254" and "_343" are just unique identifiers made up by
       entity; they may be different from run to run.








	Entity Introduction							     5



       This should be familiar to anyone who has seen a graphical directory tree
       browser.  We can see that we have a root, "/", which has a single child, an
       object node called "foo". "foo" in turn has two children:  a window node with
       an arbitrary (but unique) name, and a perl node with another arbitrary name.
       The window has one child: a button node with an arbitrary name.

       At parse time entity will construct the implementations of these tags and keep
       them synchronized with your tree.  In our example, a window is made with title
       "This app rules", containing just a button labelled "DO NOT CLICK ME".  Also,
       the perl code is compiled and placed in its own perl namespace.

       As a consequence of these at-startup actions, syntax errors or compilation
       errors in code elements will be flagged at startup.  The tree will still con-
       tinue being built and the program will be run, but the offending node will not
       be added to the tree.

       Once entity has finished parsing the XML file and building the in-memory
       objects, entity waits for events to happen - events being anything the applica-
       tion listens to, from user actions to network activity.

       If the user clicks the button, entity looks to see if that button wants to
       report the event to anyone.  Since our example has no code, nothing happens.
       Let's change that now.

       Change your file to look like this:


	    <object name="foo">
	      <window title="This app rules">
		<button label="DO NOT CLICK ME" onclick="perl:clicked"/>
	      </window>
	      <?perl
		sub clicked
		{
		  $the_button = shift;
		  print "button $the_button was clicked\n";
		}
	      ?>
	    </object>

       So what's changed?  We've added an attribute called "onclick" to our button
       tag, with the value "perl:clicked".  This means that when a click event hap-
       pens, entity looks in any perl nodes within the parent object tag (this is one
       of the main roles of the object tag) for a procedure called "clicked" and exe-
       cutes that.

       We've also added some code in the perl node, a sub called "clicked" that we've
       told the button to call on click events.  This sub takes one parameter: the
       node that was clicked.  This is so you can use a single handler for a number of
       events, which can often be a very elegant way of doing things.

       You will find that in many applications programmers will set the "default-lang"
       attribute in the object node to specify what language should be called when no
       language identifier is given.  For example:








	Entity Introduction							     6



	    <object default-lang="javascript">
		<button onclick="some_javascript_function"/>
		...
	    </object>

       Because of the 'default-lang="javascript"' attribute of this object, when the
       button is clicked, entity assumes the onclick callback "some_javascript_func-
       tion" is in fact a javascript function.	Entity will search for this function
       in any javascript nodes within this object and execute this function.
       _6_.  _A _M_o_r_e _c_o_m_p_l_e_x _A_p_p_l_i_c_a_t_i_o_n

       To really excercise some entity, we're going to make an application that modi-
       fies its own structure.

       Here's the XML:


	    <object name="foo">
	      <window title="This app rules">
		<button label="DO NOT CLICK ME" onclick="perl:clicked"/>
	      </window>
	      <?perl
		sub clicked
		{
		  $the_button = shift;
		  print "button $the_button was clicked\n";
		  $the_button->attrib("label" => "I TOLD YOU NOT TO CLICK ME");
		  $xml_to_be_appended = qq!
		    <window title="This app still rules">
		      <button label="REALLY, DO NOT CLICK ME" onclick="perl:clicked"/>
		    </window>
	    !;
		  $the_button->append_xml($xml_to_be_appended);
		}
	      ?>
	    </object>

       Now every time a button is clicked, this button-node has its "label" attribute
       changed, and a small XML tree is appended to the button-node.  The appended XML
       becomes a child of the button-node and consists of a window-node which in turn
       has another button-node as its child.  This new button can then be clicked,
       which calls the "perl:clicked" callback, which then changes the label and
       appends another small XML tree...  and so on ad infinitum.

       Note in this case that the same perl callback function can be used any number
       of times with various entity events (in this case, with "onclick" events from
       various buttons).  Notice, also, that entity dynamically re-renders changed
       attributes and new nodes.
       _7_.  _E_N_o_d_e _A_P_I

       The ENode API is the interface with which all work is done in Entity.  It is
       through this API that the programmer is able to change the XML tree at runtime,
       and thereby produce a non-static application.









	Entity Introduction							     7



       The enode API is similar across all languages, but not identical.  The refer-
       ence API is documented in docs/ENode.idl, in the Entity distribution.  This API
       is then mapped as well as possible into each language supported by Entity.
       Some languages also have special ways of doing things that can make life eas-
       ier.  Where that is the case, those features have been used.

       There are a few global methods that the langauges embedded within Entity will
       recognise.  These will all return either a single ENode object (an instance of
       the ENode class), or a list of ENode objects.  These are generally designed to
       find nodes within your application, and return the object representation of
       them to you so that you may manipulate them.  All these search routines will
       start at the parent 'object' tag of the code that calls them.  This allows
       seperate 'object's to exist within entity, and not have them interfere with one
       another.

	  +o enode

	    This function returns the ENode that matches its argument.	This is gener-
	    ally a 'basename' argument, that is, the type of the node concatenated
	    with the name of the node (eg, 'button.mybutton').	The name is also
	    optional, so you may simply search for 'button' and it will return the
	    first match.  If the arg starts with a '/' it will return the node based
	    on a full path starting at the root of the XML tree.  If no node matches
	    it will return the appropriate NULL construct for the language it was
	    called from.

			   Examples:
				perl:
				     my $node = enode("button.Mybutton");
				javascript:
				     othernode = enode ("ctree.FooCtree");
				C:
				     ENode *thisnode;
				     thisnode = enode ("valign.MyAlign");
				python:
				     thatnode = enode("object");
				tcl:
				     set node [enode object.FooObject]


	  +o enode_rx

	    Same as enode except the argument it accepts is a regular expression (perl
	    compatible), matching the basename of each node in turn.


















	Entity Introduction							     8



			   Examples:
				perl:
				     $node = enode_rx('window\.Win[1-4]');
				javascript:
				     anothernode = enode_rx("ctree\.FB.*");
				C:
				     Enode *mynode;
				     mynode = enode_rx ("[button|window]\.ThisNode");
				python:
				     nodetwo = enode_rx (".*");
				tcl:
				     set foonode [enode_rx object\..*]


	  +o elist

	    Returns a list of nodes matching the argument.

			   Examples:
				perl:
				     my @nodes = elist("ctree");
				javascript:
				     nodes = elist("ctree-row");
				C:
				python:
				     nodes = elist("graph");
				tcl:


	  +o elist_rx

	    Same as elist but uses a regular expression to perform the match.

       Now that we know how to get an ENode object, there are many things we can do
       once we get this object.  The following is a list of methods supported:

	  +o parent

	    Return a new ENode object that is the first parent that matches the
	    string, this only searches directly up the tree.  If no argument is given
	    (or in the case of C, it is NULL) it will return the immediate parent.

	  +o child

	    Much like enode, but searches only the children of the ENode object it is
	    called with.  Note that this will return any matching descendant node, not
	    just immediate children.

	  +o child_rx

	    Same as child but uses a regular expression for matching.

	  +o









	Entity Introduction							     9



	  +o children

	    Returns a list of ENode's matching the first basename argument.  If there
	    is no argument, it returns all the immediate children.

	  +o children_rx

	    Like children but uses a regex.

	  +o children_attrib

	    Takes two arguments, attrib and value.  This will search all children of
	    the node it is called from, and return any children who have the an
	    attribute matching the given value.

	  +o children_attrib_rx

	    Identical to above, but a regular expression may be used for the value
	    argument, and will return the list of nodes that have values for the sup-
	    plied attribute matching that regular expression.

	  +o attrib

	    Get or set an attribute.  The first argument is the attribute, the second
	    is the new value.  If no second argument is given, this function returns
	    the present value of that attribute.  Note that many language bindings use
	    a more natural notation to express attribute getting and setting - python
	    for example lets you reference a node's attributes using indexing (ie,
	    node["attribute"] = value).

	  +o

	  +o attrib_is_true

	    Check to see if the attribute supplied is true, (true, yes, 1, etc).
	    Returns a boolean.

	  +o destroy

	    Destroy the current node, and all children.

	  +o destroy_children

	    Destroy all the children of the current node while leaving the node it is
	    referred from alone.

	  +o get_xml

	    Returns an XML representation of the given node and all its children.

	  +o get_child_xml

	    Returns an XML representation of all the given node's descendants, NOT
	    including itself.








	Entity Introduction							    10



	  +o append_xml

	    Parse the given XML string and build the objects it specifies under the
	    referred ENode.

	  +o call

	    Entity has a universal way of calling functions in any of the languages
	    that it supports.	This method of the ENode class, allows you to tap into
	    this functionality, and call a function in another language, and option-
	    ally, in another 'object'.

	    The ENode object that is calling this method, will be used as the 'refer-
	    ence node', in determining which object the search for the function to
	    call will be performed in.	It will also appear as the first argument to
	    the called function, regardless of other arguments supplied.

	    The second argument, is the name of the function you wish to call.	This
	    may use the "language:function" notation that you see in callbacks from
	    nodes (because it's the same mechanism).

	    The third argument, is the prototype string that lists the type of the
	    following arguments.  This had to be done for languages like C that make
	    it impossible to determine argument types, and because many language have
	    stricter typing rules than perl, python, javascript etc.

	    The argument string can have these letters "nesidb".  n, s, and i should
	    be all you need externally, they are for node, string, and int respec-
	    tively.

	    Example: calling a the python function "foo" with parameters (1, "a
	    string")

			   node.call("python:foo", "is", 1, "a string")


	  +o new_child

	    Create a new child within the node, new_child can accept info about the
	    new node in a few ways.  The name can be specified with the element like
	    new_child("button.goodname").  Also attributes may be set by doing attrib,
	    value, attrib, value.  Note that this is another function that will vary
	    slightly depending on the language used.  This returns the newly created
	    child ENode object.

	  +o set_data

	    Set the data of the ENode to the string supplied as the only arugment.

	  +o get_data

	    Retrieve the data of the ENode.










	Entity Introduction							    11



	  +o append_data

	    Append the string given as the only node, to the data currently bound to
	    the node.

	  +o insert_data

	    Insert a string at any location within the current data.

	  +o delete_data

	    Delete a range of data within the node beginning at any offset.
       _8_.  _G_o_i_n_g _F_u_r_t_h_e_r _W_i_t_h _E_n_t_i_t_y

       This section is incomplete.  It should show a good sample program showing call-
       backs, tree searches, attrib functions etc.  This should really be the bulk of
       the tutorial.
       _9_.  _T_i_p_s _a_n_d _t_r_i_c_k_s

       This section is incomplete.  Should mention:

	  +o Config files in XML.

	  +o timers.

	  +o which attribs get saved.

	  +o userrenderers

	  +o norender

	  +o nodes as DB, interfaces with DB's etc.

	  +o entity -a file.e stembuilder.e for inspection/tweaking

	  +o multiple 'concurrent' objects

	  +o polling with the io renderer
       _1_0_.  _A_b_o_u_t

       Many thanks to John Wimer, Ian Main, Jim Meier, and Stephen Balukoff for help-
       ing with this tutorial.

       The latest version of this tutorial will always be made available at
       http://www.entity.cx.

















	Entity Introduction							    12





































































					  CONTENTS



       1.   Note ................................................................... 1

       2.   Introduction ........................................................... 1

       3.   Using XML .............................................................. 2

       4.   Data Structures ........................................................ 3

       5.   Getting Started. ....................................................... 4

       6.   A More complex Application ............................................. 6

       7.   ENode API .............................................................. 6

       8.   Going Further With Entity ............................................. 11

       9.   Tips and tricks ....................................................... 11

       10.  About ................................................................. 11

































					      i