Commit c98ff09e authored by Hanspeter Portner's avatar Hanspeter Portner

make forge:vector a real container object.

parent daf23114
Pipeline #6854245 passed with stages
in 6 minutes and 18 seconds
......@@ -8,4 +8,3 @@
=== High priority
* doc: Parameter
* api: make vector a real container forge object
......@@ -802,116 +802,41 @@ _lforge_key(lua_State *L)
__realtime static int
_lforge_vector(lua_State *L)
{
moony_t *moony = lua_touserdata(L, lua_upvalueindex(1));
lforge_t *lforge = lua_touserdata(L, 1);
LV2_URID child_type = luaL_checkinteger(L, 2);
uint32_t child_size = 0;
LV2_Atom_Forge_Frame frame;
int is_table = lua_istable(L, 3);
uint32_t child_size;
int n = is_table
? (int)lua_rawlen(L, 3)
: lua_gettop(L) - 2;
if( (child_type == lforge->forge->Int)
if( (child_type == lforge->forge->Bool)
|| (child_type == lforge->forge->Int)
|| (child_type == lforge->forge->Float)
|| (child_type == lforge->forge->URID) )
{
child_size = sizeof(int32_t);
if(!lv2_atom_forge_vector_head(lforge->forge, &frame, child_size, child_type))
luaL_error(L, forge_buffer_overflow);
for(int i=1; i<=n; i++)
{
if(is_table)
lua_rawgeti(L, 3, i);
int32_t v = luaL_checkinteger(L, is_table ? -1 : i+2);
if(is_table)
lua_pop(L, 1);
if(!lv2_atom_forge_raw(lforge->forge, &v, child_size))
luaL_error(L, forge_buffer_overflow);
}
child_size = 4;
}
else if(child_type == lforge->forge->Bool)
else if( (child_type == lforge->forge->Long)
|| (child_type == lforge->forge->Double) )
{
child_size = sizeof(int32_t);
if(!lv2_atom_forge_vector_head(lforge->forge, &frame, child_size, child_type))
luaL_error(L, forge_buffer_overflow);
for(int i=1; i<=n; i++)
{
if(is_table)
lua_rawgeti(L, 3, i);
int32_t v = lua_toboolean(L, is_table ? -1 : i+2);
if(is_table)
lua_pop(L, 1);
if(!lv2_atom_forge_raw(lforge->forge, &v, child_size))
luaL_error(L, forge_buffer_overflow);
}
child_size = 8;
}
else if(child_type == lforge->forge->Long)
else
{
child_size = sizeof(int64_t);
if(!lv2_atom_forge_vector_head(lforge->forge, &frame, child_size, child_type))
luaL_error(L, forge_buffer_overflow);
for(int i=1; i<=n; i++)
{
if(is_table)
lua_rawgeti(L, 3, i);
int64_t v = luaL_checkinteger(L, is_table ? -1 : i+2);
if(is_table)
lua_pop(L, 1);
if(!lv2_atom_forge_raw(lforge->forge, &v, child_size))
luaL_error(L, forge_buffer_overflow);
}
luaL_error(L, "Atom vector only supports atom:Bool/Int/URID/Float/Long/Double");
}
else if(child_type == lforge->forge->Float)
{
child_size = sizeof(float);
if(!lv2_atom_forge_vector_head(lforge->forge, &frame, child_size, child_type))
luaL_error(L, forge_buffer_overflow);
for(int i=1; i<=n; i++)
{
if(is_table)
lua_rawgeti(L, 3, i);
float v = luaL_checknumber(L, is_table ? -1 : i+2);
if(is_table)
lua_pop(L, 1);
if(!lv2_atom_forge_raw(lforge->forge, &v, child_size))
luaL_error(L, forge_buffer_overflow);
}
}
else if(child_type == lforge->forge->Double)
{
child_size = sizeof(double);
if(!lv2_atom_forge_vector_head(lforge->forge, &frame, child_size, child_type))
luaL_error(L, forge_buffer_overflow);
for(int i=1; i<=n; i++)
{
if(is_table)
lua_rawgeti(L, 3, i);
double v = luaL_checknumber(L, is_table ? -1 : i+2);
if(is_table)
lua_pop(L, 1);
lforge_t *lframe = moony_newuserdata(L, moony, MOONY_UDATA_FORGE, lforge->lheader.cache);
lframe->depth = 1;
lframe->last.frames = lforge->last.frames;
lframe->forge = lforge->forge;
if(!lv2_atom_forge_raw(lforge->forge, &v, child_size))
luaL_error(L, forge_buffer_overflow);
}
}
else
luaL_error(L, "vector supports only fixed sized atoms (e.g. Int, Long, Float, Double, URID, Bool)");
lua_pushvalue(L, 1); // lforge
lua_setuservalue(L, -2); // store parent as uservalue
lv2_atom_forge_pop(lforge->forge, &frame);
lv2_atom_forge_pad(lforge->forge, n*child_size);
if(!lv2_atom_forge_vector_head(lforge->forge, &lframe->frame[0], child_size, child_type))
luaL_error(L, forge_buffer_overflow);
lua_settop(L, 1);
return 1;
return 1; // derived forge
}
__realtime static int
......
......@@ -751,7 +751,11 @@ function save(forge)
-- serialize state to atom object
for k, v in pairs(state) do
obj:key(k):vector(Atom.Float, v)
for vec in obj:key(k):vector(Atom.Float):autopop() do
for i, w in ipairs(v) do
vec:float(w)
end
end
end
obj:pop()
......@@ -1474,30 +1478,27 @@ end</code></pre>
<p>Forge a vector atom, e.g. an atom of type Atom.Vector.</p>
<dl>
<dt class="func">forge:vector(type, value)</dt>
<dt>type (integer)</dt>
<dd>child type as integer URID, valid are: Atom.Bool, Atom.Int, Atom.Float, Atom.Double, Atom.URID</dd>
<dt>value (table)</dt>
<dd>table with vector elements</dd>
<dt class="ret">(userdata)</dt>
<dd>derived container forge object, needs to be finalized with <a href="#forge-pop">Pop</a></dd>
</dl>
<dl>
<dt class="func">forge:vector(type, ...)</dt>
<dt class="func">forge:vector(type)</dt>
<dt>type (integer)</dt>
<dd>child type as integer URID, valid are: Atom.Bool, Atom.Int, Atom.Float, Atom.Double, Atom.URID</dd>
<dt>... (bool | integer | number)</dt>
<dd>vector elements</dd>
<dd>child type as integer URID, valid are: Atom.Bool, Atom.Int, Atom.Float, Atom.Long, Atom.Double, Atom.URID</dd>
<dt class="ret">(userdata)</dt>
<dd>derived container forge object, needs to be finalized with <a href="#forge-pop">Pop</a></dd>
</dl>
<pre><code data-ref="forge-vector">-- Forge Vector
local vBool = {
true, false, true
}
function stash_tuple(forge)
forge:vector(Atom.Int, 1, 2, 3, 4, 5) -- vector items as individual arguments
forge:vector(Atom.Bool, {true, false, true}) --vector items as table
forge:vector(Atom.Int):int(1):int(2):int(3):int(4):int(5):pop()
for vec in forge:vector(Atom.Bool):autopop() do
for i, v in ipairs(vBool) do
vec:bool(v)
end
end
end</code></pre>
</div>
......@@ -2967,7 +2968,7 @@ end</code></pre>
-- serialize
function stash(forge)
forge:vector(Atom.Int, 12, 13, 14)
forge:vector(Atom.Int):int(12):int(13):int(14):pop()
end
function apply(vec)
......
......@@ -1156,24 +1156,32 @@ end
print('[test] Vector')
do
local function vectorize(forge, t, o)
local vec = forge:vector(t)
for i, v in ipairs(o) do
vec:typed(t, v)
end
vec:pop()
end
local function producer(forge)
forge:time(0)
forge:vector(Atom.Int, {1, 2, 3, 4})
vectorize(forge, Atom.Int, {1, 2, 3, 4})
forge:time(1)
forge:vector(Atom.Long, 5, 6, 7, 8)
vectorize(forge, Atom.Long, {5, 6, 7, 8})
forge:time(2)
forge:vector(Atom.Bool, {true, false})
vectorize(forge, Atom.Bool, {true, false})
forge:time(3)
forge:vector(Atom.Float, 1.0, 2.0)
vectorize(forge, Atom.Float, {1.0, 2.0})
forge:time(4)
forge:vector(Atom.Double, {3.3, 4.4})
vectorize(forge, Atom.Double, {3.3, 4.4})
forge:time(5)
forge:vector(Atom.URID, Atom.Int, Atom.Long)
vectorize(forge, Atom.URID, {Atom.Int, Atom.Long})
end
local function consumer(seq)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment