foru...@hotmail.com wrote:
> #include <iostream>
> #include <typeinfo>
> #include <vector>
>
> /// BEGIN "UNTOUCHABLE" CLASSES AND DATA
> INSTANTIATORS ///////////////
> class base {
> public :
> //handful of stuff
> virtual ~base() {}
> };
>
> /*
> one of many untouchable pn derived classes with
> methods not found in base class
> */
> class p1 : public base {
> int value ;
> public :
> p1()
> : value ( 0 )
> {}
> void set_something ( int in ) { value = in ; }
> int get_something() const { return ( value ) ; }
> ~p1() {}
> };
>
> class p2 : public base {
> public :
> //stuff
> ~p2() {}
> };
> //up to pn
> /// END "UNTOUCHABLE" Pn CLASSES AND DATA
> INSTANTIATORS /////////////////
>
>
> /*
> ============================================================
> holder is a collection of UNTOUCHABLE classes, with useful
> member data (For example) 'count'. For each call to Set_ a
> phandler will
> increment count
> */
> typedef unsigned int unsigned_type ;
> struct holder {
> unsigned_type holder_id ;
> unsigned_type count ;
> static base *ptr ;
> holder ( base *ptr_, unsigned_type const id )
> : holder_id ( id )
> {
> ptr = ptr_;
> }
> virtual ~holder() { }
> };
> base* holder::ptr = 0 ;
> typedef std::vector < holder* > holder_vec ;
>
> /*
> ============================================================
> base handler for d's.
> notified upon receipt of a client message
> */
> class d_handler_base {
> public :
> virtual void process() = 0 ;
> virtual ~d_handler_base() {}
> };
> class d1_handler : public d_handler_base
> {
> holder_vec hv ;
> //only interested in p1 objects located in the holder containers
> p1* ptr_p1 ;
>
> public :
> d1_handler ( holder_vec& in )
> : hv ( in )
> //NOTE!!!!!!!!!!!!!!!!!
> //ideally i need to use a map so i could interate and FIND p1
> //for now we'll assume p1 exists at location 0 within holder_vec
> , ptr_p1 ( static_cast < p1* > ( hv [ 0 ]->ptr ) )
> {}
> void process ()
> {
> unsigned_type const dummy = ptr_p1->get_something() ;
> std::cout << std::hex << "0x" << dummy << std::endl;
> }
> };
> class d2_handler : public d_handler_base
> {
> public :
> d2_handler ()
> {}
> void process ()
> {
> std::cout <<"." << std::endl;
> }
> };
>
> /*
> ============================================================
> base handler for p's.
> notified upon receipt of a server message
> */
> class p_handler_base {
> public :
> virtual ~p_handler_base() {}
> };
> class p1_handler : public p_handler_base
> {
> holder_vec& hv;
> p1* ptr_p1 ;
>
> public :
> p1_handler ( holder_vec& in )
> : hv ( in )
> , ptr_p1 ( static_cast < p1* > ( hv [ 0 ]->ptr ) )
> {}
> void update_p_msg ( unsigned_type const in ) {
> ptr_p1->set_something ( in ) ;
> hv [ 0 ]->count ++ ;
> }
> };
>
>
> int main() {
> static holder_vec hv ;
> //this 'new new' stuff seems unsightly... i think a map would be
> better....
> // for now create a p1 with its id of 0x400, similarily a p2 with
> it's id 0x500
> hv.push_back ( new holder ( new p1(), 0x400 ) ) ;
> hv.push_back ( new holder ( new p2(), 0x500 ) ) ;
>
> d1_handler *ptrd1 = new d1_handler ( hv ) ;
> p1_handler *ptrp1 = new p1_handler ( hv ) ;
> //change
> ptrp1->update_p_msg( 0xCAFE ) ;
> ptrd1->process() ;
>
> //change
> ptrp1->update_p_msg( 0xDEAD ) ;
> ptrd1->process() ;
>
>
> std::cin.get() ;
>
> }
>
> In a nutshell:
>
> Common message holder class (named holder) with a collection of base
> classes. Within main a p1_handler object initiates a change to a p1
> object (via the call to set_something). The d1_handler observes the
> change.
>
> At this juncture you may say this 'screams' an event handler (perhaps
> observer implementation). This way any change to a Pn message by a Pn
> handler is dispatched to a Dn handler.
>
> My answer to an event handler (observer implementation) is No!
> Here's why: Referencing the d1 and d2 handler classes within source
> above:
>
> a) Not all Dn handlers is interested in Pn (UNTOUCHABLE) messages.
> For instance, the message holder vec holding Pn messages is a
> _dont_care_ for a d2_handler.
>
> b) For those Dn handler interested in Pn messages (i.e d1_handler),
> these Dn handlers are not interested in being notified of immediate
> changes to Pn messages by Pn handlers. These Dn handlers is only
> interested in knowing they have the 'latest' Pn message _whenever_
> (600 updates could have occurred since) they access a Pn message
> object.
>
> From a development perspective, here's where I'm struggling with in
> this case C++. The design and what (perhaps) pattern to use to
> achieve the objective. After scanning the GOF here are my thoughts:
>
> 1) Leave well enough alone. Current implementation works but then I'm
> often not satisfied given my struggles
> 2) Add a proxy class between the Pn handlers and Dn handlers. I
> suspect this would be beneficial to the Dn handlers (more so that Pn
> handler since a Pn message could be local to a Pn handler). In doing
> so the Dn handler could request via the Proxy for a Pn message and
> receive the 'lastest/most up to date' Pn message. The drawback here is
> the overhead and (worse) I'm not sure how to implement a proxy (at
> least not yet)
> 3) Perhaps a common base class between Pn handlers and Dn handlers
> would suffice.
>
> My question is - is there a better way to do this? Thoughts/ideas
> welcomed.
>
> Thanks in advance