Do it for the same reason we did it in the frame-buffer
plugin in the previous commit. It's the "right" thing
to do and now that we map lazily, doing it the old way
is broken.
All objects can now be transformed into strings which allows them to be used as
hash indexes. Some rules do still apply. If an object is lost (freed....)
another object may take on the name of the lost one. The object address is used
to create a string in the form "#(0x123abc45)". NULL has the string "#NULL".
So arr[NULL] is the same as arr["#NULL"], and similar for the objects.
Some drivers completely choke with the amount of data plymouth is
sending over the wire. This makes sure that plymouth doesn't
keep assaulting the X server when it's already overworked by asking
the server to return back a pixel before continuing.
This renderer is useful for testing plymouth splash
plugins without leaving X. It simulates a multi-head
display by creating two X windows each representing
one monitor.
Drivers backed by TTM memory manager don't support mapping the
kernel backed framebuffer console, so can't be used for doing
a smooth transition (unless you use /dev/fb). In single head
configurations, there isn't a big advantage to using libdrm
anyway, so we bail for TTM drivers.
Much of this code comes directly from ply-frame-buffer in libply,
but shoehorned to fit into the renderer plugin interface.
One improvement over the old code is it tracks VT changes, and
stops drawing when the wrong VT is active.
In order to support multiple rendering backends, and multi-head
monitor layouts, I'm moving the actually rendering to render
plugins.
Examples of plugins could be frame-buffer, drm fb, and x11
(for debugging).
The renderer class is responsible for loading the appropriate rendering
backend, and providing an interface for the rendering backend to
advertise multiple displays.
Right now we only check for a frame-buffer plugin, although, it isn't
implemented yet.
The inheritance works primarily on objects and functions.
Object example:
A.v1 = 1;
A.v2 = 2;
B.v2 = 7;
B.v3 = 3;
C = A | B;
C is now equal to A with B as a base (C.v1 = 1, C.v2 = 2, C.v3 = 3).
A and B remain unchanged.
Function example:
fib = fun (a) if (a < 2) 1; else fail;
| fun (a) if (fibcache[a]) fibcache[a] ; else fail;
| fun (a) fib (a - 1) + fib (a - 2); ;
Fail means a function is aborted and a more base function is attempted.
This is now also looked up when evaluating vars. Vars are looked for in the
local context, then within this (current object) and finally within the
global context;
As_bool now returns false for 0.0 and NAN. It uses the fpclassify which should
be a clean way of testing for zero. The as_number function simplifies a switch
to an if.
When functins are called as an element of an object (e.g. obj.func(par) ), the
object is passed into the function execution as "this" in the local context.
Rather than directly accessing hash tables when accessing variables, use the
abstraction functions. Adds a peek function which does not create a new object
is one has not been defined already.
This removes some of the duplication due to the two methods of creating
functions. Now function definitions like:
fun name (foo) {bar}
are treated as
name = fun (foo) {bar};
No script code needs to change as both are still valid.