mirror of
https://github.com/glest/glest-source.git
synced 2025-08-11 19:04:00 +02:00
Bugfixes for network game launching:
- discard inprogress messages that don't apply during launch - added better error handling of disconnects during game launch and play on both server and clients
This commit is contained in:
@@ -405,7 +405,7 @@ void ClientInterface::updateKeyframe(int frameCount)
|
|||||||
{
|
{
|
||||||
bool done= false;
|
bool done= false;
|
||||||
|
|
||||||
while(!done)
|
while(done == false)
|
||||||
{
|
{
|
||||||
//wait for the next message
|
//wait for the next message
|
||||||
waitForMessage();
|
waitForMessage();
|
||||||
@@ -489,13 +489,17 @@ void ClientInterface::updateKeyframe(int frameCount)
|
|||||||
DisplayErrorMessage(string(__FILE__) + "::" + string(__FUNCTION__) + " Unexpected message in client interface: " + intToStr(networkMessageType));
|
DisplayErrorMessage(string(__FILE__) + "::" + string(__FUNCTION__) + " Unexpected message in client interface: " + intToStr(networkMessageType));
|
||||||
quit= true;
|
quit= true;
|
||||||
close();
|
close();
|
||||||
|
done= true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(isConnected() == false && quit == true) {
|
||||||
|
done = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientInterface::waitUntilReady(Checksum* checksum)
|
void ClientInterface::waitUntilReady(Checksum* checksum) {
|
||||||
{
|
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
|
||||||
Logger &logger= Logger::getInstance();
|
Logger &logger= Logger::getInstance();
|
||||||
@@ -514,15 +518,15 @@ void ClientInterface::waitUntilReady(Checksum* checksum)
|
|||||||
|
|
||||||
int64 lastMillisCheck = 0;
|
int64 lastMillisCheck = 0;
|
||||||
//wait until we get a ready message from the server
|
//wait until we get a ready message from the server
|
||||||
while(true)
|
while(true) {
|
||||||
{
|
|
||||||
if(isConnected() == false) {
|
if(isConnected() == false) {
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
|
||||||
string sErr = "Error, Server has disconnected!";
|
string sErr = "Error, Server has disconnected!";
|
||||||
sendTextMessage(sErr,-1);
|
//sendTextMessage(sErr,-1);
|
||||||
|
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
|
//SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
|
||||||
DisplayErrorMessage(sErr);
|
DisplayErrorMessage(sErr);
|
||||||
|
|
||||||
@@ -535,18 +539,14 @@ void ClientInterface::waitUntilReady(Checksum* checksum)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
NetworkMessageType networkMessageType = getNextMessageType(true);
|
NetworkMessageType networkMessageType = getNextMessageType(true);
|
||||||
if(networkMessageType == nmtReady)
|
if(networkMessageType == nmtReady) {
|
||||||
{
|
if(receiveMessage(&networkMessageReady)) {
|
||||||
if(receiveMessage(&networkMessageReady))
|
|
||||||
{
|
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(networkMessageType == nmtInvalid)
|
else if(networkMessageType == nmtInvalid) {
|
||||||
{
|
if(chrono.getMillis() > readyWaitTimeout) {
|
||||||
if(chrono.getMillis() > readyWaitTimeout)
|
|
||||||
{
|
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
//throw runtime_error("Timeout waiting for server");
|
//throw runtime_error("Timeout waiting for server");
|
||||||
string sErr = "Timeout waiting for server";
|
string sErr = "Timeout waiting for server";
|
||||||
@@ -564,10 +564,8 @@ void ClientInterface::waitUntilReady(Checksum* checksum)
|
|||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
if(chrono.getMillis() / 1000 > lastMillisCheck) {
|
||||||
if(chrono.getMillis() / 1000 > lastMillisCheck)
|
|
||||||
{
|
|
||||||
lastMillisCheck = (chrono.getMillis() / 1000);
|
lastMillisCheck = (chrono.getMillis() / 1000);
|
||||||
|
|
||||||
char szBuf[1024]="";
|
char szBuf[1024]="";
|
||||||
@@ -576,8 +574,7 @@ void ClientInterface::waitUntilReady(Checksum* checksum)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
//throw runtime_error(string(__FILE__) + "::" + string(__FUNCTION__) + " Unexpected network message: " + intToStr(networkMessageType) );
|
//throw runtime_error(string(__FILE__) + "::" + string(__FUNCTION__) + " Unexpected network message: " + intToStr(networkMessageType) );
|
||||||
sendTextMessage("Unexpected network message: " + intToStr(networkMessageType),-1);
|
sendTextMessage("Unexpected network message: " + intToStr(networkMessageType),-1);
|
||||||
@@ -602,8 +599,7 @@ void ClientInterface::waitUntilReady(Checksum* checksum)
|
|||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
|
||||||
//check checksum
|
//check checksum
|
||||||
if(networkMessageReady.getChecksum() != checksum->getSum())
|
if(networkMessageReady.getChecksum() != checksum->getSum()) {
|
||||||
{
|
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
|
||||||
string sErr = "Checksum error, you don't have the same data as the server";
|
string sErr = "Checksum error, you don't have the same data as the server";
|
||||||
@@ -633,8 +629,7 @@ void ClientInterface::waitUntilReady(Checksum* checksum)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//delay the start a bit, so clients have more room to get messages
|
||||||
//delay the start a bit, so clients have nore room to get messages
|
|
||||||
sleep(GameConstants::networkExtraLatency);
|
sleep(GameConstants::networkExtraLatency);
|
||||||
|
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] END\n",__FILE__,__FUNCTION__);
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] END\n",__FILE__,__FUNCTION__);
|
||||||
@@ -657,11 +652,11 @@ void ClientInterface::waitForMessage()
|
|||||||
int waitLoopCount = 0;
|
int waitLoopCount = 0;
|
||||||
while(getNextMessageType(true) == nmtInvalid)
|
while(getNextMessageType(true) == nmtInvalid)
|
||||||
{
|
{
|
||||||
if(!isConnected())
|
if(isConnected() == false)
|
||||||
{
|
{
|
||||||
//throw runtime_error("Disconnected");
|
//throw runtime_error("Disconnected");
|
||||||
sendTextMessage("Disconnected",-1);
|
sendTextMessage("Server has Disconnected.",-1);
|
||||||
DisplayErrorMessage("Disconnected");
|
DisplayErrorMessage("Server has Disconnected.");
|
||||||
quit= true;
|
quit= true;
|
||||||
close();
|
close();
|
||||||
return;
|
return;
|
||||||
|
@@ -25,7 +25,7 @@ namespace Glest{ namespace Game{
|
|||||||
|
|
||||||
class GameSettings;
|
class GameSettings;
|
||||||
|
|
||||||
enum NetworkMessageType{
|
enum NetworkMessageType {
|
||||||
nmtInvalid,
|
nmtInvalid,
|
||||||
nmtIntro,
|
nmtIntro,
|
||||||
nmtPing,
|
nmtPing,
|
||||||
@@ -51,7 +51,7 @@ const int32 commandListHeaderSize = 6;
|
|||||||
// class NetworkMessage
|
// class NetworkMessage
|
||||||
// =====================================================
|
// =====================================================
|
||||||
|
|
||||||
class NetworkMessage{
|
class NetworkMessage {
|
||||||
public:
|
public:
|
||||||
virtual ~NetworkMessage(){}
|
virtual ~NetworkMessage(){}
|
||||||
virtual bool receive(Socket* socket)= 0;
|
virtual bool receive(Socket* socket)= 0;
|
||||||
|
@@ -280,6 +280,79 @@ void ServerInterface::updateKeyframe(int frameCount){
|
|||||||
SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] broadcastMessage took %d msecs, networkMessageCommandList.getCommandCount() = %d, frameCount = %d\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis(),networkMessageCommandList.getCommandCount(),frameCount);
|
SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] broadcastMessage took %d msecs, networkMessageCommandList.getCommandCount() = %d, frameCount = %d\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis(),networkMessageCommandList.getCommandCount(),frameCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ServerInterface::shouldDiscardNetworkMessage(NetworkMessageType networkMessageType,
|
||||||
|
ConnectionSlot* connectionSlot) {
|
||||||
|
bool discard = false;
|
||||||
|
if(connectionSlot != NULL) {
|
||||||
|
switch(networkMessageType) {
|
||||||
|
case nmtIntro:
|
||||||
|
{
|
||||||
|
discard = true;
|
||||||
|
NetworkMessageIntro msg = NetworkMessageIntro();
|
||||||
|
connectionSlot->receiveMessage(&msg);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case nmtLaunch:
|
||||||
|
{
|
||||||
|
discard = true;
|
||||||
|
NetworkMessageLaunch msg = NetworkMessageLaunch();
|
||||||
|
connectionSlot->receiveMessage(&msg);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case nmtText:
|
||||||
|
{
|
||||||
|
discard = true;
|
||||||
|
NetworkMessageText msg = NetworkMessageText();
|
||||||
|
connectionSlot->receiveMessage(&msg);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case nmtSynchNetworkGameData:
|
||||||
|
{
|
||||||
|
discard = true;
|
||||||
|
NetworkMessageSynchNetworkGameData msg = NetworkMessageSynchNetworkGameData();
|
||||||
|
connectionSlot->receiveMessage(&msg);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case nmtSynchNetworkGameDataStatus:
|
||||||
|
{
|
||||||
|
discard = true;
|
||||||
|
NetworkMessageSynchNetworkGameDataStatus msg = NetworkMessageSynchNetworkGameDataStatus();
|
||||||
|
connectionSlot->receiveMessage(&msg);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case nmtSynchNetworkGameDataFileCRCCheck:
|
||||||
|
{
|
||||||
|
discard = true;
|
||||||
|
NetworkMessageSynchNetworkGameDataFileCRCCheck msg = NetworkMessageSynchNetworkGameDataFileCRCCheck();
|
||||||
|
connectionSlot->receiveMessage(&msg);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case nmtSynchNetworkGameDataFileGet:
|
||||||
|
{
|
||||||
|
discard = true;
|
||||||
|
NetworkMessageSynchNetworkGameDataFileGet msg = NetworkMessageSynchNetworkGameDataFileGet();
|
||||||
|
connectionSlot->receiveMessage(&msg);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case nmtSwitchSetupRequest:
|
||||||
|
{
|
||||||
|
discard = true;
|
||||||
|
SwitchSetupRequest msg = SwitchSetupRequest();
|
||||||
|
connectionSlot->receiveMessage(&msg);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case nmtPlayerIndexMessage:
|
||||||
|
{
|
||||||
|
discard = true;
|
||||||
|
PlayerIndexMessage msg = PlayerIndexMessage(0);
|
||||||
|
connectionSlot->receiveMessage(&msg);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return discard;
|
||||||
|
}
|
||||||
|
|
||||||
void ServerInterface::waitUntilReady(Checksum* checksum){
|
void ServerInterface::waitUntilReady(Checksum* checksum){
|
||||||
|
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s] START\n",__FUNCTION__);
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s] START\n",__FUNCTION__);
|
||||||
@@ -293,44 +366,33 @@ void ServerInterface::waitUntilReady(Checksum* checksum){
|
|||||||
chrono.start();
|
chrono.start();
|
||||||
|
|
||||||
//wait until we get a ready message from all clients
|
//wait until we get a ready message from all clients
|
||||||
while(allReady == false)
|
while(allReady == false) {
|
||||||
{
|
|
||||||
vector<string> waitingForHosts;
|
vector<string> waitingForHosts;
|
||||||
allReady= true;
|
allReady= true;
|
||||||
for(int i= 0; i<GameConstants::maxPlayers; ++i)
|
for(int i= 0; i<GameConstants::maxPlayers; ++i) {
|
||||||
{
|
|
||||||
ConnectionSlot* connectionSlot= slots[i];
|
ConnectionSlot* connectionSlot= slots[i];
|
||||||
|
if(connectionSlot != NULL && connectionSlot->isConnected() == true) {
|
||||||
if(connectionSlot != NULL && connectionSlot->isConnected() == true)
|
if(connectionSlot->isReady() == false) {
|
||||||
{
|
|
||||||
if(connectionSlot->isReady() == false)
|
|
||||||
{
|
|
||||||
NetworkMessageType networkMessageType= connectionSlot->getNextMessageType(true);
|
NetworkMessageType networkMessageType= connectionSlot->getNextMessageType(true);
|
||||||
NetworkMessageReady networkMessageReady;
|
|
||||||
|
|
||||||
// consume old messages from the setup
|
// consume old messages from the lobby
|
||||||
while(networkMessageType == nmtSwitchSetupRequest)
|
bool discarded = shouldDiscardNetworkMessage(networkMessageType,connectionSlot);
|
||||||
{
|
if(discarded == false) {
|
||||||
SwitchSetupRequest switchSetupRequest;
|
NetworkMessageReady networkMessageReady;
|
||||||
connectionSlot->receiveMessage(&switchSetupRequest);
|
if(networkMessageType == nmtReady &&
|
||||||
networkMessageType= connectionSlot->getNextMessageType(true);
|
connectionSlot->receiveMessage(&networkMessageReady)) {
|
||||||
}
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s] networkMessageType==nmtReady\n",__FUNCTION__);
|
||||||
if(networkMessageType == nmtReady &&
|
|
||||||
connectionSlot->receiveMessage(&networkMessageReady))
|
|
||||||
{
|
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s] networkMessageType==nmtReady\n",__FUNCTION__);
|
|
||||||
|
|
||||||
connectionSlot->setReady();
|
connectionSlot->setReady();
|
||||||
|
}
|
||||||
|
else if(networkMessageType != nmtInvalid) {
|
||||||
|
//throw runtime_error("Unexpected network message: " + intToStr(networkMessageType));
|
||||||
|
string sErr = "Unexpected network message: " + intToStr(networkMessageType);
|
||||||
|
sendTextMessage(sErr,-1);
|
||||||
|
DisplayErrorMessage(sErr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if(networkMessageType != nmtInvalid)
|
|
||||||
{
|
|
||||||
//throw runtime_error("Unexpected network message: " + intToStr(networkMessageType));
|
|
||||||
string sErr = "Unexpected network message: " + intToStr(networkMessageType);
|
|
||||||
sendTextMessage(sErr,-1);
|
|
||||||
DisplayErrorMessage(sErr);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//waitingForHosts.push_back(connectionSlot->getHostName());
|
//waitingForHosts.push_back(connectionSlot->getHostName());
|
||||||
waitingForHosts.push_back(connectionSlot->getName());
|
waitingForHosts.push_back(connectionSlot->getName());
|
||||||
|
|
||||||
@@ -340,25 +402,19 @@ void ServerInterface::waitUntilReady(Checksum* checksum){
|
|||||||
}
|
}
|
||||||
|
|
||||||
//check for timeout
|
//check for timeout
|
||||||
if(allReady == false)
|
if(allReady == false) {
|
||||||
{
|
if(chrono.getMillis() > readyWaitTimeout) {
|
||||||
if(chrono.getMillis() > readyWaitTimeout)
|
|
||||||
{
|
|
||||||
//throw runtime_error("Timeout waiting for clients");
|
//throw runtime_error("Timeout waiting for clients");
|
||||||
string sErr = "Timeout waiting for clients.";
|
string sErr = "Timeout waiting for clients.";
|
||||||
sendTextMessage(sErr,-1);
|
sendTextMessage(sErr,-1);
|
||||||
DisplayErrorMessage(sErr);
|
DisplayErrorMessage(sErr);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
if(chrono.getMillis() % 1000 == 0) {
|
||||||
if(chrono.getMillis() % 1000 == 0)
|
|
||||||
{
|
|
||||||
string waitForHosts = "";
|
string waitForHosts = "";
|
||||||
for(int i = 0; i < waitingForHosts.size(); i++)
|
for(int i = 0; i < waitingForHosts.size(); i++) {
|
||||||
{
|
if(waitForHosts != "") {
|
||||||
if(waitForHosts != "")
|
|
||||||
{
|
|
||||||
waitForHosts += ", ";
|
waitForHosts += ", ";
|
||||||
}
|
}
|
||||||
waitForHosts += waitingForHosts[i];
|
waitForHosts += waitingForHosts[i];
|
||||||
@@ -372,20 +428,16 @@ void ServerInterface::waitUntilReady(Checksum* checksum){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// FOR TESTING ONLY - delay to see the client count up while waiting
|
// FOR TESTING ONLY - delay to see the client count up while waiting
|
||||||
//sleep(5000);
|
//sleep(5000);
|
||||||
|
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s] PART B (telling client we are ready!\n",__FUNCTION__);
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s] PART B (telling client we are ready!\n",__FUNCTION__);
|
||||||
|
|
||||||
//send ready message after, so clients start delayed
|
//send ready message after, so clients start delayed
|
||||||
for(int i= 0; i < GameConstants::maxPlayers; ++i)
|
for(int i= 0; i < GameConstants::maxPlayers; ++i) {
|
||||||
{
|
|
||||||
NetworkMessageReady networkMessageReady(checksum->getSum());
|
|
||||||
|
|
||||||
ConnectionSlot* connectionSlot= slots[i];
|
ConnectionSlot* connectionSlot= slots[i];
|
||||||
if(connectionSlot!=NULL)
|
if(connectionSlot != NULL && connectionSlot->isConnected() == true) {
|
||||||
{
|
NetworkMessageReady networkMessageReady(checksum->getSum());
|
||||||
connectionSlot->sendMessage(&networkMessageReady);
|
connectionSlot->sendMessage(&networkMessageReady);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -82,6 +82,7 @@ private:
|
|||||||
void broadcastMessage(const NetworkMessage* networkMessage, int excludeSlot= -1);
|
void broadcastMessage(const NetworkMessage* networkMessage, int excludeSlot= -1);
|
||||||
void updateListen();
|
void updateListen();
|
||||||
void broadcastMessageToConnectedClients(const NetworkMessage* networkMessage, int excludeSlot = -1);
|
void broadcastMessageToConnectedClients(const NetworkMessage* networkMessage, int excludeSlot = -1);
|
||||||
|
bool shouldDiscardNetworkMessage(NetworkMessageType networkMessageType,ConnectionSlot* connectionSlot);
|
||||||
};
|
};
|
||||||
|
|
||||||
}}//end namespace
|
}}//end namespace
|
||||||
|
@@ -143,6 +143,28 @@ void deleteMapValues(T beginIt, T endIt){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T, typename U>
|
||||||
|
class create_map
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
std::map<T, U> m_map;
|
||||||
|
public:
|
||||||
|
create_map(const T& key, const U& val)
|
||||||
|
{
|
||||||
|
m_map[key] = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
create_map<T, U>& operator()(const T& key, const U& val)
|
||||||
|
{
|
||||||
|
m_map[key] = val;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
operator std::map<T, U>()
|
||||||
|
{
|
||||||
|
return m_map;
|
||||||
|
}
|
||||||
|
};
|
||||||
}}//end namespace
|
}}//end namespace
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Reference in New Issue
Block a user