Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Memory API #477

Merged
merged 29 commits into from Jan 24, 2023
Merged

Memory API #477

merged 29 commits into from Jan 24, 2023

Conversation

ggcrunchy
Copy link
Contributor

This is a small addition to the C API, and a major refinement of some policies I've been using to share binary data among my own plugins. It's basically in the spirit of a Lua metamethod: one side provides data of some sort, and then the other is able to consume it using that object's "memory interface", but without needing to know the internal details: the object could be a fixed string, a (possibly resizable) userdata of some sort, maybe even a static buffer.


I hammered out this draft before sitting down to code. Some of that's now obsolete, but it has a few examples too.

I did make an earlier attempt at such an API—files here and here—but never got around to testing it, much less submitting; anyhow, this version is much more focused and only adds five functions.


I've tested by building the simulator, overwriting the relevant binaries in the Windows install of Solar, building a modified Bytemap plugin (see this commit) linked to that, and then running a test.

The Bytemap's SetBytes() is being called in a few ways already in a test script: once with a blob of data encoded as a string (so it uses the special-case interface for them); another happens indirectly, via a Bytemap:loadTexture() (which will use the ByteProxy seen in that commit). I added a new test for the light userdata policy (also in the commit; 16 integers are encoded and stored in globals):

-- Test for memory feature, consuming light userdata encodings:
local bb = Bytemap.newTexture{ is_non_external = true, width = 1, height = 1 }
local slot = _G.SLOT

print("SLOT?", slot) -- confirm match

for i = 0, 15 do
  local encoding = _G["CONTEXT" .. i] -- get light userdata...

  bb:SetBytes(encoding) -- ...assign it...

  local a, b, c, d = bb:GetBytes{ x1 = 1, y1 = 1, x2 = 1, y2 = 1 }:byte(1, 4) -- ...and read it back

  print("Bytes?", ("%s = %x, %x, %x, %x"):format("CONTEXT" .. i, a, b, c, d)) -- will show buffer bytes (in reverse)
end

with results:

Sample run on Windows:

* From Bytemap, providing memory:

11:34:32.814  Buffer element 0 = 5f323bf6
11:34:32.814  Buffer element 1 = 3a9e797d
11:34:32.814  Buffer element 2 = 5f490ddc
11:34:32.814  Buffer element 3 = 4cad314f
11:34:32.814  Buffer element 4 = 5e144df2
11:34:32.814  Buffer element 5 = 49442e40
11:34:32.814  Buffer element 6 = 13661cd0
11:34:32.814  Buffer element 7 = 366b66c4
11:34:32.814  Buffer element 8 = 42307eb7
11:34:32.814  Buffer element 9 = 60322c3b
11:34:32.814  Buffer element 10 = 15a15422
11:34:32.814  Buffer element 11 = 3ef60822
11:34:32.814  Buffer element 12 = 5991409d
11:34:32.814  Buffer element 13 = 12e1798b
11:34:32.814  Buffer element 14 = 121f73da
11:34:32.814  Buffer element 15 = 58b026ca
11:34:32.814  Slot bound = 0

* Above code, consuming it:

11:34:32.982  SLOT?	0
11:34:32.982  Bytes?	CONTEXT0 = f6, 3b, 32, 5f
11:34:32.982  Bytes?	CONTEXT1 = 7d, 79, 9e, 3a
11:34:32.982  Bytes?	CONTEXT2 = dc, d, 49, 5f
11:34:32.982  Bytes?	CONTEXT3 = 4f, 31, ad, 4c
11:34:32.982  Bytes?	CONTEXT4 = f2, 4d, 14, 5e
11:34:32.982  Bytes?	CONTEXT5 = 40, 2e, 44, 49
11:34:32.982  Bytes?	CONTEXT6 = d0, 1c, 66, 13
11:34:32.982  Bytes?	CONTEXT7 = c4, 66, 6b, 36
11:34:32.982  Bytes?	CONTEXT8 = b7, 7e, 30, 42
11:34:32.982  Bytes?	CONTEXT9 = 3b, 2c, 32, 60
11:34:32.982  Bytes?	CONTEXT10 = 22, 54, a1, 15
11:34:32.982  Bytes?	CONTEXT11 = 22, 8, f6, 3e
11:34:32.982  Bytes?	CONTEXT12 = 9d, 40, 91, 59
11:34:32.982  Bytes?	CONTEXT13 = 8b, 79, e1, 12
11:34:32.982  Bytes?	CONTEXT14 = da, 73, 1f, 12
11:34:32.982  Bytes?	CONTEXT15 = ca, 26, b0, 58

Nothing in the engine yet uses this, so I figured it would be safe to add the files to the various platforms and get this out there. (It looked like web didn't add CoronaGraphics.*, so I also held off adding anything there.) I'll see if I can do some sanity checks on a few of these.

Per experience with the graphics APIs with other still-pending PRs, I also added the symbol exports for Windows simulator and Apple targets. If something similar is also needed on Linux, I missed it.


@Shchvova We were discussing ways to enhance meshes and I believe this is at least part of the puzzle (perhaps also the custom objects PRs). Off-hand, there are one or two other Solar APIs that might be able to export to a buffer as well. (To conveniently stuff into a binary archive, for instance.)

ggcrunchy and others added 26 commits February 7, 2019 17:09
…nd buffer and assignment logic

Next up, prepare details from graphics.defineEffect()
…from Program

Slight redesign of TimeTransform with caching (to synchronize multiple invocations with a frame) and slightly less heavyweight call site
Err, was calling Modulo for sine method, heh

That said, time transform seems to work in basic test
Fixed error detection for positive number time transform inputs

Relaxed amplitude positivity requirement
Maintenance Revert Test
My mistake adding back changes made
…(should also make the acquire logic a little less confusing)

Using interface macros

Also made two of them each

With and without arguments, that is (for public version and callbacks internally)

No check for resize's existence in *OfSize() interface methods, since NullResize would be installed then
Interface is reified when acquiring an interface, not in creation

Added dummy interface for failure case
Reverted uint16_t to unsigned short in C API
…ack correctly in memory API

Simply using void * rather than unsigned char * for byte getter signatures; in practice, was just recasting it again anyhow

A few more macros

Added references to APIs to be visible to Windows simulator
Added fake variable on Apple
@ggcrunchy
Copy link
Contributor Author

After some review, this will probably need at least another commit. MSVC is okay with the type punning (and I believe GCC is too), but I'm not sure about Clang. That's apparently a bit of a no-no per some of the standards, so should be redone; it might already be fairly memcpy()-friendly, actually. (In any case these are only implementation details.)

…nter (starting with a NULL one, in the second case), rather than a union-based type punning

Fixed a couple bad stack indices for environment keys in same (version and data lookups)
@Shchvova Shchvova merged commit 98412ec into coronalabs:master Jan 24, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants