GMWolf
aka fel666
Something that has always been a bit tricky in Gamemaker is managing data and their types.
This problem is most apparent when attempting to use multiple libraries together.
This is why I suggest we, the community, come up with a standard way of storing data.
A Reusable Data Unit (RDU).
What is the point?
An RDU borrows ideas from Java Beans, and aims to achieve many of the same goals.
It would allow libraries to reflectively inspect the type of data given to it, and access its fields, without it having been designed for that piece of data in particular.
For example, a library could be written to save and load RDU's, and have it work on any kind of data. This would be achievable because even though the library would not know about the type of data before hand, it could find out enough about it at run time.
Another advantage of using such RDU's would be their reusability. An RDU returned from one library could easily be used by another.
For instance, you could imagine having two libraries: one would request data from a web server, whilst the other would display arbitrary data on screen.
Ordinarily, you would have to convert the data returned from the web server into a form the display library can understand.
If both libraries are "RDU compliant", the data could be passed directly from one library to the other.
Finally, Having a standard way of defining interfaces for data means that code easier to read and understand, as libraries can rely on shared preconceived notions.
Naturally, such RDU's make most sense when used with libraries that are designed to work with arbitrary data. That is not to say libraries that work on specific data could not benefit from RDU's either; being able to return RDU's makes them more compatible with other libraries.
Here is my first proposal:
Requirements:
Proposal:
RDU script
r script
destroy script
rdu_typeof script
Example Usage
rdu_vector script
This script defines the vector RUD type
vector script
The vector constructor script. r() must be called to register the type of the RUD
vector_destroy, vector_x and vector_y can be anything you like, depending on how you chose to define your vector.
Things that still need working out:
So what do you guys think? Is this something GM needs?
Would you change anything to the requirements, proposal or requirements?
Do you have a proposal of your own?
Lets discuss!
excuse any mistakes i may have made, I may well have made this thread a little hastily...
This problem is most apparent when attempting to use multiple libraries together.
This is why I suggest we, the community, come up with a standard way of storing data.
A Reusable Data Unit (RDU).
What is the point?
An RDU borrows ideas from Java Beans, and aims to achieve many of the same goals.
It would allow libraries to reflectively inspect the type of data given to it, and access its fields, without it having been designed for that piece of data in particular.
For example, a library could be written to save and load RDU's, and have it work on any kind of data. This would be achievable because even though the library would not know about the type of data before hand, it could find out enough about it at run time.
Another advantage of using such RDU's would be their reusability. An RDU returned from one library could easily be used by another.
For instance, you could imagine having two libraries: one would request data from a web server, whilst the other would display arbitrary data on screen.
Ordinarily, you would have to convert the data returned from the web server into a form the display library can understand.
If both libraries are "RDU compliant", the data could be passed directly from one library to the other.
Finally, Having a standard way of defining interfaces for data means that code easier to read and understand, as libraries can rely on shared preconceived notions.
Naturally, such RDU's make most sense when used with libraries that are designed to work with arbitrary data. That is not to say libraries that work on specific data could not benefit from RDU's either; being able to return RDU's makes them more compatible with other libraries.
Here is my first proposal:
Requirements:
- An RDU must be able to hold data in fields.
- An RDU must be able to hold other RDUs.
- An RDU must expose each field through a standard mechanism.
- An RDU field must be typed.
- An RDU must be constructable with no parameters
- Agnostic to representation of RDU data
- An RDU must not hold transient data.
- An RDU must be typed.
- An RDU's representation must be inherently unique. (instance id, array...)
- An RDU must be distinguishable from non RDU data.
- Non RDU data must be distiguishable from RDU data.
- Virtual Destruction of RDU's through a single function.
- Avoid or report clashing of RDU types.
Proposal:
- Interface to an RDU made of constructor, destructor and getter-setter scripts.
Getter-Setter scripts both get and set data, based on argument count. (reduces number of scripts in resource tree) - Interface to RDU defined using script prefixed with "rdu_". Script index is used as type index of rdu. (this avoids naming clashes, as GM will complain if scripts clash).
- Constructor must call a register script to register the RDU type with the framework
RDU script
Code:
gml_pragma("global", "RDU()");
global._rdu_types = ds_map_create();
global._rdu_constructor_table = ds_map_create();
global._rdu_destructor_table = ds_map_create();
global._rdu_field_table = ds_map_create();
global._rdu_rdus = ds_list_create();
global._rdu_id = -1;
#macro rdu_constructor global._rdu_constructor_table[? global._rdu_id]
#macro rdu_destructor global._rdu_destructor_table[? global._rdu_id]
#macro rdu_fields global._rdu_field_table[? global._rdu_id]
//Register all RDU's
for(var script = 0; script_exists(script); script++) {
var s_name = script_get_name(script);
if (string_copy(s_name, 1, 4) == "rdu_") {
var rdu_type = script;
var rdu_name = string_delete(s_name, 1, 4);
ds_list_add(global._rdu_rdus, rdu_type);
script_execute(script);
}
}
Code:
gml_pragma("forceinline");
global._rdu_types[? argument0] = argument1;
return argument0;
Code:
var type = rdu_typeof(argument0);
var destructor = global._rdu_destructor_table[? type];
script_execute(destructor);
ds_map_delete(global._rdu_types, argument0);
Code:
return global._rdu_types[? argument0];
Example Usage
rdu_vector script
Code:
rdu_constructor = vector;
rdu_destructor = vector_destroy;
rdu_fields = [ ["x", vector_x],
["y", vector_y] ];
vector script
Code:
var v = //whatever you like. An array would be nice, could be an instance, etc
return r(v, rdu_vector);
vector_destroy, vector_x and vector_y can be anything you like, depending on how you chose to define your vector.
Things that still need working out:
- A mechanism to get RDU field names from RDU type
- A mechanism to get RDU field by name.
- A typing mechanism for RDU fields
So what do you guys think? Is this something GM needs?
Would you change anything to the requirements, proposal or requirements?
Do you have a proposal of your own?
Lets discuss!
excuse any mistakes i may have made, I may well have made this thread a little hastily...
Last edited: