r3wp [groups: 83 posts: 189283]
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

World: r3wp

[!REBOL3 Extensions] REBOL 3 Extensions discussions

BrianH
15-Jul-2010
[931]
Code:Blocks isn't bad.
Maxim
15-Jul-2010
[932x2]
Code::Blocks

http://www.codeblocks.org/
continuing Request for object lookup within host/extensions here....



Here is a proposal (using example C code) for OBJECT access within 
extensions  this uses the EXACT same API as commands, and with just 
a little bit of work on the extensions API by Carl and a single hook 
within the r3core, we could allow callbacks within objects.


the advantage is that we re-use the same safe sand box as commands, 
and don't require to do much coding to enable it, AFAICT.


since object lookup is performed on demand, we can very rapidly supply 
an object to the command, and it doesn't cause any heavy-handed conversion 
at each command call if the object isn't needed.  more fine-grained 
control could be added so we don't need to frame the whole object, 
but it would be usefull as-is already.

RXIEXT int RX_Call(int cmd, RXIFRM *frm) {
	i64 i;
	
	// objects are frames, exactly like command arguments.
	RXIFRM *obj;
	

 // return values are also frames (with one argument), for type-checking 
 purposes.
	RXIFRM *rval;
	
	if (cmd == 1) {
		// ask the core for a frame which represents object.
		// attributes are returned in order they appear in object
		//

  // the command frame doesn't include the object frame, only a handle 
  to the

  // object which the core can understand. we then ask for the object 
  frame on-demand.
		obj = RXA_OBJ(frm, 1);
		
		switch (RXA_TYPE(obj, 1)) {
			case RXT_INTEGER:
	            i = RXA_INT64(obj, 1);
				break;
			
			// we could build a frame for supplying arguments to the eval
			case RXT_FUNCTION:
				rval = RXA_EVAL(obj, 1);
				if (RXA_TYPE(rval, 1) == RXT_INTEGER){
	            	i = RXA_INT64(rval, 1);
				} else {
					// return error
				}
				break;
			
			// wrong type
			default:
				// return error
				break;
		}
		
		// do something with the value
		my-native-function(i);

	}
}

so what do you guys think?
BrianH
15-Jul-2010
[934]
Command arguments have limits on how many are passed. Those same 
limits would apply to object fields with your approach.
Graham
15-Jul-2010
[935]
7 args isn't it?
BrianH
15-Jul-2010
[936]
So objects with more than 7 fields wouldn't be supported? Command 
frames are marshaled, remember, they are not references to stack 
frames. If you want to pass an object and get access to its fields 
perhaps passing it as some kind of handle and getting access to the 
fields through accessor funcs would be better. Unless I misunderstood 
your code and you are doing this already.
Maxim
15-Jul-2010
[937]
the frame size is an artificial limit. 


the frame is just an array, there is no real reason for it to be 
limited to only 7 items, its just an initial limitation, (probably 
to simply the macros and support code).
BrianH
15-Jul-2010
[938]
Yes, but it would still be marshalled, which I thought you were trying 
to avoid.
Maxim
15-Jul-2010
[939x4]
the accessor is another approach, but marshaling would have to occur 
anyways, because on the C side we need to extract datatypes dynamically, 
which is what the current API already does.
This idea was borne out of a previous code snippet I was building 
which actually used accessors   :-)


as I was writting it up, it occured to me that I was providing a 
different syntax for the same problem.
another approach would be to access a single attribute at a time, 
but anytime data is exchanged, I think re-using the current frame 
code is ideal... 


it already solves all of the type and memory marshalling, separates 
the external data from the core, solving the issues with the GC and 
stuff like that.


as long as the API copies data when its setting values back in the 
core (which I guess its already doing) then I see no point in inventing 
a second API just for objects.
IMHO, we cannot prevent marshalling without exposing a lot more of 
the core into the extensions, and/or making extensions unsecure (able 
to peek directly within the core datasets).
Graham
16-Jul-2010
[943x6]
is anyone tracking all the new extensions being written for R3?
Oops ,, should have been in the humor group
Just curious .. why does the init_block not quote the name ?  It 
does for the titile
There are a number of bad links in the extensions-embedded.html document 
... are they just docs yet to written? Or has the doc been moved 
destroying the links?
I looked at the example ext-test.c and it lacks the extension header 
as specified in the docs
The extensions docs say that dealing with handles is undocumented 
...  but if it's just an integer, can we just pass that back and 
forth between rebol and the extension?
Maxim
16-Jul-2010
[949]
the idea of handles is for an extension to give a key to a script, 
and make sure the script can't play with it.   by key, I mean an 
arbitrary value which makes sense for the extension (pointer, index, 
value, etc).
Carl
16-Jul-2010
[950]
Quick check in. Hmmm... flooded.
Maxim
16-Jul-2010
[951x2]
carl... just look above my mock up of object access within extensions... 


does it makes sense to use the current API in given or other format?
I tried to send this on R3 chat but server is down..
Carl
16-Jul-2010
[953]
Maxim: let's see if I can get you a Reb_Get_Object(obj, word) function. 
That would work ok, right?
Maxim
16-Jul-2010
[954x3]
one of the reasons I want to use objects directly within extensions 
is that I am noticing GC recycling interruptions while scrolling 
stuff in R2 AGG driven interface.
yes that would be great.  the important detail is the need for this 
accessor to be able to get objects too, so that we can browse a whole 
object structure.
re: "GC recycling interruptions"  if we can browse the objects directly 
from extensions a lot of the need to "bake" command access within 
blocks and execute via do-commands is alleviated in the first place.
Carl
16-Jul-2010
[957x2]
Yep, I think it is a reasonable request.  The trick would be that 
you'd add any field names to the WORDs block of your ext module.
And, actually, the RXI_API would be RXI_GET_FIELD (because RXI_GET_OBJECT 
should be reserved for later obtaining parameters related to the 
object itself, such as number of values stored, etc.)
Maxim
16-Jul-2010
[959x4]
sure.


would there be a way to inspect an object to build something like 
in native C ?:

foreach words-of object [
	; ... do something ...
]
if you can add some object reference to the hostkit, I'll be switching 
over all of my tools to R3, may even help with low-level AGG, and 
finally start forgetting about R2.
:-)
as an example, we could just represent a draw structure using primitives 
as objects (which can include several AGG primitives) and call AGG 
native code directly from the object tree.

something like 
draw context [
	prim: 'cross-box
	offset: 10x10
	size: 20x20
	thickness: 1
	border: black
	cross-color: red 
]


would draw a box and two cross lines, without the need to reduce 
this at every refresh when its refreshed and data comes from external 
manipulators:

draw compose [
	pen (prim/border)
	fill-pen none 
	line-width (prim/thickness)
	line-pattern none
	box  (prim/offset) (prim/offset + prim/size - 1x1)
	pen (prim/cross-color)		
	line (prim/offset) (prim/offset + prim/size - 1x1)

 line (prim/offset  + (prim/size * 1x0)) (prim/offset  + (prim/size 
 * 0x1))
]
Carl
16-Jul-2010
[963x3]
Both examples above reduce.
Passing attributes via objects vs block of args is one of those edge 
cases where picking the best choice really depends on the source 
of the data.
For example, many graphical objects will be cached in their reduced 
blocks, so it's not a GC problem.
Maxim
16-Jul-2010
[966]
but the first one becomes a persistent object and doesn't need to 
reduce over and over.  


when the structure becomes somethings which goes beyond 50kb of draw 
source,  reducing over and over hits the GC very fast.
Carl
16-Jul-2010
[967x2]
In addition,  REDUCE on blocks now supports REDUCE/into that generates 
no garbage.
Well... I find that most coders don't pay close attention to their 
garbage side effects, but in a GUI sysetm, it's wise to do so.
Maxim
16-Jul-2010
[969]
yes, but if the structure is nested, you have to reduce things so 
they become flat.


also, not all situations allow you bind values directly to objects,
Carl
16-Jul-2010
[970]
Again, it really depends... because the DRAW block is constructed, 
objects are not that good of a substitute, because their only benefit 
is named fields, which in a constructed domain offer no clear advantage.
Maxim
16-Jul-2010
[971]
also note that I gave this example as a Draw, since we can all quickly 
see what is happening, but the above applies to many other datasets 
which are used libs, and for which objects are much more user-friendly 
than objects.


think of C libs which use deep struct trees. I'd rather keep the 
user interface object related.
Carl
16-Jul-2010
[972]
Object fields primary advantage is in human domains where the named 
fields make code more clear.
Maxim
16-Jul-2010
[973x2]
yes... but they also allow context on the REBOL source side.


note that with the example above using objects, I don't need to go 
thru a draw block on the native side.  I could inspect the object 
and fire AGG (or other lib ;-) commands directly
as you say, its a case by case issue, but in most of my larger projects, 
i end up using object for a variety of management reasons.
Carl
16-Jul-2010
[975x6]
Yes, but there is a problem in your example above in that one is 
an apple and the other an orange.
An object does not represent sequence, it represents state. A DRAW 
block represents sequence. They can be as long as you need.
So, for the above DRAW with object example to be useful, it would 
require a sequence of objects, so you're back to a block.
It's funny, I go back and forth a lot on my own designs in regard 
to object vs block.
For the human side, such as providing a style sheet containing graphics 
attributes, object is the winner. However, as that style sheet is 
processed, it is flattened into a sequence of commands sent to the 
AGG rendering engine.


Now, it's probably possible to change our API into AGG to use objects, 
and that's probably find, but I'm not sure that it's really any more 
efficient.
find = fine