-
Notifications
You must be signed in to change notification settings - Fork 5
Process Registry
#procreg.h
http://sack.sourceforge.net/sack__app__registry.html
This allows procedure registration. It registers integer values, strings, functions, interfaces and types.
##Paths The following examples are all bad exmaples of paths. THe path convention is similar to the windows registry under HKEY_CURRENT_USER/Software...
/library/module/class/...
/sack/psi/control/button/rtti/onDraw = int Draw( PSI_CONTROL pc );
/sack/psi++/control/button/....
/<application>/class
These are paths used internally for things like global types and interfaces. Functions are generally registered by application.
/system/global data/<global object name>
/system/interfaces/<interface>
a PCLASSROOT can be passed as CTEXTSTR class_name or vice versa. when building with C++, options are more limited to what you can pass. a PCLASSROOT starts with a certain, nontext prefix that can be differentiated between a string and a classroot.
Grabbing a PCLASSROOT to work from is a good idea, and saves redunant path typing.
PCLASSROOT myRoot = GetClassRoot( "<mylib>/<mymodule>" );
RegisterIntValue( myRoot, "value", 333 );
// gets a path, does not create PCLASSROOT CheckClassRoot( CTEXTSTR class_name ); // gets a path, creates if it doesn't exist. PCLASSROOT GetClassRoot( CTEXTSTR class_name );
// based on a previous path, add more options to a path. PCLASSROOT GetClassRootEx( PCLASSROOT root, CTEXTSTR name_class );
##Integer Values
RegisterIntValue( "path/to/option", "value", 333 ); int val = GetRegisteredIntValue( "path/to/option", "value" );
##functions
PROCEDURE is like void(*)(void);
it should be cast to your desired function so the macro is usually used to hide that detail.
// these are the definitions... //PROCEDURE ReadRegisteredProcedureEx( PCLASSROOT root, CTEXTSTR returntype, CTEXTSTR parms ); //#define ReadRegisteredProcedure( root,rt,a) ((rt(CPROC*)a)ReadRegisteredProcedureEx(root,WIDE(#rt),WIDE(#a)))
// this is a usage. int (*proc)(float) = ReadRegisteredProcedure( "/some/path/to/get", int, (float) );
functions are registered with their return type and arguments as part of their name. This can be (usually is) significant in returning the function. So you can have void f(), int f(), float f(), all differently named. For a while I was toying with keeping the library name as a least significant optional comparison... The names are stored sort of like ```(name)(args)(return)(library) ```
PROCREG_PROC( LOGICAL, RegisterFunctionExx )( PCLASSROOT root , PCLASSROOT name_class , CTEXTSTR public_name , CTEXTSTR returntype , PROCEDURE proc , CTEXTSTR args , CTEXTSTR library , CTEXTSTR real_name DBG_PASS ); #define RegisterFunction( nc,proc,rt,pn,a) RegisterFunctionExx( (PCLASSROOT)NULL,nc,pn,rt,(PROCEDURE)(proc),a,TARGETNAME,NULL DBG_SRC )
int f( void ) { /* some function */ } RegisterFunction( "/path/to/class", f, "int, "funcname", "(void)" );
##data Types
typedef struct someType { int a; float b; } MyType;
void open( POINTER, uintptr_t ) { /* iniitalize pointer / } void close( POINTER, uintptr_t ) { / close any resources; final close of type */ } RegisterDataType( "/path/to/class", "myType", sizeof( MyType), create, release );
uintptr_t data = CreateRegisteredDataType( "/path/to/class", "myType", "myInstanceName" ); MyType mt = (MyType)data; // data result is really a mytype type.
guess I never had the occasion to close these types... so you can create named instances of types - so if someone else asks for the same type and same instance name, they get back that same struct.
##Globals
The registered datatypes was more useful internal for single shot shared allocations. This library builds a C version and a C++ version. The two versions can interoperate; but that means that some types like FILEs, memory (malloc,free have to come from same heap) for a few examples, need to be shared. So this allows registering named globals, so the first one to ask for it gets a new instance, the second just gets the existing instance, and its initializer is not called.