ID:1086231
 
Keywords: api, dl
Applies to:
Status: Open

Issue hasn't been assigned a status value.
I had an idea of speeding up some ingame calculations, by making them in my own DLL, not in BYOND's VM itself, but external DLL calling has very little and not fast enought options, so result became slower than it was in BYOND's VM.

So I want some API for external DLL's to be able to affect game-world. Mainly I want few functions accessible for me from outside (so I can just include some headers to my code and link my dll with byondcore.dll or such) to get references to object's variables by object reference string (\ref[obj]) and variable name string.

So it to be like:
float *num;
extern "C" char* function foo(char **vars)
{
Object *obj = ByondAPI.getObjByRef(vars[0])
num = obj->getVar("num")->getData()
}
extern "C" char* function bar(char **vars)
{
*num=..........
}

And then I will be able to make adjustments to the var directly by it's reference.

I understand there is a chance of object being deleted so reference would point to some unassigned space, but that is totally my problem, I just would call some other function of my DLL to mark this reference as broken or renew it with new created object.

Also ability to call procs (at least argument-less) of said object would be nice too, but is not so necessary for me.

Glance at byondcore.so revealed it has some functions like LocateRefByText and GetVarPtr, which maybe what I want, but they are on linux only, and my server is Windows-based, and byondcore.dll don't have those.
The idea of reading and writing vars by reference from a DLL is an intriguing one, but it would have to be fairly limited if it existed at all, and it couldn't be done by a pointer. There's no such thing as direct var access in BYOND internally at a proc level; changing vars is all done through functions.

Assuming we provided a get/set interface so you could interact with vars, there would only be certain types you could handle. Passing numbers, strings, and null back and forth is easy. Handling lists, other object references, and the many internal object types is not. I believe such a function would have to be limited to knowing only about numbers, strings, null, generic references (almost everything would fall under that category), and possibly lists. Maybe atoms could be split out separately. The get/set routines would need to be modified in such a way as to avoid going through the normal proc crash behavior in the event of a bad value, and you'd need something that could send back an error code.

This kind of setup could be done, although I'd question whether it would be much faster than BYOND handling the calculations itself. Most of the extra overhead in BYOND would be from processing a few more instructions in the bytecode, and the DLL call would incur overhead of its own.

Direct access to the obj struct itself would sadly not be possible. Aside from the crash risk (which goes a little past "developer beware"), there is a need to keep certain internals properly in sync. This is especially true of pixel movement and big atoms, for instance, but it goes well beyond that.
Yes, I understand all that... I, myself, want to modify numbers only, so set/get other types would be great too, but not necessary for me right now. Main idea of speed up was in the fact of this: number variables in memory are just float in some place in memory, if object is not deleted - that place position would not change, so if I save that precise pointer to value itself, I would be able to modify value in just a few CPU calls. So even if it would be get/set method of access, it would be fast too, if I would be able to store memory pointer to object itself - and even better if pointer to variable object, getting/setting data from them would not be a lot more CPU consuming.

Strange fact: did 5 different forfor iterators (256x256 iterations each)
profiler says they work nearly same time, but few do lots of math, and few just iterate all the elements in list[x][y] and set one variable to off. Calling all those 7 times (256*256*7*5) takes nearly two seconds and twice the time if accessing of list[][] is made in proc, not directly