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");
but now, how to change the data member A::_IsLogin when the AMI invloved????
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&){}
};
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");
but now, how to change the data member A::_IsLogin when the AMI invloved????
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&){}
};
0
Comments
-
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.0 -
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.:)0 -
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;
}0 -
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.0 -
In my application, it is necessary to define another slice because it has more responsibilities.
the reference idea is more simple. and now i use it .:p0