Hello.
I've heard about ICE a few days ago in slashdot pointed article "The Rise and Fall of Corba" by Michi Henning. As ICE seems to be a very good replacement for difficult to use CORBA I'm trying to translate my IDLs to Slice and learn how to deal in this new environment.
As far the most difficult case is to find good solution for CORBA union replacement. I've read docs and forum threads about this but I'm not sure if proposed solution is the best in my case.
In CORBA I've created a set of generic functions to create, modify and delete some objects. Please look at the code snippet.
1. I created structures for over 30 objects:
Code:struct tOperator { string code; string name; }; struct tService { string name; }; struct tPrice { price_t price; date_t start_date; date_t end_date; }; ...
2. I've created object type enumerator for use in union container.
3. The functions:Code:enum object_type_t { OT_OPERATOR, OT_SERVICE, OT_PRICE, ... }; union tObject switch (object_type_t) { case OT_OPERATOR: tOperator m_operator; case OT_SERVICE: tService m_service; case OT_PRICE: tService m_price; ... };
Code:interface ObjectManipulator { bool createObject(out obj_id_t objid, in tObject obj); bool modifyObject(in obj_id_t objid, in tObject obj); bool deleteObject(in obj_id_t objid, in object_type_t objtype); };
In a servant I can easily and fast work on passed objects, ie:
This approach let me to create simple, easy to maintain, IDL API.Code:bool createObject(obj_id_t objid, tObject& obj) { switch (obj._d()) { case OT_OPERATOR: createOperator(obj.m_operator()); break; case OT_SERVICE: createService(obj.m_service()); break; case OT_PRICE: createPrice(obj.m_price()); break; ... } }
The problem is how to translate it to Slice and ICE. As I know, it's recomended to use classes, ie:
It looks very good. But I've got a problem with deal with this in servant and client. First, to create object I have to do in client:Code:enum object_type_t { OT_OPERATOR, OT_SERVICE, OT_PRICE, ... } class tObject { object_type_t d; }; class tOperator extends tObject { string code; string name; }; interface ObjectManipulator { bool createObject(out obj_id_t objid, tObject obj); bool modifyObject(obj_id_t objid, tObject obj); bool deleteObject(obj_id_t objid, object_type_t objtype); };
In servant I have to do:Code:tOperator* obj = new tOperator(); obj.name = "Woohaa Com"; obj.code = "WHC"; obj.d = OT_OPERATOR; // right? obj_id_t* id; createObject(id, obj);
Is this all right? If it is, then if something will be wrong with tObject.d type indicator it will be known not earlier then on run time. With CORBA unions this kind of errors give me a compiler errors. Second, It gives much more bloated code than before, with CORBA...Code:switch (obj.d) { case OT_OPERATOR: tOperatorPtr p = tOperatorPtr::dynamicCast(obj); if (p) createOperator(*p); else throw runtime_error("Invalid object type"); break; }
I know, I can handle this with tObject factory, but this requires additional effort and I don't have any guarantee that client developers will do it. So I think I should reanalyze this solution once again.
Can you help me how to do it proper with ICE?
thanks in advance.

Reply With Quote