Archived

This forum has been archived. Please start a new discussion on GitHub.

hard to use AMI,help me,please

The blow is a simple example only to explain what problem i encountered.

Chat.ice
#ifndef CHAT_ICE
#define CHAT_ICE

module Demo
{
interface Chat
{
["ami"]bool login(string name);
};

};

#endif // define CHAT_ICE
class ChatI : public Demo::Chat
{
//............
};

class A defined in C++
{
public
void login();
//............
private:
std::string _name;
bool _IsLogin;
Demo::ChatPrx _chati; // * a member of class A
}

// implementation of functon login() using login_async
void A::login()
{

AMI_Chat_loginPtr amiptr = new AMI_Chat_loginI;
_chati->login_async(amiptr,"kin");
}

the question is :
if i use synchronous programming model. it is very easy to get the value _IsLogin:
_IsLogin = _chati->login("kin"); :D

but now, how to change the data member A::_IsLogin when the AMI invloved???? :confused::confused:

class AMI_Chat_loginI : public Demo::AMI_Chat_login
{
void ice_response(bool res)
{
//
//how to change the data member
// A::_IsLogin when the AMI invloved????
// seems it is impossible to modefiy here
//
}

void ice_exception(const ::Ice::Exception&){}
};

Comments

  • benoit
    benoit Rennes, France
    Hi,

    You need to add a setIsLogin method to your class A to modify the _IsLogin attribute and call it from the AMI callback, for example:
    class AMI_Chat_loginI : public Demo::AMI_Chat_login
    {
    
    AMI_Chat_loginI(A& a) : _a(a) 
    { 
    }
    
    void ice_response(bool res)
    {
        _a.setIsLogin(res)
    }
    
    void ice_exception(const ::Ice::Exception&)
    {
    }
    
    private:
    
    // Using a reference might not be appropriate here 
    // if A might have been destroyed by the time the 
    // response is sent (you should reference count the A
    // class if that's the case).
    //
    A& _a; 
    
    };
    

    Note also that you'll probably have to add some synchronization to the setIsLogin method since the _IsLogin attribute will be accessed from different threads.

    Cheers,
    Benoit.
  • :D:D:D i got it .
    thanks for your prompt reply which gives me lots of hints.
    because my english is poor ,
    i dont know how to deliver my deep thanks for your kindly help.
    thanks.:) :):):):):)
  • :D now my solution is below. i use the following code to show my solution,not in details.:p

    will you tell me the advantage and disadvantafe of this solution? thanks.

    Chat.ice

    as before
    AA.ice

    module Demo
    {
    interface AA
    {
    bool loginResult(bool ret);
    };
    };

    class AAI : public Demo::AA
    {
    public:
    bool loginResult(bool ret, Ice::Current &);

    inline void IsLogin()
    {
    return _IsLogin;
    }

    // and so on .........

    private:
    bool _IsLogin;
    }

    typedef IceUtil::Handle<AAI> AAPtr;

    class A
    {
    public:

    A(const Ice::ObjectAdapter &adapter,const AAPtr aa):
    _adapter(adapter),_aai(aa);
    {
    Ice::Identity id;
    id.name = // some unique name;
    _adapter->add(_aai,id)
    };

    void login();

    void IsLogin()
    {
    return _aai.IsLogin();
    };

    private:

    AAPtr _aai // * a member of class A
    std::string _name;
    Demo::ChatPrx _chati; // * a member of class A
    Ice::ObjectAdapter _adapter;
    std::string _name;

    }
    // implementation of functon login() using login_async
    void A::login()
    {
    Ice::Identity id;

    id.name = // some unique name;

    AMI_Chat_loginPtr amiptr = new AMI_Chat_loginI(_adapter->createProxy(id));

    _chati->login_async(amiptr,"kin");

    }

    void A::loginResult(bool ret, const ::Ice::Current&)
    {
    _IsLogin= ret;
    // more codes here
    // the new value _IsLogin can be used anywhere in class A
    }

    class AMI_Chat_loginI : public Demo::AMI_Chat_login
    {
    AMI_Chat_loginI(const Ice::ObjectPrx& proxy):_proxy(proxy)
    {};

    void ice_response(bool res)
    {
    APrx proxy = APrx::uncheckedCast(_proxy);
    proxy ->loginResult(res);
    }

    void ice_exception(const ::Ice::Exception&){}

    private:
    Ice::ObjectPrx _proxy;
    }
  • benoit
    benoit Rennes, France
    Hi,

    Why do you define another Slice interface, AA, just to pass the result of the login operation? It would be much simpler to just pass the reference of your `A' class as I've mentioned above.

    Cheers,
    Benoit.
  • In my application, it is necessary to define another slice because it has more responsibilities. :o

    the reference idea is more simple. and now i use it .:p :p:p:p