aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/docs/ClientHamr/README.GuiLua
diff options
context:
space:
mode:
Diffstat (limited to 'docs/ClientHamr/README.GuiLua')
-rw-r--r--docs/ClientHamr/README.GuiLua581
1 files changed, 581 insertions, 0 deletions
diff --git a/docs/ClientHamr/README.GuiLua b/docs/ClientHamr/README.GuiLua
new file mode 100644
index 0000000..f60d7b2
--- /dev/null
+++ b/docs/ClientHamr/README.GuiLua
@@ -0,0 +1,581 @@
1GuiLua is basically a redo of my ancient Java based matrix-RAD system,
2but using Lua and EFL. Lua is entirely different from Java, and Lua
3doesn't run in web browsers, so this version has similar concepts, and
4similar names, it's not exactly the same. It's more accurate to say
5this is in the spirit of matrix-RAD.
6
7The ultimate goal is for the various ClientHamr parts to be able to
8either host their own UI, or have it hosted in the in world 3D window.
9Matrix-RAD's ability to run either server or client side, with no change
10to the code, is great for this sort of thing. If I can manage the
11ability to "tear off" windows, in other words, pull them out of the 3D
12window to be real windows, then that's something people have been asking
13for from LL forever.
14
15Stdin/out might be good to use. Extantz starts up "client" programs,
16with a "use stdin/out" argument, the clients pass skang commands (open
17this internal window with these widgets) to extantz through their
18stdout, extantz passes skang commands (these values where set by these
19widgets) back through their stdin. With no "use stdin/out" argument,
20the programs host their own UI. Perhaps extantz can just pass the UI
21skang stuff back to the client, which will mean "draw your own window",
22to support the "tear off" feature. If I remember skang had suitable
23serialization stuff to support this. Lua does anyway. B-)
24
25Naturally, like matrix-RAD, all this UI stuff can happen across a socket
26as well as through stdin/out. Should be transparent to the user proggy.
27
28I can redesign skang to be more Lua like, to take advantage of Lua's
29meta language capabilities. Since no one used skang anyway, I can get
30away with this. Also should add a Lua friendly wrapper around nails, so
31that addons for Extantz can be supplied entirely as Lua scripts. In
32other words, LuaSL scripts. On top of all that, should also allow
33access to the Edje Lua stuff I've already written, but drag it outside
34of an edje file.
35
36This pretty much means that GuiLua should be a shared library, coz in
37the ClientHamr use case, several programs are gonna be using it at once.
38Should also be separate modules for development stuff like the skin
39editor, which could be just another proggy using GuiLua.
40
41Initially GuiLua can wrap elementary / evas, with the goal of wrapping
42NAWS, just like matrix-RAD was originally planned. Then I can put off
43writing NAWS for another decade. lol
44
45Might be nice to have a wrapper that is a web server that generates
46standard HTML forms. No JavaScript, no HTML5, just plain old,
47compatible with everything, HTML forms.
48
49
50Design notes
51------------
52
53Edje Lua does not wrap elementary widgets, and is not likely to due to
54elementary being compiled after edje. Smart objects and swallows
55probably can deal with that though, I'm not familiar enough with them to
56know. Eo on the other hand allegedly offers introspection, which was
57always the corner stone of matrix-RAD. So access to elementary widgets
58via Eo might be possible. That's kinda the entire hook I'm hoping will
59help to make matrix-RAD style stuff work as well as it did there.
60Apparently when they promised introspection with Eo, they meant compile
61time, not run time.
62
63Edje Lua is restricted to scripts in edje files, AND sandboxed to those
64edje files as well. We want to step outside that sandbox, and run stand
65alone Lua scripts, as well as GuiLua / LuaSL scripts internal to
66extantz. Some merging of LuaSL and Edje Lua, leaving room for GuiLua,
67would be great, but I might have to convince Raster. Note that the
68socket idea wont work in sandboxed edje Lua scripts, unless the socket
69is in C code, that uses edje messages as the internal transport.
70
71Just so it's easier to find, I'll repeat a bit from the Enlightenment
72mailing list here, the result of discussions with raster and other
73interested parties -
74
75"First step is to write edje functions for generically bundling up one
76or more Lua tables into a message, sending that message, then unpacking
77it again. This will be able to be done from edje, from C, and from Lua
78directly. Perhaps adding that as one more edje messege type. This is
79for sending Lua tables between threads. A later addition will be to
80send them through the 'net, probably as eet.
81
82Host apps can register arbitrary functions with edje Lua, using a more
83generic version of the code I already wrote for letting edje register
84lua functions. These host functions are by default not thread safe.
85Edje puts a wrapper function around the host app, and registers that
86wrapper function with Lua. The wrapper function, when called from Lua,
87does this -
88
89ecore_thread_main_loop_begin();
90call the host app callback();
91ecore_thread_main_loop_end();
92
93The first alternative, which the host app must request, is for the
94wrapper function to use the table message functions to marshal the
95arguments, send it to the main thread, wait for the response (or do
96something else), then unmarshal the result before sending it back to
97Lua.
98
99The second alternative, which the host app must REALLY request, is for
100the host app to say "I'm REALLY going out of my way to be threadsafe,
101just call me direct". No edje wrapper function, BUT the host app still
102has to use edje to register this function.
103
104The first two might be done this way -
105
106host_cb = edje_lua2_functions_add(...);
107edje_lua2_function_marshal_set(host_cb, function);
108
109The last one could be -
110
111host_cb = edje_lua2_threadsafe_function_add(...);
112
113Note the difference between _functions_ and _function_. The first call
114registers an entire metatable full of functions, in the same way that
115edje does for it's functions. These are the default sort of
116functions. The second call references one of those previously
117registered functions, and makes it marshal arguments and results. The
118third one registers a single function, but it could be added to an
119existing metatable registered by the first function."
120
121and -
122
123"We are actually half way there. Anticipating that there would be way
124more edje and evas stuff to add to the edje Lua API in the future, I
125created generic wrapper functions to make that easier. Implementing
126this would mean exposing those static functions, and writing more of
127these generic wrapper stuff.
128
129Lua already provides a mechanism for this sort of thing, but we
130currently sandbox that out. We can provide a very limited version of
131the package module, that only lets the Lua script load modules that the
132host app explicitly provides. This keeps edje Lua in it's strictly
133sandboxed state."
134
135Raster also wants to thread lots of edje, likely including having edje
136Lua scripts as threads, much like I'm doing with LuaSL already. Plus
137LuaJIT SPEEEEED!!. B-)
138
139
140Skang notes
141-----------
142
143So, what will this variation of skang look like? For a start, the
144syntax will have to be more Lua like, so that's a real basic change.
145Can't use a space as an argument separator, Lua allows only ',' and
146';'. Strings can still use single or double quotes.
147
148The magic "_123" system I used before to specify "position / size in
149characters instead of pixels" just wont work in Lua. Using _ as a table
150name with a meta table means that this syntax now becomes "_.123", which
151is kinda acceptable. Note that _.123 is syntax sugar for _["123"], so
152I'm not sure if using a number there works. An alternative is to just
153use a string -
154
155foo = widget.label(0, "1", 100, 0, 'Text goes here")
156
157Uses as many characters, and ends up being a value instead of an index,
158which is the right thing to do. While on this subject, anything less
159than 1, but more than 0, can be used as a percentage, maybe combined
160with "character" mode (this is a new thing) -
161
162foo = widget.label(0, "0.1", 0.5, 0, 'Text goes here")
163
164This could even allow relative placement as mentioned in the skang TODO -
165
166foo = widget.label(0, "otherWidget+0.1", 0.5, 0, 'Text goes here")
167
168
169"widget" would be a table with functions for dealing with widgets. It
170would include metatable stuff for widget set introspection. So
171"widget.label" would introspect in our widget set for a widget type of
172"label", and return a widget type table. So we could do -
173
174foo = widget.label(0, "0.1", 0.5, 0, 'Text goes here :")
175foo:colour(255, 255, 255, 0, 0, 100, 255, 0)
176foo:hide()
177foo:action("skang.load(some/skang/file.skang)")
178
179Also allow access via table elements -
180
181foo.action = "skang.load('some/skang/file.skang')"
182foo.colour.r = 123
183foo.look('some/edje/file/somewhere.edj')
184foo.help = 'This is a widget for labelling some foo.'
185
186We can use the concat operator (..) to append things to widgets, like
187adding choices in a drop down, rows in a grid, etc.
188
189Hmm, need a skang table as well -
190
191skang.module(Evas)
192skang.module(Elementary)
193skang.clear()
194skang.load('some/skang/file.skang')
195
196
197I don't think we need variable introspection as much, since in this case
198Lua is both the skang and the underlaying language, the variables can
199just be accessed directly. Not sure on this, need to experiment. This
200is what we normally need variable introspection for -
201
202foo = 'bar' -- Using the metatable to override '=' to set the actual value of the widget, say the text of a label or edit widget.
203bar = foo -- The reverse of the above. Though perhaps these can't be done?
204foo = foo .. 'stuff' .. 'more stuff' .. 'another line of the dropdown or whatever'
205
206OK, first two can't be done, metatable only overides that for table elements. The third one can only be (I might be wrong there) -
207
208foo.value = 'stuff' .. 'more stuff'
209foo.value = foo.value .. 'another line of the dropdown or whatever'
210
211Skang relied on the use of the set command to make sure that any
212matching widgets and variables got updated. And the get command.
213
214foo:set('stuff')
215bar = foo:get()
216
217On the other hand, given the module / package stuff mentioned below, and
218some metatable magic, we could do -
219
220local other = require('otherPackageName')
221other.foo = 'stuff'
222bar = other.foo
223
224Sooo, how does that squeeze into a "skang" file?
225
226#!skang myApp.skang -- This is Lua, so this might not work.
227-- There's an implied local this = require('myApp')
228-- There's an implied local skang = require('skang')
229local widget = require('EvasWidgets')
230local other = require('otherPackageName')
231skang.clear
232skang.window(200, 200, "G'day planet.")
233quitter = widget.button('Quit', 0.5, 0.5, 0.5, 0.5)
234quitter:action('quit') -- 'quit' is looked up in ThingSpcae.commands, and translated into the Lua 'skang.quit()'.
235other.foo = 'stuff'
236this.bar = other.foo
237
238
239Original Skang infrastructure
240-----------------------------
241
242Skang starts with a Thing as the base. In Java it's a base object for
243everything else, with a bunch of methods and elements. We can probably
244use a Thing metatable and replicate most of it. The widget used in the
245previous section is built on top of Thing. Things are stored in
246ThingSpace, which is a BonsaiTree of LeafLike Things. Java's version of
247multiple inheritance was used. Commands are a Thing.
248
249ThingSpace is per users session. classCache stores cached class
250lookukps, command stores commands, module stores loaded modules, param
251stores variables and their values, widget stores widgets and their value
252/ state.
253
254Skanglet is a generated mapping between actual methods / variables in a
255class, and skang. Each method or variable that ends up in the skanglet
256was marked by special javadoc tags. It also included some meta data
257like version and the default skang. For variables it defined -
258
259"Name", "Field/Method()", "Required", "Shortcut", "Default", "Help text"
260
261... and for methods -
262
263"Name", "Method", "Syntax", "Help text"
264
265In both cases the "Name" was the skang name, it could be different from
266the Java name specified in the second field. Likely we can do away with
267the need to generate these skanglet files, and just add stuff to the
268Thing. Modules wrap Skanglets, and takes care of loading them into ThingSpace.
269
270Module are used for -
271 loading the Skanglet for the Thing currently running (match java class name to skang file name).
272 loading the AWT interface in skang files.
273 loading OTHER skanglet based Things
274 loading Squeal, StuffSkang, and Who from java when needed.
275
276So in Lua, we can use the package system. First require(moduleName) to
277load up the skang module. Require can return a table, the Lua package
278called ends with "return someTable". See LuaLSL for an example. This
279package is actually run, so it can figure out what to put in the
280returned table. So for instance it could use inlined methods and such -
281
282local skang = require('skang')
283local result = {};
284result.author = 'onefang'
285result.version = '0.72 alpha 2004-11-19 16:28:00'
286local foo
287-- The first argument would be the name of a local variable / method. Which could be accessed via _G?
288-- Not sure if we could use a global foo, AND use it directly.
289result.foo = skang.newParam('foo', "Required", "Shortcut", "Default", "Help text")
290result.func = skang.newCommand('arg1_type,arg2_type', 'Help Text', function (arg1, arg2)
291...
292end)
293return result;
294
295
296Stuff is the base class used to track database rows and other multi
297value things. Would still need to deal with variable sub things, though
298that's likely just using tables. SquealStuff is the database version,
299using Squeal as the database driver wrapper. Squeal could wrap
300esskyuehl?
301
302
303The pre tokenized structure thingy I had planned in the TODO just wont
304work, as it uses symbols. On the other hand, we will be using Lua
305tables anyway. B-)
306
307
308NAWS
309----
310
311NAWS was always planned, but never actually written. Though some stuff
312was kinda prototyped, especially UberMatrix stuff. I think this time
313around, NAWS should be written in C, based on pure Evas + Edje. Perhaps
314with direct support for introspection? After EO settles down, I might
315use that to.
316
317
318Edje_Lua notes
319--------------
320
321Edje_Lua is sandboxed firmly inside of edje files. This makes it
322unsuitable for our use, as we want to step outside that sandbox.
323However, we still want to wrap Lua around EFL stuff, preferably using
324the same API. Raster fought against using this new eolian stuff to
325generate edje_lua2.c, and seems to be against having a "no sandbox" flag
326in edje_lua2.c. For now I'll let q66 go ahead with his Edje Lua via
327LuaJIT FFI conversion that uses a variation of eolian written in Lua.
328Seems like much more work than my way of doing it. shrugs
329
330Unfortunately, this might not be ready soon enough for me, AND it might
331not even be suitable. While I agree that LuaJIT FFI stuff might be a
332good idea, if I read the docs correctly FFI simply wraps around C
333headers and libraries directly, making it less suitable for sandboxes
334and other environments where you want to wrap those library functions
335differently.
336
337So, I might have to go ahead with my own plan anyway. On the other
338hand, for skang, I want to wrap things a bit differently. Might be best
339to do that wrapping C side. In other words, the skang and widget Lua
340packages get written in C, and are different from edje_lua2.c.
341
342On the gripping hand, there might be use in including edje_lua2.c style
343bindings in GuiLua as an edje package, evas package, elementary package,
344etc. This could be done by going ahead with my plans to modify
345edje_lua2.c to include the "no sandbox" flag, then compile it with that
346flag turned on to produce a standard Lua package. Then get eolian to
347produce evas_lua.c, elementary_lua.c, etc.
348
349Another idea worth investigating is to rewrite edje_lua2.c to use
350introspection directly to figure out it's "combined set and get" style
351bindings.
352
353
354Introspected EFL notes
355----------------------
356
357See below for the basic EO notes, where I come to the conclusion that
358the other EFL devs wont be adding introspection to EO themselves. It's
359all too hard they say. Pffft
360
361So, I might have to do this myself, call it "entro"....
362
363Write a patch against eolian that outputs introspection data. That data
364is C code for a hash of EO class names. Each hash points to a data
365structure that includes a hash of method names for that class, and a
366pointer to the class description. Each of those hashes points to a data
367structure that includes an array of argument types and names. The
368method ID should be in that structure to, and maybe even the doc text.
369Might even include an Eo internal data structure that links Op IDs to
370that method structure (I dunno what they call that). The final output
371is a library of that C code, that includes functions for doing the
372actual introspection.
373
374See? Not to hard at all, all described in a paragraph. lol
375
376One function we could include is a way to "compile" eo_do arguments.
377That would be an array (va_list actually) of method ID's followed by the
378arguments for that method. Some of those arguments might be pointers to
379memory structures, so this is not suitable for storing on disk.
380Instead, it could be used for "compiling" commonly used code or hot
381paths to get the introspection overhead out of the way early. Could
382also compile parameterized versions, with numbered place holders that
383get filled in later. Certainly we need a Lua interface to eo_do of some
384sort.
385
386In the same way that Java skang cached the results of introspection in
387ThingSpace.CLASS, we could use cache introspection lookups to speed
388things up. Not a great saving, one hash lookup versus two. Caching the
389"class.method" string that points to the method structure for any method
390we have used already.
391
392NAWS could use the compile function to create eo_do commands needed to
393create each of it's widget types, and the window. Yes, I know, NAWS
394only has two "widget types". B-)
395
396
397For quick and dirty early testing, I'll probably write a widget package
398that has hard coded mappings between some basic "label", "button", etc.
399and ordinary elementary widgets. Proper introspection can come later.
400
401
402LuaJIT FFI notes
403----------------
404
405LuaJIT 2.0 FFI needs to have cleaned up versions of C header files
406included in the Lua scripts that use it. This is messy. Version 2.1
407(or perhaps 3.0) has on it's road map to include a C pre processor,
408which should help that problem.
409
410
411EO notes
412--------
413
414tl;dr - eo introspection doesn't actually exist, even though it was
415"promised" years ago, but looks trivial to add. On the other hand, the
416other EFL devs seem to be fighting against it, so I might need to write
417my own. sigh
418
419object = eo_add(EVAS_OBJ_LINE_CLASS, canvas);
420 evas_line.eo.h -> #define EVAS_OBJ_LINE_CLASS evas_obj_line_class_get()
421 -> const Eo_Class *evas_obj_line_class_get(void) EINA_CONST;
422 evas_line.eo.c -> EO_DEFINE_CLASS(evas_obj_line_class_get, &_evas_line_class_desc, EVAS_OBJ_CLASS, NULL);
423 Eo.h -> EO_DEFINE_CLASS is a macro that basically wraps eo_class_new(), and returns it's result.
424
425So Eo_Class is the type of a class, but it's A) opaque, B) deprecated!
426It includes a pointor to the Eo_Class_Description, which includes the
427actual name. I'm not seeing anywhere the names of the get/set
428paramaters being passed into the system, or any way to look up a class
429based on name. Not even a way to get to the public Eo_Class_Description
430from the opaque Eo_Class.
431
432Eo_Class_Description is at least public. It includes
433Eo_Op_Description's and Eo_Event_Description's. Eo_Op_ and Eo_Event_
434include the name and documentation of the op / event. The macro used to
435generate Eo_Op_ does NOT pass the name, just the ID number as a string.
436There is also Eo_Op_Func_Description, which does not include a name, it
437seems to be generated in the constructor. The same Eo_Op_ ID number is
438used to index it. Seems to be no direct link between Eo_Class and
439Eo_Op_func_, just the same Eo_Op_ ID numbers used internally somehow.
440
441eo_do(obj, evas_obj_line_xy_set(200, 200, 300, 300));
442 evas_line.eo.h -> #define evas_obj_line_xy_set(x1, y1, x2, y2) EVAS_OBJ_LINE_ID(EVAS_OBJ_LINE_SUB_ID_XY_SET), EO_TYPECHECK(Evas_Coord , x1), EO_TYPECHECK(Evas_Coord , y1), EO_TYPECHECK(Evas_Coord , x2), EO_TYPECHECK(Evas_Coord , y2)
443 #define EVAS_OBJ_LINE_ID(sub_id) (EVAS_OBJ_LINE_BASE_ID + sub_id)
444 extern EAPI Eo_Op EVAS_OBJ_LINE_BASE_ID;
445
446 enum
447 {
448 EVAS_OBJ_LINE_SUB_ID_XY_SET,
449 EVAS_OBJ_LINE_SUB_ID_XY_GET,
450 EVAS_OBJ_LINE_SUB_ID_LAST
451 };
452 evas_line.eo.c -> EAPI Eo_Op EVAS_OBJ_LINE_BASE_ID = EO_NOOP;
453 static void _gen_evas_line_class_constructor(Eo_Class *klass)
454 {
455 const Eo_Op_Func_Description func_desc[] = {
456 EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_CONSTRUCTOR), _eo_obj_evas_line_constructor),
457 EO_OP_FUNC(EVAS_OBJ_LINE_ID(EVAS_OBJ_LINE_SUB_ID_XY_SET), _eo_obj_evas_line_xy_set),
458 EO_OP_FUNC(EVAS_OBJ_LINE_ID(EVAS_OBJ_LINE_SUB_ID_XY_GET), _eo_obj_evas_line_xy_get),
459 EO_OP_FUNC_SENTINEL
460 };
461 eo_class_funcs_set(klass, func_desc);
462 }
463
464 static void
465 _eo_obj_evas_line_xy_set(Eo *obj, void *_pd, va_list *list)
466 {
467 Evas_Coord x1 = va_arg(*list, Evas_Coord);
468 Evas_Coord y1 = va_arg(*list, Evas_Coord);
469 Evas_Coord x2 = va_arg(*list, Evas_Coord);
470 Evas_Coord y2 = va_arg(*list, Evas_Coord);
471 _evas_line_xy_set(obj, _pd, x1, y1, x2, y2);
472 }
473
474 void _evas_line_xy_set(Eo *obj, Evas_Line_Data *pd, Evas_Coord x1, Evas_Coord y1, Evas_Coord x2, Evas_Coord y2);
475
476 evas_object_line.c -> EOLIAN static void _evas_line_xy_set(Eo *eo_obj, Evas_Line_Data *_pd, Evas_Coord x1, Evas_Coord y1, Evas_Coord x2, Evas_Coord y2)
477
478
479Evas_Object_Line *o = eo_data_scope_get(obj, EVAS_OBJ_LINE_CLASS);
480Evas_Object_Line *o = eo_data_ref(obj, EVAS_OBJ_LINE_CLASS);
481
482
483.. evas_line.eo
484
485class Evas_Line (Evas_Object)
486{
487 legacy_prefix: evas_object_line;
488 eo_prefix: evas_obj_line;
489 properties {
490 xy {
491 set {
492 /*@
493 @since 1.8
494
495 Sets the coordinates of the end points of the given evas line object. */
496 }
497 get {
498 /*@
499 Retrieves the coordinates of the end points of the given evas line object.
500 second end point. */
501 }
502 values {
503 Evas_Coord x1; /*@ The X coordinate of the first point. */
504 Evas_Coord y1; /*@ The Y coordinate of the first point. */
505 Evas_Coord x2; /*@ The X coordinate of the second point. */
506 Evas_Coord y2; /*@ The Y coordinate of the second point. */
507 }
508 }
509 }
510 implements {
511 Eo_Base::constructor;
512 }
513
514}
515
516... evas_line.eo.c
517
518EAPI void
519evas_object_line_xy_set(Evas_Object *obj, Evas_Coord x1, Evas_Coord y1, Evas_Coord x2, Evas_Coord y2)
520{
521 eo_do((Eo *) obj, evas_obj_line_xy_set(x1, y1, x2, y2));
522 return ;
523}
524
525
526static const Eo_Class_Description _evas_line_class_desc = {
527 EO_VERSION,
528 "Evas_Line",
529 EO_CLASS_TYPE_REGULAR,
530 EO_CLASS_DESCRIPTION_OPS(&EVAS_OBJ_LINE_BASE_ID, _evas_line_op_desc, EVAS_OBJ_LINE_SUB_ID_LAST),
531 _evas_line_event_desc,
532 sizeof(Evas_Line_Data),
533 _gen_evas_line_class_constructor,
534 NULL
535};
536
537
538skang vs edje vs LL shit
539------------------------
540
541EDJE
542Verbose, complex.
543Used to place and decorate widget parts.
544Can be used to place entire widgets through externals and swallows.
545Basic parts relative to each other.
546Signals and messages.
547Embryo scripts.
548Lua scripts (sandboxed).
549
550
551SKANG
552Tight, simple.
553Used to place widgets, and describe actions.
554Can include some really basic scripting.
555Widgets in a fixed position, but included stuff for relative placement in the TODO.
556Automated associations between widget name and variable (and method?) via introspection.
557Actions.
558Looks (could easily be extended to edje groups).
559Extensible.
560Can be used to pass values around.
561
562
563LL SHIT
564Verbose, even worse, XML, more crap than is needed.
565Menus.
566Windows with widgets relative to each other.
567 Basically nested rectangles.
568Manual association of widgets to methods.
569Can include tool tip string, enabled, visible, hover cursor, bounding rectangle?, mouse opaque?, tab groups, font (name, size, style, and alignment).
570 More stuff, typically hidden in the OO somewhere. sigh
571Generally uses fixed image and colour names, which skins overide.
572Skins can also overide the XML files.
573Translations provide override XML files that need only override the text bits.
574
575
576old notes
577---------
578
579See if it's possible to disable the Emerald/Phoenix/Firestorm LSL bridge
580when connecting to OpenSim. Actually, they finally came to their senses
581and support OpenSim now, so that should be sorted already.