Interfaces: correct way of using Clone() method

Have a question about our Software Developer Kit? Ask them here.
Post Reply
User avatar
AlfredOne
Beta Tester
Beta Tester
Posts: 135
Joined: Wed Dec 22, 2010 11:45 pm
Location: Terlizzi (BA) , Italy
Contact:

Interfaces: correct way of using Clone() method

Post by AlfredOne »

I need help to understand the correct way of using Clone() method in order tor clone interfaces.

What the Clone() method should do in his implementation?
How should be obtained or released a cloned interface?

Thanks.

Alfredo
Amiga500 Kickstart1.3
AmigaONE XE G4 833MHz - 2GB RAM - Radeon9200 256MB
AmigaONE X1000 - 2GB RAM
  • Radeon R9-280X 3GB
  • Radeon HIS4670 1GB DDR3
  • Radeon RX550
My site: https://project4a.eu
centaurz
Posts: 13
Joined: Sat Jun 18, 2011 1:24 pm

Re: Interfaces: correct way of using Clone() method

Post by centaurz »

Hi,

Clone() is expected to build a new interface (by means of MakeInterface()), flag it as IFLF_CLONED, initialize its private data and return a pointer to it.
In this case, Expunge() shall also be implemented in order to undo what was done in Clone() (free memory, etc...).
Such interfaces are also supposed to perform garbage collecting in Release() when their usage counter reach 0 (i.e. call DeleteInterface() on themselves if the IFLF_CLONED flag is set).

Clone() is automatically used by the system (namely GetInterface()) for interfaces declared as IFLF_PRIVATE. In this case a clone of the private interface is returned on each call. I suppose you could also use it as a real copy constructor on an existing interface like it is suggested in the SDK...

Note that this usage only makes sense for libraries that export interfaces in an object oriented fashion (that is, hardly any but application.library dockies and expansion.library pci devices). Most libraries only export a single shared interface which is just a function table (but if you ask the question you probably already know that...).
User avatar
Hans-Joerg Frieden
AmigaOS Core Developer
AmigaOS Core Developer
Posts: 223
Joined: Wed Dec 08, 2010 3:52 pm

Re: Interfaces: correct way of using Clone() method

Post by Hans-Joerg Frieden »

AlfredOne wrote:What the Clone() method should do in his implementation?
How should be obtained or released a cloned interface?
What centaurz said. Also, here's an example Clone() implementation I use in Gallium:

Code: Select all

struct Interface * _EGL_Clone(struct EGLIFace *Self)
{
	uint32 size = Self->Data.PositiveSize + Self->Data.NegativeSize;
	uint8 *newInterface = IExec->AllocVecTags(size, TAG_DONE);

	struct Interface *retValue = NULL;

	if (newInterface)
	{

		retValue = (struct Interface *)(newInterface + Self->Data.NegativeSize);
		uint8 *base = ((uint8 *)Self) - Self->Data.NegativeSize;
		IExec->CopyMem(base, newInterface, size);

		retValue -> Data.Flags = IFLF_CLONED;
		retValue -> Data.RefCount = 0;

		((eglinstance_t *)newInterface)->ITLS = (struct TLSIFace *)IExec->GetInterfaceTags(TLSBase, "main", 1, NULL);
		((eglinstance_t *)newInterface)->eglGlobalData = NULL;
		((eglinstance_t *)newInterface)->importTable = NULL;
		((eglinstance_t *)newInterface)->patchStart = NULL;
		((eglinstance_t *)newInterface)->patchEnd = NULL;
		((eglinstance_t *)newInterface)->FuncData = NULL;
		((eglinstance_t *)newInterface)->resolveFunc = NULL;
		((eglinstance_t *)newInterface)->unloadFunc = NULL;
		((eglinstance_t *)newInterface)->_eglModules = NULL;
		((eglinstance_t *)newInterface)->eglModuleMutex = IExec->AllocSysObjectTags(ASOT_MUTEX,
						ASOMUTEX_Recursive, TRUE,
						TAG_DONE);

	}
	return retValue;
}

There is nothing special you need to do, just GetInterface() this as usual; if an interface is flagged private and has a clone method, you will receive a "blank" copy of the interface that is not shared with anyone else.
centaurz wrote:Note that this usage only makes sense for libraries that export interfaces in an object oriented fashion (that is, hardly any but application.library dockies and expansion.library pci devices). Most libraries only export a single shared interface which is just a function table (but if you ask the question you probably already know that...).
Not necessarily. In this case, I made the interface private and cloned it because it requires a per-task/thread-local data. In this case, OpenGL and EGL require task-specific data (like the current error and such) so the library keeps track of that through a private interface. There is nothing "object oriented" about this, in fact, since egl functions are supposed to be called like "eglXXXX()" without an interface, the caller will not even notice that there is anything like that going on :)
NOTICE: If you want to contact me, use E-Mail. I cannot be contacted via the forum/private messages anymore
Post Reply