Re: Relationship between IoTag and IoObject

Steve Dekorte <[email protected]>
Newsgroups gmane.comp.lang.io
Message-ID <[email protected]>
On 2011-06-04 Sat, at 09:28 PM, dennisf486 wrote:
> I've been working for a while with Io as an embedded interpreter in C++ programs with my LikeMagic binding library, but there are still some things I don't understand.  (As Joshua Cearley said, the documentation for embedding Io leaves something to be desired; unfortunately those of us with the most to gain from the documentation existing don't have the knowledge of what to write for it!)
> 
> One thing in particular I don't understand is what is the architectural relationship between IoTag and IoObject in the implementation of Io?  And the relation of IoTag to CFunction?
> 
> I can see that:
> IoObject is a typedef for CollectorMarker
> CollectorMarker has a pointer to IoObjectData
> IoObjectData has a pointer to IoTag
> 
> What was the reason to have some fields in IoTag versus just putting them all in IoObjectData?  Are there many IoObjects to one tag, or is it one-to-one?  Is IoTag kind of like a "type"?

IIRC, a tag is shared by all the instances. It's sort of like a very, very primitive class that only has methods for things like slot lookups, message sends and garbage collection hooks. I think I named it Tag because IIRC, it's similar to what Lua called tags (previously "hooks").

> I see functions for adding CFunctions with or without IoTags.  How is a CFunction without an IoTag different from one with?  Is a CFunction also an IoObject, or is a CFunction with an IoTag unrelated to an IoObject with an IoTag?  Can I create CFunctions with IoTags in a CFunction factory and use setSlot to attach them where they go?

An IoCFunction (like the other atomic prototypes) is just a clone of IoObject with a custom tag. You can't not have a tag on an object IIRC - you could set it to be the same tag as an IoObject though, in which case it would behave just like an IoObject, AFAICS.

> I'm particularly interested because for my C++ binding library, it would be useful to be able to stuff an extra void* object into my CFunctions, distinct from the the target function pointer itself.  I'm hoping IoTag might be one way to do that.

I don't recommend this. I'd recommend creating an OO binding instead. You might check out some of the other Io addons for examples.

> 
> The assumption with CFunctions seems to have been that you would have a unique CFunction for every unique thing you want to do, but for my C++ bindings library I find it more convenient to have a single function in C that is my only entry point from Io, and from there branch out to whatever C++ object & method should be invoked.  Currently I do this by examing the name of the message I receive to figure out what method should actually be called, but this string lookup is not so efficient.  What I'd much rather do is be able to embed a pointer to my C++ CallTarget object in a void* inside the CFunction; then in my entry point I can just cast the void* to CallTarget and call CallTarget::eval(); no lookup needed.
> 
> I think what I want is a "void* user_data;" item right under "void* state;".

I'd recommend just copying at a simple addon like the User addon, changing it's name and then modifying it to do what you want:

https://github.com/stevedekorte/io/tree/master/addons/User/source

Basically, you write a C function (Not a IoCFunction) for each function you want to bind, e.g:

IoObject *IoUser_protoName(IoUser *self, IoObject *locals, IoMessage *m)
{
	TCHAR userName[256]; 
	DWORD userSize = 255;
	GetUserName(userName, &userSize);
	return IOSYMBOL(userName);
}

And make them a slot on your object when you set up it's proto:

IoUser *IoUser_proto(void *state)
{
	IoObject *self = IoObject_new(state);
	IoObject_tag_(self, IoUser_newTag(state));

	IoState_registerProtoWithFunc_(state, self, IoUser_proto);

	{
		IoMethodTable methodTable[] = {
		{"name", IoUser_protoName},
		{"homeDirectory", IoUser_homeDirectory},
		{NULL, NULL},
		};
		IoObject_addMethodTable_(self, methodTable);
	}
	return self;
}



> While I'm looking at IoTag:  what is the difference between performFunc and activateFunc?  What is the difference between performing and activating in Io?

performFunc handles slot lookup and then calls activateFunc and v only handles a direct activation.
e.g. if you want to change how lookup works, override performFunc. If you want to just change how activation works, override activateFunc.

Cheers and I hope this helps,
Steve
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.