Skip to content

Instantly share code, notes, and snippets.

@SoylentGraham
Last active April 5, 2023 10:43
Show Gist options
  • Save SoylentGraham/967bd5fe743e68cb16ba719262ede249 to your computer and use it in GitHub Desktop.
Save SoylentGraham/967bd5fe743e68cb16ba719262ede249 to your computer and use it in GitHub Desktop.
class TempBuffer_t
{
constructor(Module,Size,Length)
{
this.Module = Module;
if ( Size === null )
{
this.Address = 0;
this.Size = 0;
this.Length = 0;
}
else
{
this.Address = Module._malloc(Size);
this.Size = Size;
this.Length = Length;
}
}
Free()
{
if ( this.Address != 0 )
this.Module._free(this.Address);
}
GetStringAsJson()
{
const Json = this.GetString();
// extra debug if parsing fails
try
{
const Obj = JSON.parse(Json);
return Obj;
}
catch(e)
{
throw `Failed to decode JSON from buffer (x${this.Length}); ${e}. ${Json}`;
}
}
GetString()
{
return this.Module.UTF8ToString(this.Address);
}
CopyTo(OutputTypedArray,CopyByteSize=null)
{
if ( OutputTypedArray === null )
return;
// buffer is the same for whichever heap view
const Buffer = this.Module.HEAPU8.buffer;
// all typed arrays take buffer+BYTE offset (so address doesn't need to be corrected)
// note: it requires LENGTH though, not byte-size
let CopyLength = OutputTypedArray.length;
if ( CopyByteSize !== null )
{
CopyLength = Math.ceil(CopyByteSize / OutputTypedArray.BYTES_PER_ELEMENT);
}
// we will get an exception if the output is smaller than input
const ViewLength = Math.min( this.Length, CopyLength );
// skip doing anything
if ( ViewLength == 0 )
return;
const ModuleViewArray = new OutputTypedArray.constructor( Buffer, this.Address, ViewLength );
OutputTypedArray.set( ModuleViewArray );
}
}
class ModuleBufferPool_t
{
constructor(Module)
{
this.Module = Module;
}
Allocate(Data,CopyToBuffer=true)
{
// todo: use a pool!
// use null as explicit address=0 buffer
if ( Data === null )
{
const Buffer = new TempBuffer_t( this.Module, null );
return Buffer;
}
if ( Data === undefined )
throw `undefined Data passed into Module Buffer Allocation`;
// assuming bytes if number
let Size = (typeof Data == 'number') ? Data : (Data.byteLength||Data.length);
// length = elements for typed arrays
let Length = Data.length || Size;
if ( typeof Data == 'number' )
Data = null;
const Buffer = new TempBuffer_t( this.Module, Size, Length );
// copy data into heap buffer
if ( Data && CopyToBuffer )
this.Module.writeArrayToMemory( Data, Buffer.Address );
// else data is uninitialised!
return Buffer;
}
Free(Buffer)
{
// todo: return to pool
Buffer.Free();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment