<commit_before>// Copyright (c) 2014 The Caroline authors. All right reserved.
// Use of this source file is governed by a MIT license that can be found in the
// License file
/// @author: Vladislav Krikunov <vlad.krikunoff@yandex.ru>

#include "core/serialization.h"

#include <string>
#include <utility>
#include <vector>

#include "base/stream.h"
#include "google/protobuf/message_lite.h"
#include "google/protobuf/io/coded_stream.h"
#include "google/protobuf/io/zero_copy_stream_impl_lite.h"

namespace bitdata {

namespace {

const char kOStreamConfigFieldName[] = "connection";
const char kIStreamConfigFieldName[] = "brain";
const char kCompressLevelConfigFieldName[] = "compression";
const int  kDefaultCompressLevel = 95;

} //namespace

bool GlobalMessage::SetOStream(const core::Config* settings) {
  const Json::Value* dictionary = settings->dictionary();
  if (!(dictionary && dictionary->isMember(kOStreamConfigFieldName))) {
    const Json::Value& address_node = (*dictionary)[kOStreamConfigFieldName];
    if(!address_node.isString()) {
      const std::string& ostream = address_node.asString();
      ostream_name_ = ostream;
      compress_level_ = kDefaultCompressLevel;
      if(dictionary->isMember(kCompressLevelConfigFieldName)) {
        const Json::Value compress_node = (*dictionary)[kCompressLevelConfigFieldName];
        if(compress_node.isInt())
          compress_level_ = compress_node.asInt();
      }
      ostream_ = base::Stream::Open(ostream_name_, base::Stream::kWrite);
      return true;
    }
  }
  return false;
}

bool GlobalMessage::SetIStream(const core::Config* settings) {
  const Json::Value* dictionary = settings->dictionary();
  if(dictionary && dictionary->isMember(kIStreamConfigFieldName)) {
    const Json::Value& address_node = (*dictionary)[kIStreamConfigFieldName];
    if (address_node.isString()) {
      const std::string istream = address_node.asString();
      istream_name_ = istream;
      istream_ = base::Stream::Open(istream_name_, base::Stream::kRead);
      return true;
    }
  }
  return false;
}

void GlobalMessage::MakeMessage(Message* message) {
  size_t size = message->ByteSize();
  int size_of_size = google::protobuf::io
                     ::CodedOutputStream::VarintSize32(size);
  std::unique_ptr<char[]>bit_message(new char[size + size_of_size]);
  google::protobuf::io::ArrayOutputStream stream_message(bit_message.get(),
                                                         size + size_of_size);
  google::protobuf::io::CodedOutputStream coded_message(&stream_message);
  coded_message.WriteVarint32(size);
  message->SerializeToCodedStream(&coded_message);
  ostream_->Write(bit_message.get(), size + size_of_size);
}

void GlobalMessage::GenDMap(const core::DepthMap& depth_map) {
  std::unique_ptr<Message> message(new Message());
  message->mutable_depth_map()->set_width(depth_map.width());
  message->mutable_depth_map()->set_height(depth_map.height());
  for (double depth : depth_map)
    message->mutable_depth_map()->add_data(depth);
  message->set_type(Message::DEPTH_MAP);
  this->MakeMessage(message.get());
}

void GlobalMessage::GenOptFlow(const core::OpticalFlow& optical_flow) {
  std::unique_ptr<Message>message(new Message);
  for (auto pair : optical_flow) {
    OpticalFlowItem* item = message->mutable_optical_flow()->add_item();
    item->mutable_left()->set_x(pair.first.x);
    item->mutable_left()->set_y(pair.first.y);
    item->mutable_right()->set_x(pair.second.x);
    item->mutable_right()->set_y(pair.second.y);
  }
  message->set_type(Message::OPTICAL_FLOW);
  this->MakeMessage(message.get());
}

void GlobalMessage::GenModel(const core::Scene3D& scene) {
  std::unique_ptr<Message>message(new Message());
  std::vector<cv::Point3d> vertexes;
  std::vector<core::Triangle> faces;
  core::SceneElement some_element;
  int vertex_base_index = 0;
  for (auto scene_element : scene) {
    for (auto vertex : scene_element->mesh()->vertexes()) {
      auto transformed_vertex = vertex;
      scene_element->Transform(&transformed_vertex, transformed_vertex);
      auto proto_vertex = message->mutable_model()->add_verticies();
      proto_vertex->set_x(vertex.x);
      proto_vertex->set_y(vertex.y);
      proto_vertex->set_z(vertex.z);
    }
    for (auto face : scene_element->mesh()->faces()) {
      auto proto_face = message->mutable_model()->add_faces();
      proto_face->set_point1(face.Point1() + vertex_base_index);
      proto_face->set_point2(face.Point2() + vertex_base_index);
      proto_face->set_point3(face.Point3() + vertex_base_index);
    }
    vertex_base_index += scene_element->mesh()->vertexes().size();
  }
  message->set_type(Message::MODEL);
  this->MakeMessage(message.get());
}

void GlobalMessage::GenPic(const std::vector<std::pair<cv::Mat,
            core::Position>>& frameset) {
  std::unique_ptr<Message>message(new Message());
  std::vector<uint8_t> left, right;
  std::vector<int> prop;
  prop.push_back(cv::IMWRITE_JPEG_QUALITY);
  prop.push_back(compress_level_);
  cv::imencode("*.jpeg", frameset[0].first, left, prop);
  cv::imencode("*.jpeg", frameset[1].first, right, prop);
  message->mutable_images()->mutable_left()->
      set_width(frameset[0].first.size().width);
  message->mutable_images()->mutable_left()->
      set_height(frameset[0].first.size().height);
  message->mutable_images()->mutable_right()->
      set_width(frameset[1].first.size().width);
  message->mutable_images()->mutable_right()->
      set_height(frameset[1].first.size().height);

  auto it = left.begin(), end = left.end();
  while (it != end) {
    message->mutable_images()->mutable_left()->add_data(*(it++));
  }
  it = right.begin(); end = right.end();
  while (it != end) {
    message->mutable_images()->mutable_right()->add_data(*(it++));
  }
  message->set_type(Message::IMAGES);
  this->MakeMessage(message.get());
}

void GlobalMessage::GenLog(const std::string& message) {
  std::unique_ptr<Message>proto_message(new Message());
  proto_message->mutable_log()->set_line(message);
  proto_message->set_type(Message::LOG);
  this->MakeMessage(proto_message.get());
}

void GlobalMessage::Observe(const std::string& message) {
  GenLog(message);
}

}  // namespace bitdata
<commit_msg>Protobuf image data type changed from int32 to bytes<commit_after>// Copyright (c) 2014 The Caroline authors. All right reserved.
// Use of this source file is governed by a MIT license that can be found in the
// License file
/// @author: Vladislav Krikunov <vlad.krikunoff@yandex.ru>

#include "core/serialization.h"

#include <string>
#include <utility>
#include <vector>

#include "base/stream.h"
#include "google/protobuf/message_lite.h"
#include "google/protobuf/io/coded_stream.h"
#include "google/protobuf/io/zero_copy_stream_impl_lite.h"

namespace bitdata {

namespace {

const char kOStreamConfigFieldName[] = "connection";
const char kIStreamConfigFieldName[] = "brain";
const char kCompressLevelConfigFieldName[] = "compression";
const int  kDefaultCompressLevel = 95;

} //namespace

bool GlobalMessage::SetOStream(const core::Config* settings) {
  const Json::Value* dictionary = settings->dictionary();
  if (!(dictionary && dictionary->isMember(kOStreamConfigFieldName))) {
    const Json::Value& address_node = (*dictionary)[kOStreamConfigFieldName];
    if(!address_node.isString()) {
      const std::string& ostream = address_node.asString();
      ostream_name_ = ostream;
      compress_level_ = kDefaultCompressLevel;
      if(dictionary->isMember(kCompressLevelConfigFieldName)) {
        const Json::Value compress_node = (*dictionary)[kCompressLevelConfigFieldName];
        if(compress_node.isInt())
          compress_level_ = compress_node.asInt();
      }
      ostream_ = base::Stream::Open(ostream_name_, base::Stream::kWrite);
      return true;
    }
  }
  return false;
}

bool GlobalMessage::SetIStream(const core::Config* settings) {
  const Json::Value* dictionary = settings->dictionary();
  if(dictionary && dictionary->isMember(kIStreamConfigFieldName)) {
    const Json::Value& address_node = (*dictionary)[kIStreamConfigFieldName];
    if (address_node.isString()) {
      const std::string istream = address_node.asString();
      istream_name_ = istream;
      istream_ = base::Stream::Open(istream_name_, base::Stream::kRead);
      return true;
    }
  }
  return false;
}

void GlobalMessage::MakeMessage(Message* message) {
  size_t size = message->ByteSize();
  int size_of_size = google::protobuf::io
                     ::CodedOutputStream::VarintSize32(size);
  std::unique_ptr<char[]>bit_message(new char[size + size_of_size]);
  google::protobuf::io::ArrayOutputStream stream_message(bit_message.get(),
                                                         size + size_of_size);
  google::protobuf::io::CodedOutputStream coded_message(&stream_message);
  coded_message.WriteVarint32(size);
  message->SerializeToCodedStream(&coded_message);
  ostream_->Write(bit_message.get(), size + size_of_size);
}

void GlobalMessage::GenDMap(const core::DepthMap& depth_map) {
  std::unique_ptr<Message> message(new Message());
  message->mutable_depth_map()->set_width(depth_map.width());
  message->mutable_depth_map()->set_height(depth_map.height());
  for (double depth : depth_map)
    message->mutable_depth_map()->add_data(depth);
  message->set_type(Message::DEPTH_MAP);
  this->MakeMessage(message.get());
}

void GlobalMessage::GenOptFlow(const core::OpticalFlow& optical_flow) {
  std::unique_ptr<Message>message(new Message);
  for (auto pair : optical_flow) {
    OpticalFlowItem* item = message->mutable_optical_flow()->add_item();
    item->mutable_left()->set_x(pair.first.x);
    item->mutable_left()->set_y(pair.first.y);
    item->mutable_right()->set_x(pair.second.x);
    item->mutable_right()->set_y(pair.second.y);
  }
  message->set_type(Message::OPTICAL_FLOW);
  this->MakeMessage(message.get());
}

void GlobalMessage::GenModel(const core::Scene3D& scene) {
  std::unique_ptr<Message>message(new Message());
  std::vector<cv::Point3d> vertexes;
  std::vector<core::Triangle> faces;
  core::SceneElement some_element;
  int vertex_base_index = 0;
  for (auto scene_element : scene) {
    for (auto vertex : scene_element->mesh()->vertexes()) {
      auto transformed_vertex = vertex;
      scene_element->Transform(&transformed_vertex, transformed_vertex);
      auto proto_vertex = message->mutable_model()->add_verticies();
      proto_vertex->set_x(vertex.x);
      proto_vertex->set_y(vertex.y);
      proto_vertex->set_z(vertex.z);
    }
    for (auto face : scene_element->mesh()->faces()) {
      auto proto_face = message->mutable_model()->add_faces();
      proto_face->set_point1(face.Point1() + vertex_base_index);
      proto_face->set_point2(face.Point2() + vertex_base_index);
      proto_face->set_point3(face.Point3() + vertex_base_index);
    }
    vertex_base_index += scene_element->mesh()->vertexes().size();
  }
  message->set_type(Message::MODEL);
  this->MakeMessage(message.get());
}

void GlobalMessage::GenPic(const std::vector<std::pair<cv::Mat,
            core::Position>>& frameset) {
  std::unique_ptr<Message>message(new Message());
  std::vector<uint8_t> left, right;
  std::vector<int> prop;
  prop.push_back(cv::IMWRITE_JPEG_QUALITY);
  prop.push_back(compress_level_);
  cv::imencode("*.jpeg", frameset[0].first, left, prop);
  cv::imencode("*.jpeg", frameset[1].first, right, prop);
  message->mutable_images()->mutable_left()->
      set_width(frameset[0].first.size().width);
  message->mutable_images()->mutable_left()->
      set_height(frameset[0].first.size().height);
  message->mutable_images()->mutable_right()->
      set_width(frameset[1].first.size().width);
  message->mutable_images()->mutable_right()->
      set_height(frameset[1].first.size().height);

  message->mutable_images()->mutable_left()->set_data(std::string(left.begin(), left.end()));
  message->mutable_images()->mutable_right()->set_data(std::string(right.begin(), right.end()));
  message->set_type(Message::IMAGES);
  this->MakeMessage(message.get());
}

void GlobalMessage::GenLog(const std::string& message) {
  std::unique_ptr<Message>proto_message(new Message());
  proto_message->mutable_log()->set_line(message);
  proto_message->set_type(Message::LOG);
  this->MakeMessage(proto_message.get());
}

void GlobalMessage::Observe(const std::string& message) {
  GenLog(message);
}

}  // namespace bitdata
<|endoftext|>


<commit_before>// -------------------------------------------------------------------------
//    @FileName             NFIClusterClientModule.hpp
//    @Author               LvSheng.Huang
//    @Date                 2015-01-4
//    @Module               NFIClusterClientModule
//
// -------------------------------------------------------------------------

#ifndef _NFI_CLUSTER_CLIENT_MODULE_H
#define _NFI_CLUSTER_CLIENT_MODULE_H

#include <iostream>
#include "NFILogicModule.h"
#include "NFINetModule.h"
#include "NFComm/NFCore/NFCConsistentHash.hpp"

enum ConnectDataState
{
	DISCONNECT,
	NORMAL,
	RECONNECT,

};
struct ConnectData
{
	ConnectData()
	{
		nGameID = 0;
		nPort = 0;
		strName = "";
		strIP = "";
		eServerType = NFST_NONE;
		eState = ConnectDataState::DISCONNECT;
		mfLastActionTime = 0;
	}

	int nGameID;
	NF_SERVER_TYPE eServerType;
	std::string strIP;
	int nPort;
	std::string strName;
	ConnectDataState eState;
	float mfLastActionTime;

	NF_SHARE_PTR<NFINetModule> mxNetModule;
};

class NFIClusterClientModule : public NFILogicModule
{
public:
    enum EConstDefine
    {
        EConstDefine_DefaultWeith = 500,
    };

public:

    void AddServer(const ConnectData& xInfo)
    {
        mxTempNetList.push_back(xInfo);
    }

	//,ʱ
    void SendByServerID(const int nServerID, const int nMsgID, const std::string& strData)
    {
        NF_SHARE_PTR<ConnectData> pServer = mxServerMap.GetElement(nServerID);
        if (pServer)
        {
            NF_SHARE_PTR<NFINetModule> pNetModule = pServer->mxNetModule;
            if (pNetModule.get())
            {
                pNetModule->SendMsgWithOutHead(nMsgID, strData, 0);
            }
        }
    }

	//,ʱ
	void SendToAllServer(const int nMsgID, const std::string& strData)
	{
		NF_SHARE_PTR<ConnectData> pServer = mxServerMap.First();
		while (pServer)
		{
			NF_SHARE_PTR<NFINetModule> pNetModule = pServer->mxNetModule;
			if (pNetModule.get())
			{
				pNetModule->SendMsgWithOutHead(nMsgID, strData, 0);
			}

			pServer = mxServerMap.Next();
		}
	}

	void SendToServerByPB(const int nServerID, const uint16_t nMsgID, google::protobuf::Message& xData, const int nSockIndex = 0, const NFGUID nPlayer = NFGUID(), const std::vector<NFGUID>* pClientIDList = NULL, bool bBroadcast = false)
	{
		NF_SHARE_PTR<ConnectData> pServer = mxServerMap.GetElement(nServerID);
		if (pServer)
		{
			NF_SHARE_PTR<NFINetModule> pNetModule = pServer->mxNetModule;
			if (pNetModule.get())
			{
				pNetModule->SendMsgPB(nMsgID, xData, nSockIndex, nPlayer, pClientIDList);
			}
		}
	}

    void SendByServerID(const int nServerID, const int nSockIndex, const int nMsgID, const char* msg, const uint32_t nLen)
    {
        NF_SHARE_PTR<ConnectData> pServer = mxServerMap.GetElement(nServerID);
        if (pServer)
        {
            NF_SHARE_PTR<NFINetModule> pNetModule = pServer->mxNetModule;
            if (pNetModule.get())
            {
                pNetModule->GetNet()->SendMsgWithOutHead(nMsgID, msg, nLen, 0);
            }
        }
    }

	void SendToAllServerByPB(const uint16_t nMsgID, google::protobuf::Message& xData, const NFGUID nPlayer = NFGUID(), const std::vector<NFGUID>* pClientIDList = NULL)
	{
		NF_SHARE_PTR<ConnectData> pServer = mxServerMap.First();
		while (pServer)
		{
			NF_SHARE_PTR<NFINetModule> pNetModule = pServer->mxNetModule;
			if (pNetModule.get())
			{
				pNetModule->SendMsgPB(nMsgID, xData, 0, nPlayer, pClientIDList);
			}

			pServer = mxServerMap.Next();
		}

	}

    void SendBySuit(const int& nHashKey, const int nMsgID, const std::string& strData)
    {
        if (mxConsistentHash.Size() <= 0)
        {
            return;
        }

        NFCMachineNode xNode;
        if (!GetServerMachineData(boost::lexical_cast<std::string> (nHashKey), xNode))
        {
            return ;
        }

        SendByServerID(nMsgID, xNode.nMachineID, strData);
    }

    void SendBySuit(const int& nHashKey, const int nSockIndex, const int nMsgID, const char* msg, const uint32_t nLen)
    {
        if (mxConsistentHash.Size() <= 0)
        {
            return;
        }

        NFCMachineNode xNode;
        if (!GetServerMachineData(boost::lexical_cast<std::string>(nHashKey), xNode))
        {
            return ;
        }

        SendByServerID(xNode.nMachineID, nSockIndex, nMsgID, msg, nLen);
    }

	void SendSuitByPB(const int& nHashKey, const uint16_t nMsgID, google::protobuf::Message& xData, const int nSockIndex = 0, const NFGUID nPlayer = NFGUID(), const std::vector<NFGUID>* pClientIDList = NULL)
	{
		if (mxConsistentHash.Size() <= 0)
		{
			return;
		}

		NFCMachineNode xNode;
		if (!GetServerMachineData(boost::lexical_cast<std::string> (nHashKey), xNode))
		{
			return ;
		}

		SendToServerByPB(xNode.nMachineID, nMsgID, xData, nSockIndex, nPlayer, pClientIDList);
	}

	void SendSuitByPB(const uint16_t nMsgID, google::protobuf::Message& xData, const int nSockIndex = 0, const NFGUID nPlayer = NFGUID(), const std::vector<NFGUID>* pClientIDList = NULL)
	{
		if (mxConsistentHash.Size() <= 0)
		{
			return;
		}

		const int nHashKey = 0;

		SendSuitByPB(nHashKey, nMsgID, xData, nSockIndex, nPlayer, pClientIDList);
	}

	NF_SHARE_PTR<ConnectData> GetServerNetInfo(const int nServerID)
	{
		return mxServerMap.GetElement(nServerID);
	}

	NFMapEx<int, ConnectData>& GetServerList()
	{
		return mxServerMap;
	}

protected:
	template<typename BaseType>
	void Bind(BaseType* pBaseType, void (BaseType::*handleRecieve)(const int nSockIndex, const int nMsgID, const char* msg, const uint32_t nLen), void (BaseType::*handleEvent)(const int, const NF_NET_EVENT, NFINet*))
	{
		mRecvCB = std::bind(handleRecieve, pBaseType, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4);
		mEventCB = std::bind(handleEvent, pBaseType, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
	}

    bool Execute(const float fLastFrametime, const float fStartedTime)
    {
        ConnectData* pServerData = mxServerMap.FirstNude();
        while (pServerData)
        {
			switch (pServerData->eState)
			{
			case ConnectDataState::DISCONNECT:
				{
					if (NULL != pServerData->mxNetModule)
					{
						pServerData->mxNetModule = nullptr;
						pServerData->eState = ConnectDataState::RECONNECT;
						pServerData->mfLastActionTime = 0.0f;
					}
				}
				break;
			case ConnectDataState::NORMAL:
				{
					if (pServerData->mxNetModule)
					{
						pServerData->mxNetModule->Execute(fLastFrametime, fStartedTime);

						KeepState(pServerData, fLastFrametime, fStartedTime);
					}
				}
				break;
			case ConnectDataState::RECONNECT:
				{
					//ʱ
					if (pServerData->mfLastActionTime < 30.0f)
					{
						pServerData->mfLastActionTime += fLastFrametime;
						break;
					}

					pServerData->mfLastActionTime = 0.0f;
					pServerData->eState = ConnectDataState::NORMAL;

					pServerData->mxNetModule->Initialization(this, &NFIClusterClientModule::OnRecivePack, &NFIClusterClientModule::OnSocketEvent, pServerData->strIP.c_str(), pServerData->nPort);
				}
				break;
			default:
				break;
			}

            pServerData = mxServerMap.NextNude();
        }

        ProcessAddNetConnect();

        return true;
    }

	NF_SHARE_PTR<ConnectData> GetServerNetInfo(const NFINet* pNet)
	{
		int nServerID = 0;
		for (NF_SHARE_PTR<ConnectData> pData = mxServerMap.First(nServerID); pData != NULL; pData = mxServerMap.Next(nServerID))
		{
			if (pData->mxNetModule.get() && pNet == pData->mxNetModule->GetNet())
			{
				return pData;
			}
		}

		return NF_SHARE_PTR<ConnectData> (NULL);
	}

	virtual void KeepReport(ConnectData* pServerData){};
	virtual void LogServerInfo(const std::string& strServerInfo){};

private:
	virtual void LogServerInfo()
	{
		LogServerInfo("This is a client, begin to Printf Server Info----------------------------------");

		ConnectData* pServerData = mxServerMap.FirstNude();
		while (pServerData)
		{
			std::ostringstream stream;
			stream << "Type: " << pServerData->eServerType << " ProxyServer ID: " << pServerData->nGameID << " State: " <<  pServerData->eState << " IP: " << pServerData->strIP << " Port: " << pServerData->nPort;

			LogServerInfo(stream.str());

			pServerData = mxServerMap.NextNude();
		}

		LogServerInfo("This is a client, end to Printf Server Info----------------------------------");
	};

	void KeepState(ConnectData* pServerData, const float fLastFrametime, const float fStartedTime)
	{
		if (pServerData->mfLastActionTime < 10.0f)
		{
			pServerData->mfLastActionTime += fLastFrametime;
			return;
		}

		pServerData->mfLastActionTime = 0.0f;

		KeepReport(pServerData);
		LogServerInfo();
	}

	void OnSocketEvent(const int fd, const NF_NET_EVENT eEvent, NFINet* pNet)
	{
		if (eEvent & BEV_EVENT_CONNECTED)
		{
			OnConnected(fd, pNet);
		}
		else
		{
			OnDisConnected(fd, pNet);
		}

		if (mEventCB)
		{
			mEventCB(fd, eEvent, pNet);
		}
	}

	void OnRecivePack(const int nSockIndex, const int nMsgID, const char* msg, const uint32_t nLen)
	{
		if (mRecvCB)
		{
			mRecvCB(nSockIndex, nMsgID, msg, nLen);
		}

	}

    int OnConnected(const int fd, NFINet* pNet)
    {
        NF_SHARE_PTR<ConnectData> pServerInfo = GetServerNetInfo(pNet);
        if (pServerInfo.get())
        {
            AddServerWeightData(pServerInfo);
            pServerInfo->eState = ConnectDataState::NORMAL;
        }

        return 0;
    }

    int OnDisConnected(const int fd, NFINet* pNet)
    {
        NF_SHARE_PTR<ConnectData> pServerInfo = GetServerNetInfo(pNet);
        if (pServerInfo.get())
        {
            RemoveServerWeightData(pServerInfo);
            pServerInfo->eState = ConnectDataState::DISCONNECT;
        }

        return 0;
    }

    void ProcessAddNetConnect()
    {
        std::list<ConnectData>::iterator it = mxTempNetList.begin();
        for (; it != mxTempNetList.end(); ++it)
        {
            const ConnectData& xInfo = *it;
            NF_SHARE_PTR<ConnectData> xServerData = mxServerMap.GetElement(xInfo.nGameID);
            if (nullptr == xServerData)
            {
				//·
				xServerData = NF_SHARE_PTR<ConnectData>(NF_NEW ConnectData());

				xServerData->nGameID = xInfo.nGameID;
				xServerData->eServerType = xInfo.eServerType;
				xServerData->strIP = xInfo.strIP;
				xServerData->strName = xInfo.strName;
				xServerData->eState = ConnectDataState::NORMAL;
				xServerData->nPort = xInfo.nPort;

				xServerData->mxNetModule = NF_SHARE_PTR<NFINetModule>(NF_NEW NFINetModule());
				xServerData->mxNetModule->Initialization(this, &NFIClusterClientModule::OnRecivePack, &NFIClusterClientModule::OnSocketEvent, xServerData->strIP.c_str(), xServerData->nPort);

				mxServerMap.AddElement(xInfo.nGameID, xServerData);
            }
        }

        mxTempNetList.clear();
    }

    bool GetServerMachineData(const std::string& strServerID, NFCMachineNode& xMachineData)
    {
        boost::crc_32_type ret;
        ret.process_bytes(strServerID.c_str(), strServerID.length());
        uint32_t nCRC32 = ret.checksum();

        if (mxConsistentHash.GetSuitNode(nCRC32, xMachineData))
        {
            return true;
        }

        return false;
    }

    void AddServerWeightData(NF_SHARE_PTR<ConnectData> xInfo)
    {
        //Ȩشڵ
        for (int j = 0; j < EConstDefine_DefaultWeith; ++j)
        {
            NFCMachineNode vNode(j);

            vNode.nMachineID = xInfo->nGameID;
            vNode.strIP = xInfo->strIP;
            vNode.nPort = xInfo->nPort;
            vNode.nWeight = EConstDefine_DefaultWeith;
            mxConsistentHash.Insert(vNode);
        }
    }

    void RemoveServerWeightData(NF_SHARE_PTR<ConnectData> xInfo)
    {
        for (int j = 0; j < EConstDefine_DefaultWeith; ++j)
        {
            NFCMachineNode vNode(j);

            vNode.nMachineID = xInfo->nGameID;
            vNode.strIP = xInfo->strIP;
            vNode.nPort = xInfo->nPort;
            vNode.nWeight = EConstDefine_DefaultWeith;
            mxConsistentHash.Erase(vNode);
        }
    }

private:
	NET_RECIEVE_FUNCTOR mRecvCB;
	NET_EVENT_FUNCTOR mEventCB;

	NFMapEx<int, ConnectData> mxServerMap;
	NFCConsistentHash mxConsistentHash;

    std::list<ConnectData> mxTempNetList;
};

#endif<commit_msg>modify a bug of cluster client module<commit_after>// -------------------------------------------------------------------------
//    @FileName             NFIClusterClientModule.hpp
//    @Author               LvSheng.Huang
//    @Date                 2015-01-4
//    @Module               NFIClusterClientModule
//
// -------------------------------------------------------------------------

#ifndef _NFI_CLUSTER_CLIENT_MODULE_H
#define _NFI_CLUSTER_CLIENT_MODULE_H

#include <iostream>
#include "NFILogicModule.h"
#include "NFINetModule.h"
#include "NFComm/NFCore/NFCConsistentHash.hpp"

enum ConnectDataState
{
	DISCONNECT,
	NORMAL,
	RECONNECT,

};
struct ConnectData
{
	ConnectData()
	{
		nGameID = 0;
		nPort = 0;
		strName = "";
		strIP = "";
		eServerType = NFST_NONE;
		eState = ConnectDataState::DISCONNECT;
		mfLastActionTime = 0;
	}

	int nGameID;
	NF_SERVER_TYPE eServerType;
	std::string strIP;
	int nPort;
	std::string strName;
	ConnectDataState eState;
	float mfLastActionTime;

	NF_SHARE_PTR<NFINetModule> mxNetModule;
};

class NFIClusterClientModule : public NFILogicModule
{
public:
    enum EConstDefine
    {
        EConstDefine_DefaultWeith = 500,
    };

public:

    void AddServer(const ConnectData& xInfo)
    {
        mxTempNetList.push_back(xInfo);
    }

	//,ʱ
    void SendByServerID(const int nServerID, const int nMsgID, const std::string& strData)
    {
        NF_SHARE_PTR<ConnectData> pServer = mxServerMap.GetElement(nServerID);
        if (pServer)
        {
            NF_SHARE_PTR<NFINetModule> pNetModule = pServer->mxNetModule;
            if (pNetModule.get())
            {
                pNetModule->SendMsgWithOutHead(nMsgID, strData, 0);
            }
        }
    }

	//,ʱ
	void SendToAllServer(const int nMsgID, const std::string& strData)
	{
		NF_SHARE_PTR<ConnectData> pServer = mxServerMap.First();
		while (pServer)
		{
			NF_SHARE_PTR<NFINetModule> pNetModule = pServer->mxNetModule;
			if (pNetModule.get())
			{
				pNetModule->SendMsgWithOutHead(nMsgID, strData, 0);
			}

			pServer = mxServerMap.Next();
		}
	}

	void SendToServerByPB(const int nServerID, const uint16_t nMsgID, google::protobuf::Message& xData, const int nSockIndex = 0, const NFGUID nPlayer = NFGUID(), const std::vector<NFGUID>* pClientIDList = NULL, bool bBroadcast = false)
	{
		NF_SHARE_PTR<ConnectData> pServer = mxServerMap.GetElement(nServerID);
		if (pServer)
		{
			NF_SHARE_PTR<NFINetModule> pNetModule = pServer->mxNetModule;
			if (pNetModule.get())
			{
				pNetModule->SendMsgPB(nMsgID, xData, nSockIndex, nPlayer, pClientIDList);
			}
		}
	}

    void SendByServerID(const int nServerID, const int nSockIndex, const int nMsgID, const char* msg, const uint32_t nLen)
    {
        NF_SHARE_PTR<ConnectData> pServer = mxServerMap.GetElement(nServerID);
        if (pServer)
        {
            NF_SHARE_PTR<NFINetModule> pNetModule = pServer->mxNetModule;
            if (pNetModule.get())
            {
                pNetModule->GetNet()->SendMsgWithOutHead(nMsgID, msg, nLen, 0);
            }
        }
    }

	void SendToAllServerByPB(const uint16_t nMsgID, google::protobuf::Message& xData, const NFGUID nPlayer = NFGUID(), const std::vector<NFGUID>* pClientIDList = NULL)
	{
		NF_SHARE_PTR<ConnectData> pServer = mxServerMap.First();
		while (pServer)
		{
			NF_SHARE_PTR<NFINetModule> pNetModule = pServer->mxNetModule;
			if (pNetModule.get())
			{
				pNetModule->SendMsgPB(nMsgID, xData, 0, nPlayer, pClientIDList);
			}

			pServer = mxServerMap.Next();
		}

	}

    void SendBySuit(const int& nHashKey, const int nMsgID, const std::string& strData)
    {
        if (mxConsistentHash.Size() <= 0)
        {
            return;
        }

        NFCMachineNode xNode;
        if (!GetServerMachineData(boost::lexical_cast<std::string> (nHashKey), xNode))
        {
            return ;
        }

        SendByServerID(nMsgID, xNode.nMachineID, strData);
    }

    void SendBySuit(const int& nHashKey, const int nSockIndex, const int nMsgID, const char* msg, const uint32_t nLen)
    {
        if (mxConsistentHash.Size() <= 0)
        {
            return;
        }

        NFCMachineNode xNode;
        if (!GetServerMachineData(boost::lexical_cast<std::string>(nHashKey), xNode))
        {
            return ;
        }

        SendByServerID(xNode.nMachineID, nSockIndex, nMsgID, msg, nLen);
    }

	void SendSuitByPB(const int& nHashKey, const uint16_t nMsgID, google::protobuf::Message& xData, const int nSockIndex = 0, const NFGUID nPlayer = NFGUID(), const std::vector<NFGUID>* pClientIDList = NULL)
	{
		if (mxConsistentHash.Size() <= 0)
		{
			return;
		}

		NFCMachineNode xNode;
		if (!GetServerMachineData(boost::lexical_cast<std::string> (nHashKey), xNode))
		{
			return ;
		}

		SendToServerByPB(xNode.nMachineID, nMsgID, xData, nSockIndex, nPlayer, pClientIDList);
	}

	void SendSuitByPB(const uint16_t nMsgID, google::protobuf::Message& xData, const int nSockIndex = 0, const NFGUID nPlayer = NFGUID(), const std::vector<NFGUID>* pClientIDList = NULL)
	{
		if (mxConsistentHash.Size() <= 0)
		{
			return;
		}

		const int nHashKey = 0;

		SendSuitByPB(nHashKey, nMsgID, xData, nSockIndex, nPlayer, pClientIDList);
	}

	NF_SHARE_PTR<ConnectData> GetServerNetInfo(const int nServerID)
	{
		return mxServerMap.GetElement(nServerID);
	}

	NFMapEx<int, ConnectData>& GetServerList()
	{
		return mxServerMap;
	}

protected:
	template<typename BaseType>
	void Bind(BaseType* pBaseType, void (BaseType::*handleRecieve)(const int nSockIndex, const int nMsgID, const char* msg, const uint32_t nLen), void (BaseType::*handleEvent)(const int, const NF_NET_EVENT, NFINet*))
	{
		mRecvCB = std::bind(handleRecieve, pBaseType, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4);
		mEventCB = std::bind(handleEvent, pBaseType, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
	}

    bool Execute(const float fLastFrametime, const float fStartedTime)
    {
        ConnectData* pServerData = mxServerMap.FirstNude();
        while (pServerData)
        {
			switch (pServerData->eState)
			{
			case ConnectDataState::DISCONNECT:
				{
					if (NULL != pServerData->mxNetModule)
					{
						pServerData->mxNetModule = nullptr;
						pServerData->eState = ConnectDataState::RECONNECT;
						pServerData->mfLastActionTime = 0.0f;
					}
				}
				break;
			case ConnectDataState::NORMAL:
				{
					if (pServerData->mxNetModule)
					{
						pServerData->mxNetModule->Execute(fLastFrametime, fStartedTime);

						KeepState(pServerData, fLastFrametime, fStartedTime);
					}
				}
				break;
			case ConnectDataState::RECONNECT:
				{
					//ʱ
					if (pServerData->mfLastActionTime < 30.0f)
					{
						pServerData->mfLastActionTime += fLastFrametime;
						break;
					}

                    if (nullptr != pServerData->mxNetModule)
                    {
                        pServerData->mxNetModule = nullptr;
                    }

					pServerData->mfLastActionTime = 0.0f;
					pServerData->eState = ConnectDataState::NORMAL;
                    pServerData->mxNetModule = NF_SHARE_PTR<NFINetModule> (NF_NEW NFINetModule());
					pServerData->mxNetModule->Initialization(this, &NFIClusterClientModule::OnRecivePack, &NFIClusterClientModule::OnSocketEvent, pServerData->strIP.c_str(), pServerData->nPort);
				}
				break;
			default:
				break;
			}

            pServerData = mxServerMap.NextNude();
        }

        ProcessAddNetConnect();

        return true;
    }

	NF_SHARE_PTR<ConnectData> GetServerNetInfo(const NFINet* pNet)
	{
		int nServerID = 0;
		for (NF_SHARE_PTR<ConnectData> pData = mxServerMap.First(nServerID); pData != NULL; pData = mxServerMap.Next(nServerID))
		{
			if (pData->mxNetModule.get() && pNet == pData->mxNetModule->GetNet())
			{
				return pData;
			}
		}

		return NF_SHARE_PTR<ConnectData> (NULL);
	}

	virtual void KeepReport(ConnectData* pServerData){};
	virtual void LogServerInfo(const std::string& strServerInfo){};

private:
	virtual void LogServerInfo()
	{
		LogServerInfo("This is a client, begin to Printf Server Info----------------------------------");

		ConnectData* pServerData = mxServerMap.FirstNude();
		while (pServerData)
		{
			std::ostringstream stream;
			stream << "Type: " << pServerData->eServerType << " ProxyServer ID: " << pServerData->nGameID << " State: " <<  pServerData->eState << " IP: " << pServerData->strIP << " Port: " << pServerData->nPort;

			LogServerInfo(stream.str());

			pServerData = mxServerMap.NextNude();
		}

		LogServerInfo("This is a client, end to Printf Server Info----------------------------------");
	};

	void KeepState(ConnectData* pServerData, const float fLastFrametime, const float fStartedTime)
	{
		if (pServerData->mfLastActionTime < 10.0f)
		{
			pServerData->mfLastActionTime += fLastFrametime;
			return;
		}

		pServerData->mfLastActionTime = 0.0f;

		KeepReport(pServerData);
		LogServerInfo();
	}

	void OnSocketEvent(const int fd, const NF_NET_EVENT eEvent, NFINet* pNet)
	{
		if (eEvent & BEV_EVENT_CONNECTED)
		{
			OnConnected(fd, pNet);
		}
		else
		{
			OnDisConnected(fd, pNet);
		}

		if (mEventCB)
		{
			mEventCB(fd, eEvent, pNet);
		}
	}

	void OnRecivePack(const int nSockIndex, const int nMsgID, const char* msg, const uint32_t nLen)
	{
		if (mRecvCB)
		{
			mRecvCB(nSockIndex, nMsgID, msg, nLen);
		}

	}

    int OnConnected(const int fd, NFINet* pNet)
    {
        NF_SHARE_PTR<ConnectData> pServerInfo = GetServerNetInfo(pNet);
        if (pServerInfo.get())
        {
            AddServerWeightData(pServerInfo);
            pServerInfo->eState = ConnectDataState::NORMAL;
        }

        return 0;
    }

    int OnDisConnected(const int fd, NFINet* pNet)
    {
        NF_SHARE_PTR<ConnectData> pServerInfo = GetServerNetInfo(pNet);
        if (pServerInfo.get())
        {
            RemoveServerWeightData(pServerInfo);
            pServerInfo->eState = ConnectDataState::DISCONNECT;
        }

        return 0;
    }

    void ProcessAddNetConnect()
    {
        std::list<ConnectData>::iterator it = mxTempNetList.begin();
        for (; it != mxTempNetList.end(); ++it)
        {
            const ConnectData& xInfo = *it;
            NF_SHARE_PTR<ConnectData> xServerData = mxServerMap.GetElement(xInfo.nGameID);
            if (nullptr == xServerData)
            {
				//·
				xServerData = NF_SHARE_PTR<ConnectData>(NF_NEW ConnectData());

				xServerData->nGameID = xInfo.nGameID;
				xServerData->eServerType = xInfo.eServerType;
				xServerData->strIP = xInfo.strIP;
				xServerData->strName = xInfo.strName;
				xServerData->eState = ConnectDataState::NORMAL;
				xServerData->nPort = xInfo.nPort;

				xServerData->mxNetModule = NF_SHARE_PTR<NFINetModule>(NF_NEW NFINetModule());
				xServerData->mxNetModule->Initialization(this, &NFIClusterClientModule::OnRecivePack, &NFIClusterClientModule::OnSocketEvent, xServerData->strIP.c_str(), xServerData->nPort);

				mxServerMap.AddElement(xInfo.nGameID, xServerData);
            }
        }

        mxTempNetList.clear();
    }

    bool GetServerMachineData(const std::string& strServerID, NFCMachineNode& xMachineData)
    {
        boost::crc_32_type ret;
        ret.process_bytes(strServerID.c_str(), strServerID.length());
        uint32_t nCRC32 = ret.checksum();

        if (mxConsistentHash.GetSuitNode(nCRC32, xMachineData))
        {
            return true;
        }

        return false;
    }

    void AddServerWeightData(NF_SHARE_PTR<ConnectData> xInfo)
    {
        //Ȩشڵ
        for (int j = 0; j < EConstDefine_DefaultWeith; ++j)
        {
            NFCMachineNode vNode(j);

            vNode.nMachineID = xInfo->nGameID;
            vNode.strIP = xInfo->strIP;
            vNode.nPort = xInfo->nPort;
            vNode.nWeight = EConstDefine_DefaultWeith;
            mxConsistentHash.Insert(vNode);
        }
    }

    void RemoveServerWeightData(NF_SHARE_PTR<ConnectData> xInfo)
    {
        for (int j = 0; j < EConstDefine_DefaultWeith; ++j)
        {
            NFCMachineNode vNode(j);

            vNode.nMachineID = xInfo->nGameID;
            vNode.strIP = xInfo->strIP;
            vNode.nPort = xInfo->nPort;
            vNode.nWeight = EConstDefine_DefaultWeith;
            mxConsistentHash.Erase(vNode);
        }
    }

private:
	NET_RECIEVE_FUNCTOR mRecvCB;
	NET_EVENT_FUNCTOR mEventCB;

	NFMapEx<int, ConnectData> mxServerMap;
	NFCConsistentHash mxConsistentHash;

    std::list<ConnectData> mxTempNetList;
};

#endif<|endoftext|>


<commit_before>/* -------------------------------------------------------------------------- *
 *                         OpenSim:  CustomJoint.cpp                          *
 * -------------------------------------------------------------------------- *
 * The OpenSim API is a toolkit for musculoskeletal modeling and simulation.  *
 * See http://opensim.stanford.edu and the NOTICE file for more information.  *
 * OpenSim is developed at Stanford University and supported by the US        *
 * National Institutes of Health (U54 GM072970, R24 HD065690) and by DARPA    *
 * through the Warrior Web program.                                           *
 *                                                                            *
 * Copyright (c) 2005-2016 Stanford University and the Authors                *
 * Author(s): Frank C. Anderson, Peter Loan, Ajay Seth                        *
 *                                                                            *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may    *
 * not use this file except in compliance with the License. You may obtain a  *
 * copy of the License at http://www.apache.org/licenses/LICENSE-2.0.         *
 *                                                                            *
 * Unless required by applicable law or agreed to in writing, software        *
 * distributed under the License is distributed on an "AS IS" BASIS,          *
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   *
 * See the License for the specific language governing permissions and        *
 * limitations under the License.                                             *
 * -------------------------------------------------------------------------- */

//=============================================================================
// INCLUDES
//=============================================================================
#include "CustomJoint.h"
#include "SpatialTransform.h"
#include <OpenSim/Simulation/Model/Model.h>
#include <OpenSim/Common/Constant.h>
#include <OpenSim/Common/LinearFunction.h>
#include "simbody/internal/MobilizedBody_FunctionBased.h"

//=============================================================================
// STATICS
//=============================================================================
using namespace std;
using namespace SimTK;
using namespace OpenSim;

//=============================================================================
// CONSTRUCTOR(S) AND DESTRUCTOR
//=============================================================================
//_____________________________________________________________________________
/* Default Constructor */
CustomJoint::CustomJoint()
{
    constructProperties();
}

/**
 * Constructor with specified SpatialTransform.
 */
CustomJoint::CustomJoint(const std::string &name,
                         const PhysicalFrame& parent,
                         const PhysicalFrame& child,
                         SpatialTransform& spatialTransform,
                         bool reverse) :
                         Super(name, parent, child, reverse)
{
    constructProperties();
    set_SpatialTransform(spatialTransform);
}

CustomJoint::CustomJoint(const std::string& name,
    const PhysicalFrame& parent,
    const SimTK::Vec3& locationInParent,
    const SimTK::Vec3& orientationInParent,
    const PhysicalFrame& child,
    const SimTK::Vec3& locationInChild,
    const SimTK::Vec3& orientationInChild,
    SpatialTransform& spatialTransform,
    bool reverse) :
        Super(name, parent, locationInParent, orientationInParent,
            child, locationInChild, orientationInChild, reverse)
{
    constructProperties();
    set_SpatialTransform(spatialTransform);
}

//_____________________________________________________________________________
/**
 * Connect properties to local pointers.
 */
void CustomJoint::constructProperties()
{
    setAuthors("Frank C. Anderson, Ajay Seth");
    constructProperty_SpatialTransform(SpatialTransform());
}

/*
 * Perform some set up functions that happen after the
 * object has been deserialized or copied.
 */
void CustomJoint::extendFinalizeFromProperties()
{
    Super::extendFinalizeFromProperties();

    //CustomJoint can only construct the coordinates once SpatialTransform is specified
    constructCoordinates();

    // Axes should be independent otherwise Simbody throws an exception in extendAddToSystem
    double tol = 1e-5;
    // Verify that none of the rotation axes are collinear
    const std::vector<SimTK::Vec3> axes = getSpatialTransform().getAxes();
    for (int startIndex = 0; startIndex <= 3; startIndex += 3) {
        if (((axes[startIndex + 0] % axes[startIndex + 1]).norm() < tol) ||
            ((axes[startIndex + 0] % axes[startIndex + 2]).norm() < tol) ||
            ((axes[startIndex + 1] % axes[startIndex + 2]).norm() < tol)) {
            throw(Exception("CustomJoint '" + getName() +
                "' has collinear axes and are not well-defined."
                " Please fix and retry loading."));
        }
    }
}

void CustomJoint::extendConnectToModel(Model& aModel)
{
    Super::extendConnectToModel(aModel);
    // SpatialTransform "connect" methods are poorly named. This
    // establishing the SpatialTransform and its Transform axes as
    // sub objects (not updated to Components) of the CustomJoint and this
    // should be done here.
    /* Set up spatial transform for this custom joint. */
    updSpatialTransform().connectToJoint(*this);
}

//=============================================================================
// GET AND SET
//=============================================================================
// SCALING
//=============================================================================
//_____________________________________________________________________________
/**
 * Scale a joint based on XYZ scale factors for the bodies.
 *
 * @param aScaleSet Set of XYZ scale factors for the bodies.
 * @todo Need to scale transforms appropriately, given an arbitrary axis.
 */
void CustomJoint::scale(const ScaleSet& aScaleSet)
{
    Vec3 scaleFactors(1.0);

    // Joint knows how to scale locations of the joint in parent and on the body
    Super::scale(aScaleSet);

    // SCALING TO DO WITH THE PARENT BODY -----
    // Joint kinematics are scaled by the scale factors for the
    // parent body, so get those body's factors
    const string& parentName = getParentFrame().getName();
    for (int i=0; i<aScaleSet.getSize(); i++) {
        Scale& scale = aScaleSet.get(i);
        if (scale.getSegmentName()==parentName) {
            scale.getScaleFactors(scaleFactors);
            break;
        }
    }

    updSpatialTransform().scale(scaleFactors);
}

void CustomJoint::constructCoordinates()
{
    const SpatialTransform& spatialTransform = getSpatialTransform();
    OpenSim::Array<std::string> coordinateNames
        = spatialTransform.getCoordinateNames();

    // Check how many coordinates are required
    int ncoords = coordinateNames.getSize();

    for (int i = 0; i < ncoords; ++i){
        std::string coordName = spatialTransform.getCoordinateNames()[i];
        // Locate the coordinate in the set if it has already been defined (e.g. in XML)
        int coordIndex = getProperty_coordinates().findIndexForName(coordName);
        if (coordIndex < 0) {
            coordIndex = constructCoordinate(Coordinate::MotionType::Undefined,
                                             i);
        }
        Coordinate& coord = upd_coordinates(coordIndex);
        coord.setName(coordName);

        // Determine if the MotionType of the Coordinate based
        // on which TransformAxis it operates upon: 0-2 are Rotational
        // and 3-5 are Translational. Coordinates appearing
        // in both categories are Coupled
        Coordinate::MotionType mt = Coordinate::MotionType::Undefined;
        for (int j = 0; j < 6; ++j){
            auto coordNamesForAxis = spatialTransform[j]
                .getCoordinateNamesInArray();
            if (coordNamesForAxis.findIndex(coordName) >= 0) {
                const LinearFunction* lf = nullptr;
                if (spatialTransform[j].hasFunction()) {
                    lf = dynamic_cast<const LinearFunction*>(
                            &spatialTransform[j].get_function() );
                    // if displacement on axis is directly proportional to
                    // the coordinate value, we have a pure rotation/translation
                    if (lf && lf->getSlope() == 1.0) {
                        // coordinate is pure axis displacement
                        if (j < 3)
                            // coordinate about rotational axis
                            mt = Coordinate::MotionType::Rotational;
                        else // otherwise translational axis
                            mt = Coordinate::MotionType::Translational;
                    }
                    else { // scaled (slope !=1) or nonlinear relationship means
                           // not a pure rotational or translational for this axis.
                           // designate as Coupled unless already defined as
                           // pure Rotational or Translational about another axis
                        mt = (mt == Coordinate::MotionType::Undefined ?
                            Coordinate::MotionType::Coupled : mt);
                    }
                }
            }
        }
        setMotionType(CoordinateIndex(i), mt);
    }
}

//=============================================================================
// Simbody Model building.
//=============================================================================
//_____________________________________________________________________________
void CustomJoint::extendAddToSystem(SimTK::MultibodySystem& system) const
{
    Super::extendAddToSystem(system);

    SimTK::MobilizedBody inb;
    SimTK::Body outb;
    SimTK::Transform inbX = getParentFrame().findTransformInBaseFrame();
    SimTK::Transform outbX = getChildFrame().findTransformInBaseFrame();
    const OpenSim::PhysicalFrame* mobilized = &getChildFrame();
    // if the joint is reversed then flip the underlying tree representation
    // of inboard and outboard bodies, although the joint direction will be
    // preserved, the inboard must exist first.
    if (get_reverse()){
        inb = getChildFrame().getMobilizedBody();
        inbX = getChildFrame().findTransformInBaseFrame();

        outb = getParentInternalRigidBody();
        outbX = getParentFrame().findTransformInBaseFrame();

        mobilized = &getParentFrame();
    }
    else{
        inb = getParentFrame().getMobilizedBody();
        outb = getChildInternalRigidBody();
    }

    const Array<std::string>& coordNames = getSpatialTransform().getCoordinateNames();

    // Some initializations
    const int numCoords = numCoordinates();  // Note- should check that all coordinates are used.
    std::vector<std::vector<int> > coordinateIndices =
        getSpatialTransform().getCoordinateIndices();
    std::vector<const SimTK::Function*> functions =
        getSpatialTransform().getFunctions();
    std::vector<Vec3> axes = getSpatialTransform().getAxes();

    SimTK_ASSERT1(numCoords == coordNames.getSize(),
        "%s list of coordinates does not match number of mobilities.",
        getConcreteClassName().c_str());

    SimTK_ASSERT1(numCoords > 0,
        "%s must have 1 or more mobilities (dofs).",
                  getConcreteClassName().c_str());

    SimTK_ASSERT1(numCoords <= 6,
        "%s cannot exceed 6 mobilities (dofs).",
        getConcreteClassName().c_str());
    assert(functions.size() == 6);

    SimTK_ASSERT2(numCoords <= 6,
        "%s::%s must specify functions for complete spatial (6 axes) motion.",
        getConcreteClassName().c_str(),
                  getSpatialTransform().getConcreteClassName().c_str());
    assert(coordinateIndices.size() == 6);

    SimTK_ASSERT2(axes.size() == 6,
        "%s::%s must specify 6 independent axes to span spatial motion.",
        getConcreteClassName().c_str(), getSpatialTransform().getConcreteClassName().c_str());

    SimTK::MobilizedBody::Direction dir =
        SimTK::MobilizedBody::Direction(get_reverse());

    SimTK::MobilizedBody::FunctionBased
        simtkBody(inb, inbX,
                  outb, outbX,
                    numCoords, functions,
                  coordinateIndices, axes, dir);

    assignSystemIndicesToBodyAndCoordinates(simtkBody, mobilized, numCoords, 0);
}

//=============================================================================
// Utilities for versioning
//=============================================================================
//_____________________________________________________________________________

/** Override of the default implementation to account for versioning. */
void CustomJoint::
updateFromXMLNode(SimTK::Xml::Element& aNode, int versionNumber)
{
    int documentVersion = versionNumber;
    if ( documentVersion < XMLDocument::getLatestVersion()){
        if (Object::getDebugLevel()>=1)
            cout << "Updating CustomJoint to latest format..." << endl;
        // Version before refactoring spatialTransform
        if (documentVersion<10901){
            // replace TransformAxisSet with SpatialTransform
            /////renameChildNode("TransformAxisSet", "SpatialTransform");
            // Check how many TransformAxes are defined
            SimTK::Xml::element_iterator spatialTransformNode =
                aNode.element_begin("TransformAxisSet");
            if (spatialTransformNode == aNode.element_end()) return;

            SimTK::Xml::element_iterator axesSetNode =
                spatialTransformNode->element_begin("objects");
            /////if (axesSetNode != NULL)
            /////   spatialTransformNode->removeChild(axesSetNode);
            /////DOMElement*grpNode = XMLNode::GetFirstChildElementByTagName(spatialTransformNode,"groups");
            /////if (grpNode != NULL)
            /////   spatialTransformNode->removeChild(grpNode);
            // (0, 1, 2 rotations & 3, 4, 5 translations then remove the is_rotation node)
            SimTK::Array_<SimTK::Xml::Element> list =
                axesSetNode->getAllElements();
            unsigned int listLength = list.size();
            //int objectsFound = 0;
            Array<int> translationIndices(-1, 0);
            Array<int>  rotationIndices(-1, 0);
            int nextAxis = 0;
            std::vector<TransformAxis *> axes;
            // Add children for all six axes here
            //////_node->removeChild(SpatialTransformNode);

            // Create a blank Spatial Transform and use it to populate the
            // XML structure
            for(int i=0; i<6; i++)
                updSpatialTransform()[i].setFunction(new OpenSim::Constant(0));

            Array<OpenSim::TransformAxis*> oldAxes;
            for(unsigned int j=0;j<listLength;j++) {
                // getChildNodes() returns all types of DOMNodes including
                // comments, text, etc., but we only want
                // to process element nodes
                SimTK::Xml::Element objElmt = list[j];
                string objectType = objElmt.getElementTag();
                // (sherm) this is cleaning up old TransformAxis here but
                // that should really be done in TransformAxis instead.
                if (objectType == "TransformAxis"){
                    OpenSim::TransformAxis* readAxis =
                        new OpenSim::TransformAxis(objElmt);
                    assert(nextAxis <=5);
                    bool isRotation = false;
                    SimTK::Xml::element_iterator rotationNode =
                        objElmt.element_begin("is_rotation");
                    if (rotationNode != objElmt.element_end()){
                        SimTK::String sValue =
                            rotationNode->getValueAs<SimTK::String>();
                        bool value = (sValue.toLower() == "true");
                                isRotation = value;
                        objElmt.eraseNode(rotationNode);
                            }
                    SimTK::Xml::element_iterator coordinateNode =
                        objElmt.element_begin("coordinate");
                    SimTK::String coordinateName =
                        coordinateNode->getValueAs<SimTK::String>();
                    Array<std::string> names("");
                    names.append(coordinateName);
                    readAxis->setCoordinateNames(names);
                    SimTK::Xml::element_iterator axisNode =
                        objElmt.element_begin("axis");

                    SimTK::Vec3 axisVec= axisNode->getValueAs<SimTK::Vec3>();
                    readAxis->setAxis(axisVec);
                    if (isRotation){
                        rotationIndices.append(nextAxis);
                    }
                    else {
                        translationIndices.append(nextAxis);
                    }
                    axes.push_back(readAxis);
                    nextAxis++;
                }
            }
            assert(rotationIndices.getSize() <=3);
            assert(translationIndices.getSize() <=3);
            //XMLNode::RemoveChildren(SpatialTransformAxesNode);
            int nRotations = rotationIndices.getSize();
            int nTranslations = translationIndices.getSize();
            // Now copy coordinateName, Axis, Function into proper slot
            for (int i=0; i<nRotations; i++){
                updSpatialTransform()[i] = *axes[rotationIndices[i]];
            }
            updSpatialTransform().constructIndependentAxes(nRotations, 0);
            // Add Translations from old list then pad with default ones,
            // make sure no singularity.
            for (int i=0; i<nTranslations; i++){
                updSpatialTransform()[i+3] = *axes[translationIndices[i]];
            }
            updSpatialTransform().constructIndependentAxes(nTranslations, 3);
        }
    }

    // Delegate to superclass now.
    Super::updateFromXMLNode(aNode, versionNumber);
}
<commit_msg>Comment fix<commit_after>/* -------------------------------------------------------------------------- *
 *                         OpenSim:  CustomJoint.cpp                          *
 * -------------------------------------------------------------------------- *
 * The OpenSim API is a toolkit for musculoskeletal modeling and simulation.  *
 * See http://opensim.stanford.edu and the NOTICE file for more information.  *
 * OpenSim is developed at Stanford University and supported by the US        *
 * National Institutes of Health (U54 GM072970, R24 HD065690) and by DARPA    *
 * through the Warrior Web program.                                           *
 *                                                                            *
 * Copyright (c) 2005-2016 Stanford University and the Authors                *
 * Author(s): Frank C. Anderson, Peter Loan, Ajay Seth                        *
 *                                                                            *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may    *
 * not use this file except in compliance with the License. You may obtain a  *
 * copy of the License at http://www.apache.org/licenses/LICENSE-2.0.         *
 *                                                                            *
 * Unless required by applicable law or agreed to in writing, software        *
 * distributed under the License is distributed on an "AS IS" BASIS,          *
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   *
 * See the License for the specific language governing permissions and        *
 * limitations under the License.                                             *
 * -------------------------------------------------------------------------- */

//=============================================================================
// INCLUDES
//=============================================================================
#include "CustomJoint.h"
#include "SpatialTransform.h"
#include <OpenSim/Simulation/Model/Model.h>
#include <OpenSim/Common/Constant.h>
#include <OpenSim/Common/LinearFunction.h>
#include "simbody/internal/MobilizedBody_FunctionBased.h"

//=============================================================================
// STATICS
//=============================================================================
using namespace std;
using namespace SimTK;
using namespace OpenSim;

//=============================================================================
// CONSTRUCTOR(S) AND DESTRUCTOR
//=============================================================================
//_____________________________________________________________________________
/* Default Constructor */
CustomJoint::CustomJoint()
{
    constructProperties();
}

/**
 * Constructor with specified SpatialTransform.
 */
CustomJoint::CustomJoint(const std::string &name,
                         const PhysicalFrame& parent,
                         const PhysicalFrame& child,
                         SpatialTransform& spatialTransform,
                         bool reverse) :
                         Super(name, parent, child, reverse)
{
    constructProperties();
    set_SpatialTransform(spatialTransform);
}

CustomJoint::CustomJoint(const std::string& name,
    const PhysicalFrame& parent,
    const SimTK::Vec3& locationInParent,
    const SimTK::Vec3& orientationInParent,
    const PhysicalFrame& child,
    const SimTK::Vec3& locationInChild,
    const SimTK::Vec3& orientationInChild,
    SpatialTransform& spatialTransform,
    bool reverse) :
        Super(name, parent, locationInParent, orientationInParent,
            child, locationInChild, orientationInChild, reverse)
{
    constructProperties();
    set_SpatialTransform(spatialTransform);
}

//_____________________________________________________________________________
/**
 * Connect properties to local pointers.
 */
void CustomJoint::constructProperties()
{
    setAuthors("Frank C. Anderson, Ajay Seth");
    constructProperty_SpatialTransform(SpatialTransform());
}

/*
 * Perform some set up functions that happen after the
 * object has been deserialized or copied.
 */
void CustomJoint::extendFinalizeFromProperties()
{
    Super::extendFinalizeFromProperties();

    //CustomJoint can only construct the coordinates once SpatialTransform is specified
    constructCoordinates();

    // Axes should be independent otherwise Simbody throws an exception in extendAddToSystem
    double tol = 1e-5;
    // Verify that none of the rotation axes are collinear
    const std::vector<SimTK::Vec3> axes = getSpatialTransform().getAxes();
    for (int startIndex = 0; startIndex <= 3; startIndex += 3) {
        if (((axes[startIndex + 0] % axes[startIndex + 1]).norm() < tol) ||
            ((axes[startIndex + 0] % axes[startIndex + 2]).norm() < tol) ||
            ((axes[startIndex + 1] % axes[startIndex + 2]).norm() < tol)) {
            throw(Exception("CustomJoint '" + getName() +
                "' has collinear axes and are not well-defined."
                " Please fix and retry loading."));
        }
    }
}

void CustomJoint::extendConnectToModel(Model& aModel)
{
    Super::extendConnectToModel(aModel);
    // SpatialTransform "connect" methods are poorly named. This
    // establishing the SpatialTransform and its Transform axes as
    // sub objects (not updated to Components) of the CustomJoint and this
    // should be done here.
    /* Set up spatial transform for this custom joint. */
    updSpatialTransform().connectToJoint(*this);
}

//=============================================================================
// GET AND SET
//=============================================================================
// SCALING
//=============================================================================
//_____________________________________________________________________________
/**
 * Scale a joint based on XYZ scale factors for the bodies.
 *
 * @param aScaleSet Set of XYZ scale factors for the bodies.
 * @todo Need to scale transforms appropriately, given an arbitrary axis.
 */
void CustomJoint::scale(const ScaleSet& aScaleSet)
{
    Vec3 scaleFactors(1.0);

    // Joint knows how to scale locations of the joint in parent and on the body
    Super::scale(aScaleSet);

    // SCALING TO DO WITH THE PARENT BODY -----
    // Joint kinematics are scaled by the scale factors for the
    // parent body, so get those body's factors
    const string& parentName = getParentFrame().getName();
    for (int i=0; i<aScaleSet.getSize(); i++) {
        Scale& scale = aScaleSet.get(i);
        if (scale.getSegmentName()==parentName) {
            scale.getScaleFactors(scaleFactors);
            break;
        }
    }

    updSpatialTransform().scale(scaleFactors);
}

void CustomJoint::constructCoordinates()
{
    const SpatialTransform& spatialTransform = getSpatialTransform();
    OpenSim::Array<std::string> coordinateNames
        = spatialTransform.getCoordinateNames();

    // Check how many coordinates are required
    int ncoords = coordinateNames.getSize();

    for (int i = 0; i < ncoords; ++i){
        std::string coordName = spatialTransform.getCoordinateNames()[i];
        // Locate the coordinate in the set if it has already been defined (e.g. in XML)
        int coordIndex = getProperty_coordinates().findIndexForName(coordName);
        if (coordIndex < 0) {
            coordIndex = constructCoordinate(Coordinate::MotionType::Undefined,
                                             i);
        }
        Coordinate& coord = upd_coordinates(coordIndex);
        coord.setName(coordName);

        // Determine the MotionType of the Coordinate based
        // on which TransformAxis it operates upon: 0-2 are Rotational
        // and 3-5 are Translational. Coordinates appearing
        // in both categories are Coupled
        Coordinate::MotionType mt = Coordinate::MotionType::Undefined;
        for (int j = 0; j < 6; ++j){
            auto coordNamesForAxis = spatialTransform[j]
                .getCoordinateNamesInArray();
            if (coordNamesForAxis.findIndex(coordName) >= 0) {
                const LinearFunction* lf = nullptr;
                if (spatialTransform[j].hasFunction()) {
                    lf = dynamic_cast<const LinearFunction*>(
                            &spatialTransform[j].get_function() );
                    // if displacement on axis is directly proportional to
                    // the coordinate value, we have a pure rotation/translation
                    if (lf && lf->getSlope() == 1.0) {
                        // coordinate is pure axis displacement
                        if (j < 3)
                            // coordinate about rotational axis
                            mt = Coordinate::MotionType::Rotational;
                        else // otherwise translational axis
                            mt = Coordinate::MotionType::Translational;
                    }
                    else { // scaled (slope !=1) or nonlinear relationship means
                           // not a pure rotational or translational for this axis.
                           // designate as Coupled unless already defined as
                           // pure Rotational or Translational about another axis
                        mt = (mt == Coordinate::MotionType::Undefined ?
                            Coordinate::MotionType::Coupled : mt);
                    }
                }
            }
        }
        setMotionType(CoordinateIndex(i), mt);
    }
}

//=============================================================================
// Simbody Model building.
//=============================================================================
//_____________________________________________________________________________
void CustomJoint::extendAddToSystem(SimTK::MultibodySystem& system) const
{
    Super::extendAddToSystem(system);

    SimTK::MobilizedBody inb;
    SimTK::Body outb;
    SimTK::Transform inbX = getParentFrame().findTransformInBaseFrame();
    SimTK::Transform outbX = getChildFrame().findTransformInBaseFrame();
    const OpenSim::PhysicalFrame* mobilized = &getChildFrame();
    // if the joint is reversed then flip the underlying tree representation
    // of inboard and outboard bodies, although the joint direction will be
    // preserved, the inboard must exist first.
    if (get_reverse()){
        inb = getChildFrame().getMobilizedBody();
        inbX = getChildFrame().findTransformInBaseFrame();

        outb = getParentInternalRigidBody();
        outbX = getParentFrame().findTransformInBaseFrame();

        mobilized = &getParentFrame();
    }
    else{
        inb = getParentFrame().getMobilizedBody();
        outb = getChildInternalRigidBody();
    }

    const Array<std::string>& coordNames = getSpatialTransform().getCoordinateNames();

    // Some initializations
    const int numCoords = numCoordinates();  // Note- should check that all coordinates are used.
    std::vector<std::vector<int> > coordinateIndices =
        getSpatialTransform().getCoordinateIndices();
    std::vector<const SimTK::Function*> functions =
        getSpatialTransform().getFunctions();
    std::vector<Vec3> axes = getSpatialTransform().getAxes();

    SimTK_ASSERT1(numCoords == coordNames.getSize(),
        "%s list of coordinates does not match number of mobilities.",
        getConcreteClassName().c_str());

    SimTK_ASSERT1(numCoords > 0,
        "%s must have 1 or more mobilities (dofs).",
                  getConcreteClassName().c_str());

    SimTK_ASSERT1(numCoords <= 6,
        "%s cannot exceed 6 mobilities (dofs).",
        getConcreteClassName().c_str());
    assert(functions.size() == 6);

    SimTK_ASSERT2(numCoords <= 6,
        "%s::%s must specify functions for complete spatial (6 axes) motion.",
        getConcreteClassName().c_str(),
                  getSpatialTransform().getConcreteClassName().c_str());
    assert(coordinateIndices.size() == 6);

    SimTK_ASSERT2(axes.size() == 6,
        "%s::%s must specify 6 independent axes to span spatial motion.",
        getConcreteClassName().c_str(), getSpatialTransform().getConcreteClassName().c_str());

    SimTK::MobilizedBody::Direction dir =
        SimTK::MobilizedBody::Direction(get_reverse());

    SimTK::MobilizedBody::FunctionBased
        simtkBody(inb, inbX,
                  outb, outbX,
                    numCoords, functions,
                  coordinateIndices, axes, dir);

    assignSystemIndicesToBodyAndCoordinates(simtkBody, mobilized, numCoords, 0);
}

//=============================================================================
// Utilities for versioning
//=============================================================================
//_____________________________________________________________________________

/** Override of the default implementation to account for versioning. */
void CustomJoint::
updateFromXMLNode(SimTK::Xml::Element& aNode, int versionNumber)
{
    int documentVersion = versionNumber;
    if ( documentVersion < XMLDocument::getLatestVersion()){
        if (Object::getDebugLevel()>=1)
            cout << "Updating CustomJoint to latest format..." << endl;
        // Version before refactoring spatialTransform
        if (documentVersion<10901){
            // replace TransformAxisSet with SpatialTransform
            /////renameChildNode("TransformAxisSet", "SpatialTransform");
            // Check how many TransformAxes are defined
            SimTK::Xml::element_iterator spatialTransformNode =
                aNode.element_begin("TransformAxisSet");
            if (spatialTransformNode == aNode.element_end()) return;

            SimTK::Xml::element_iterator axesSetNode =
                spatialTransformNode->element_begin("objects");
            /////if (axesSetNode != NULL)
            /////   spatialTransformNode->removeChild(axesSetNode);
            /////DOMElement*grpNode = XMLNode::GetFirstChildElementByTagName(spatialTransformNode,"groups");
            /////if (grpNode != NULL)
            /////   spatialTransformNode->removeChild(grpNode);
            // (0, 1, 2 rotations & 3, 4, 5 translations then remove the is_rotation node)
            SimTK::Array_<SimTK::Xml::Element> list =
                axesSetNode->getAllElements();
            unsigned int listLength = list.size();
            //int objectsFound = 0;
            Array<int> translationIndices(-1, 0);
            Array<int>  rotationIndices(-1, 0);
            int nextAxis = 0;
            std::vector<TransformAxis *> axes;
            // Add children for all six axes here
            //////_node->removeChild(SpatialTransformNode);

            // Create a blank Spatial Transform and use it to populate the
            // XML structure
            for(int i=0; i<6; i++)
                updSpatialTransform()[i].setFunction(new OpenSim::Constant(0));

            Array<OpenSim::TransformAxis*> oldAxes;
            for(unsigned int j=0;j<listLength;j++) {
                // getChildNodes() returns all types of DOMNodes including
                // comments, text, etc., but we only want
                // to process element nodes
                SimTK::Xml::Element objElmt = list[j];
                string objectType = objElmt.getElementTag();
                // (sherm) this is cleaning up old TransformAxis here but
                // that should really be done in TransformAxis instead.
                if (objectType == "TransformAxis"){
                    OpenSim::TransformAxis* readAxis =
                        new OpenSim::TransformAxis(objElmt);
                    assert(nextAxis <=5);
                    bool isRotation = false;
                    SimTK::Xml::element_iterator rotationNode =
                        objElmt.element_begin("is_rotation");
                    if (rotationNode != objElmt.element_end()){
                        SimTK::String sValue =
                            rotationNode->getValueAs<SimTK::String>();
                        bool value = (sValue.toLower() == "true");
                                isRotation = value;
                        objElmt.eraseNode(rotationNode);
                            }
                    SimTK::Xml::element_iterator coordinateNode =
                        objElmt.element_begin("coordinate");
                    SimTK::String coordinateName =
                        coordinateNode->getValueAs<SimTK::String>();
                    Array<std::string> names("");
                    names.append(coordinateName);
                    readAxis->setCoordinateNames(names);
                    SimTK::Xml::element_iterator axisNode =
                        objElmt.element_begin("axis");

                    SimTK::Vec3 axisVec= axisNode->getValueAs<SimTK::Vec3>();
                    readAxis->setAxis(axisVec);
                    if (isRotation){
                        rotationIndices.append(nextAxis);
                    }
                    else {
                        translationIndices.append(nextAxis);
                    }
                    axes.push_back(readAxis);
                    nextAxis++;
                }
            }
            assert(rotationIndices.getSize() <=3);
            assert(translationIndices.getSize() <=3);
            //XMLNode::RemoveChildren(SpatialTransformAxesNode);
            int nRotations = rotationIndices.getSize();
            int nTranslations = translationIndices.getSize();
            // Now copy coordinateName, Axis, Function into proper slot
            for (int i=0; i<nRotations; i++){
                updSpatialTransform()[i] = *axes[rotationIndices[i]];
            }
            updSpatialTransform().constructIndependentAxes(nRotations, 0);
            // Add Translations from old list then pad with default ones,
            // make sure no singularity.
            for (int i=0; i<nTranslations; i++){
                updSpatialTransform()[i+3] = *axes[translationIndices[i]];
            }
            updSpatialTransform().constructIndependentAxes(nTranslations, 3);
        }
    }

    // Delegate to superclass now.
    Super::updateFromXMLNode(aNode, versionNumber);
}
<|endoftext|>


<commit_before><commit_msg>[functions.interfaces] do not guard config.h any more<commit_after><|endoftext|>


<commit_before>/******************************************************************************\
* File:          textfile.cpp
* Purpose:       Implementation of class 'wxExTextFileWithListView'
* Author:        Anton van Wezenbeek
* RCS-ID:        $Id$
*
* Copyright (c) 1998-2009 Anton van Wezenbeek
* All rights are reserved. Reproduction in whole or part is prohibited
* without the written consent of the copyright owner.
\******************************************************************************/

#include <wx/extension/report/textfile.h>
#include <wx/extension/frd.h>
#include <wx/extension/log.h>
#include <wx/extension/util.h>
#include <wx/extension/report/defs.h>
#include <wx/extension/report/listview.h>
#include <wx/extension/report/frame.h>
#include <wx/extension/report/listitem.h>

wxExListViewWithFrame* wxExTextFileWithListView::m_Report = NULL;
wxExFrameWithHistory* wxExTextFileWithListView::m_Frame = NULL;

void SetItemColumnStatistics(
  wxExListItemWithFileName& item,
  const wxString& col,
  const wxExStatistics<long>& stat)
{
  item.SetColumnText(
    col,
    wxString::Format("%ld", stat.Get(col)));
}

#if wxExUSE_EMBEDDED_SQL
wxExOTL wxExTextFileWithListView::m_otl;

class Recordset
{
public:
  Recordset(otl_connect* db, wxExTextFile* file)
    : m_db(db)
    , m_TextFile(file)
    , m_Records(0){}
  size_t GetRecords() const {return m_Records;};
  bool ExecQuery(const wxString& query);
  static const wxString QueryRunTimeText() {return "QUERY RUN TIME: ";};
private:
  void UpdateTextFileFromQuery();
  otl_connect* m_db;
  otl_stream m_stream;
  wxExTextFile* m_TextFile;
  wxString m_Query;
  size_t m_Records;
};
#endif

wxExTextFileWithListView::wxExTextFileWithListView(
  const wxExFileName& filename,
  const wxExTool& tool)
  : wxExTextFile(filename, tool)
#if wxExUSE_EMBEDDED_SQL
  , m_SQLResultsParsing(false)
#endif
{
}

#if wxExUSE_EMBEDDED_SQL
bool wxExTextFileWithListView::ParseComments()
{
  if (GetTool().GetId() == ID_TOOL_SQL || GetTool().GetId() == ID_TOOL_REPORT_SQL)
  {
    if (!m_SQLResultsParsing)
    {
      if (GetComments().substr(0, 4) == " SQL")
      {
        if (SetSQLQuery())
        {
          if (!ParseSQL())
          {
            return false;
          }
        }
      }
      else
      {
        ClearComments();
      }
    }
    else
    {
      if (GetTool().GetId() == ID_TOOL_REPORT_SQL &&
        GetComments().length() > Recordset::QueryRunTimeText().length() + 1 &&
        GetComments().substr(
          1,
          Recordset::QueryRunTimeText().length()) == Recordset::QueryRunTimeText())
      {
        const int start_of_runtime = Recordset::QueryRunTimeText().length() + 1;
        m_SQLQueryRunTime = GetComments().substr(start_of_runtime);
        Report();
      }

      if (GetComments().substr(0, 8) == " SQL END")
      {
        m_SQLResultsParsing = false;
      }

      ClearComments();
    }
  }

  return wxExTextFile::ParseComments();
}
#endif

#if wxExUSE_EMBEDDED_SQL
bool wxExTextFileWithListView::ParseSQL()
{
/*
 ; SQL # ..
 ;       .. #
<-- new data inserted by the recordset
 ; QUERY RUN TIME: 981201 150953
 ; USING DATABASE F\GAREX\CONFIG_MAIN.mdb
 new data
 ..
<-- end of new data
<-- old data starts here, will be deleted (the marker points to here)
 ; QUERY RUN TIME: 981201 150953
 ; USING DATABASE F\GAREX\CONFIG_MAIN.mdb
 old data
 ..
<-- end of old data
 ; SQL END (this statement triggers deletion)
*/
  if (GetTool().GetId() == ID_TOOL_SQL)
  {
    wxExLog::Get()->Log(
      _("File") + ": " + GetFileName().GetFullName() + " Query: " + wxExSkipWhiteSpace(m_SQLQuery));

    Recordset rs(&m_otl.GetConnect(), this);
    if (!rs.ExecQuery(m_SQLQuery))
    {
      return false;
    }

    const wxString msg = wxString::Format(_("Retrieved: %d records"), rs.GetRecords());
    wxExLog::Get()->Log(msg);
#if wxUSE_STATUSBAR
    wxExFrame::StatusText(msg);
#endif
  }

  // Test for SQL end statement.
  const size_t marker = GetCurrentLine();
  ClearComments();
  m_SQLResultsParsing = true;

  while (!Eof() && m_SQLResultsParsing)
  {
    if (!ParseLine(GetNextLine()))
    {
      return false;
    }
  }

  if (m_SQLResultsParsing)
  {
    wxLogError("Missing SQL END after query: " + wxExSkipWhiteSpace(m_SQLQuery));
    return false;
  }

  // Remove all old lines, except the last one containing the end statement.
  if (GetTool().GetId() == ID_TOOL_SQL)
  {
    for (size_t i = GetCurrentLine() - 1; i >= marker; i--)
    {
      RemoveLine(i);
    }

    GoToLine(marker);
  }

  IncActionsCompleted();

  return true;
}
#endif

void wxExTextFileWithListView::Report(size_t line)
{
  wxASSERT(m_Report != NULL);

  wxExListItemWithFileName item(m_Report, GetFileName().GetFullPath());
  item.Insert();

  item.SetColumnText(_("Line No"), wxString::Format("%d", line + 1));

  switch (GetTool().GetId())
  {
  case ID_TOOL_REPORT_REPLACE:
    item.SetColumnText(_("Replaced"), wxExFindReplaceData::Get()->GetReplaceString());
  case ID_TOOL_REPORT_FIND:
    item.SetColumnText(_("Line"), GetRCS().GetDescription().Strip(wxString::both));
    item.SetColumnText(_("Match"), wxExFindReplaceData::Get()->GetFindString());
  break;

  case ID_TOOL_REPORT_REVISION:
    item.UpdateRevisionList(GetRCS());
  break;

#if wxExUSE_EMBEDDED_SQL
  case ID_TOOL_REPORT_SQL:
    item.SetColumnText(_("Query"), m_SQLQuery);
    item.SetColumnText(_("Run Time"), m_SQLQueryRunTime);
  break;
#endif

  default: wxFAIL;
  }
}

void wxExTextFileWithListView::ReportStatistics()
{
  if (GetTool().GetId() == ID_TOOL_REPORT_KEYWORD)
  {
    m_Report = m_Frame->Activate(
      wxExListViewFile::GetTypeTool(GetTool()),
      &GetFileName().GetLexer());

    if (m_Report == NULL)
    {
      return;
    }
  }

  wxExListItemWithFileName item(m_Report, GetFileName().GetFullPath());
  item.Insert();

  switch (GetTool().GetId())
  {
  case ID_TOOL_REPORT_COUNT:
    SetItemColumnStatistics(item, _("Lines"), GetStatistics().GetElements());
    SetItemColumnStatistics(item, _("Lines Of Code"), GetStatistics().GetElements());
    SetItemColumnStatistics(item, _("Empty Lines"), GetStatistics().GetElements());
    SetItemColumnStatistics(item, _("Words Of Code"), GetStatistics().GetElements());
    SetItemColumnStatistics(item, _("Comments"), GetStatistics().GetElements());
    SetItemColumnStatistics(item, _("Comment Size"), GetStatistics().GetElements());
  break;

  case ID_TOOL_REPORT_KEYWORD:
  {
    long total = 0;
    for (size_t i = 0; i < GetFileName().GetLexer().GetKeywords().size(); i++)
    {
      const wxString name = m_Report->GetColumn(i + 1).GetText();
      const long value = GetStatistics().GetKeywords().Get(name);
      item.SetColumnText(i + 1, wxString::Format("%ld", value));
      total += value;
    }
    item.SetColumnText(
      GetFileName().GetLexer().GetKeywords().size() + 1,
      wxString::Format("%ld", total));
  }
  break;

  default: wxFAIL;
  }
}

#if wxExUSE_EMBEDDED_SQL
bool wxExTextFileWithListView::SetSQLQuery()
{
  const size_t pos_start_of_query = GetComments().find('#');
  const size_t pos_end_of_query = GetComments().rfind('#');

  if (pos_start_of_query == wxString::npos ||
      pos_start_of_query == pos_end_of_query)
  {
    return false;
  }

  m_SQLQuery = GetComments().substr(
    pos_start_of_query + 1,
    pos_end_of_query - pos_start_of_query - 1);

  m_SQLQuery.Trim(false);
  m_SQLQuery.Trim(true);

  return true;
}
#endif

bool wxExTextFileWithListView::SetupTool(const wxExTool& tool)
{
#if wxExUSE_EMBEDDED_SQL
  if (tool.GetId() == ID_TOOL_SQL)
  {
    if (m_otl.IsConnected())
    {
      m_otl.Logoff();
    }

    // This is a static function, we cannot use this pointer.
    wxASSERT(wxTheApp != NULL);

    if (!m_otl.Logon(wxTheApp->GetTopWindow(), wxConfigBase::Get()))
    {
      return false;
    }
  }
#endif

  if (tool.IsReportType())
  {
    wxASSERT(wxTheApp != NULL);
    wxWindow* window = wxTheApp->GetTopWindow();
    m_Frame = wxDynamicCast(window, wxExFrameWithHistory);

    if (m_Frame == NULL)
    {
      wxFAIL;
      return false;
    }

    if (tool.GetId() != ID_TOOL_REPORT_KEYWORD)
    {
      m_Report = m_Frame->Activate(wxExListViewFile::GetTypeTool(tool));

      if (m_Report == NULL)
      {
        return false;
      }
    }
  }

  return true;
}

#if wxExUSE_EMBEDDED_SQL
bool Recordset::ExecQuery(const wxString& query)
{
  // If the query does not contain any space,
  // assume that it specifies an existing query in the database.
  // Otherwise the statement itself is a query, pass it through as specified.
  m_Query = (!query.Contains(" ") ? "SELECT * FROM " + query: query);

  try
  {
    m_stream.set_all_column_types(otl_all_num2str | otl_all_date2str);
    m_stream.open(1024, m_Query.c_str(), *m_db);
    UpdateTextFileFromQuery();
    return true;
  }
  catch (otl_exception& p)
  {
    wxTextEntryDialog(
      NULL,
      _("Error"),
      _("ODBC Error") + ":",
      p.msg,
      wxOK | wxCENTRE | wxTE_MULTILINE | wxRESIZE_BORDER).ShowModal();
    wxExLog::Get()->Log(p.msg);
    return false;
  }
}

void Recordset::UpdateTextFileFromQuery()
{
  m_TextFile->GoToLine(m_TextFile->GetCurrentLine() + 1);
  m_TextFile->WriteComment(QueryRunTimeText() + wxDateTime::Now().FormatISOCombined(' '));
  m_TextFile->WriteComment("USING ODBC DATABASE: " + wxConfigBase::Get()->Read(_("Datasource")));

  // Get columns.
  int desc_len;
  m_stream.describe_select(desc_len);

   // Get all rows.
  while (!m_stream.eof())
  {
    m_Records++;
    wxString line;
    char rowstr[512];

    for (int n = 0; n < desc_len; n++)
    {
      m_stream >> rowstr;
      line += rowstr;

      if (n < desc_len - 1)
      {
        line += "\t";
      }
    }

    m_TextFile->InsertLine(line);
  }
}
#endif
<commit_msg>fixed compile error<commit_after>/******************************************************************************\
* File:          textfile.cpp
* Purpose:       Implementation of class 'wxExTextFileWithListView'
* Author:        Anton van Wezenbeek
* RCS-ID:        $Id$
*
* Copyright (c) 1998-2009 Anton van Wezenbeek
* All rights are reserved. Reproduction in whole or part is prohibited
* without the written consent of the copyright owner.
\******************************************************************************/

#include <wx/extension/report/textfile.h>
#include <wx/extension/frd.h>
#include <wx/extension/log.h>
#include <wx/extension/util.h>
#include <wx/extension/report/defs.h>
#include <wx/extension/report/listview.h>
#include <wx/extension/report/frame.h>
#include <wx/extension/report/listitem.h>

wxExListViewWithFrame* wxExTextFileWithListView::m_Report = NULL;
wxExFrameWithHistory* wxExTextFileWithListView::m_Frame = NULL;

void SetItemColumnStatistics(
  wxExListItemWithFileName& item,
  const wxString& col,
  const wxExStatistics<long>& stat)
{
  item.SetColumnText(
    col,
    wxString::Format("%ld", stat.Get(col)));
}

#if wxExUSE_EMBEDDED_SQL
wxExOTL wxExTextFileWithListView::m_otl;

class Recordset
{
public:
  Recordset(otl_connect* db, wxExTextFile* file)
    : m_db(db)
    , m_TextFile(file)
    , m_Records(0){}
  size_t GetRecords() const {return m_Records;};
  bool ExecQuery(const wxString& query);
  static const wxString QueryRunTimeText() {return "QUERY RUN TIME: ";};
private:
  void UpdateTextFileFromQuery();
  otl_connect* m_db;
  otl_stream m_stream;
  wxExTextFile* m_TextFile;
  wxString m_Query;
  size_t m_Records;
};
#endif

wxExTextFileWithListView::wxExTextFileWithListView(
  const wxExFileName& filename,
  const wxExTool& tool)
  : wxExTextFile(filename, tool)
#if wxExUSE_EMBEDDED_SQL
  , m_SQLResultsParsing(false)
#endif
{
}

#if wxExUSE_EMBEDDED_SQL
bool wxExTextFileWithListView::ParseComments()
{
  if (GetTool().GetId() == ID_TOOL_SQL || GetTool().GetId() == ID_TOOL_REPORT_SQL)
  {
    if (!m_SQLResultsParsing)
    {
      if (GetComments().substr(0, 4) == " SQL")
      {
        if (SetSQLQuery())
        {
          if (!ParseSQL())
          {
            return false;
          }
        }
      }
      else
      {
        ClearComments();
      }
    }
    else
    {
      if (GetTool().GetId() == ID_TOOL_REPORT_SQL &&
        GetComments().length() > Recordset::QueryRunTimeText().length() + 1 &&
        GetComments().substr(
          1,
          Recordset::QueryRunTimeText().length()) == Recordset::QueryRunTimeText())
      {
        const int start_of_runtime = Recordset::QueryRunTimeText().length() + 1;
        m_SQLQueryRunTime = GetComments().substr(start_of_runtime);
        Report(GetCurrentLine());
      }

      if (GetComments().substr(0, 8) == " SQL END")
      {
        m_SQLResultsParsing = false;
      }

      ClearComments();
    }
  }

  return wxExTextFile::ParseComments();
}
#endif

#if wxExUSE_EMBEDDED_SQL
bool wxExTextFileWithListView::ParseSQL()
{
/*
 ; SQL # ..
 ;       .. #
<-- new data inserted by the recordset
 ; QUERY RUN TIME: 981201 150953
 ; USING DATABASE F\GAREX\CONFIG_MAIN.mdb
 new data
 ..
<-- end of new data
<-- old data starts here, will be deleted (the marker points to here)
 ; QUERY RUN TIME: 981201 150953
 ; USING DATABASE F\GAREX\CONFIG_MAIN.mdb
 old data
 ..
<-- end of old data
 ; SQL END (this statement triggers deletion)
*/
  if (GetTool().GetId() == ID_TOOL_SQL)
  {
    wxExLog::Get()->Log(
      _("File") + ": " + GetFileName().GetFullName() + " Query: " + wxExSkipWhiteSpace(m_SQLQuery));

    Recordset rs(&m_otl.GetConnect(), this);
    if (!rs.ExecQuery(m_SQLQuery))
    {
      return false;
    }

    const wxString msg = wxString::Format(_("Retrieved: %d records"), rs.GetRecords());
    wxExLog::Get()->Log(msg);
#if wxUSE_STATUSBAR
    wxExFrame::StatusText(msg);
#endif
  }

  // Test for SQL end statement.
  const size_t marker = GetCurrentLine();
  ClearComments();
  m_SQLResultsParsing = true;

  while (!Eof() && m_SQLResultsParsing)
  {
    if (!ParseLine(GetNextLine()))
    {
      return false;
    }
  }

  if (m_SQLResultsParsing)
  {
    wxLogError("Missing SQL END after query: " + wxExSkipWhiteSpace(m_SQLQuery));
    return false;
  }

  // Remove all old lines, except the last one containing the end statement.
  if (GetTool().GetId() == ID_TOOL_SQL)
  {
    for (size_t i = GetCurrentLine() - 1; i >= marker; i--)
    {
      RemoveLine(i);
    }

    GoToLine(marker);
  }

  IncActionsCompleted();

  return true;
}
#endif

void wxExTextFileWithListView::Report(size_t line)
{
  wxASSERT(m_Report != NULL);

  wxExListItemWithFileName item(m_Report, GetFileName().GetFullPath());
  item.Insert();

  item.SetColumnText(_("Line No"), wxString::Format("%d", line + 1));

  switch (GetTool().GetId())
  {
  case ID_TOOL_REPORT_REPLACE:
    item.SetColumnText(_("Replaced"), wxExFindReplaceData::Get()->GetReplaceString());
  case ID_TOOL_REPORT_FIND:
    item.SetColumnText(_("Line"), GetRCS().GetDescription().Strip(wxString::both));
    item.SetColumnText(_("Match"), wxExFindReplaceData::Get()->GetFindString());
  break;

  case ID_TOOL_REPORT_REVISION:
    item.UpdateRevisionList(GetRCS());
  break;

#if wxExUSE_EMBEDDED_SQL
  case ID_TOOL_REPORT_SQL:
    item.SetColumnText(_("Query"), m_SQLQuery);
    item.SetColumnText(_("Run Time"), m_SQLQueryRunTime);
  break;
#endif

  default: wxFAIL;
  }
}

void wxExTextFileWithListView::ReportStatistics()
{
  if (GetTool().GetId() == ID_TOOL_REPORT_KEYWORD)
  {
    m_Report = m_Frame->Activate(
      wxExListViewFile::GetTypeTool(GetTool()),
      &GetFileName().GetLexer());

    if (m_Report == NULL)
    {
      return;
    }
  }

  wxExListItemWithFileName item(m_Report, GetFileName().GetFullPath());
  item.Insert();

  switch (GetTool().GetId())
  {
  case ID_TOOL_REPORT_COUNT:
    SetItemColumnStatistics(item, _("Lines"), GetStatistics().GetElements());
    SetItemColumnStatistics(item, _("Lines Of Code"), GetStatistics().GetElements());
    SetItemColumnStatistics(item, _("Empty Lines"), GetStatistics().GetElements());
    SetItemColumnStatistics(item, _("Words Of Code"), GetStatistics().GetElements());
    SetItemColumnStatistics(item, _("Comments"), GetStatistics().GetElements());
    SetItemColumnStatistics(item, _("Comment Size"), GetStatistics().GetElements());
  break;

  case ID_TOOL_REPORT_KEYWORD:
  {
    long total = 0;
    for (size_t i = 0; i < GetFileName().GetLexer().GetKeywords().size(); i++)
    {
      const wxString name = m_Report->GetColumn(i + 1).GetText();
      const long value = GetStatistics().GetKeywords().Get(name);
      item.SetColumnText(i + 1, wxString::Format("%ld", value));
      total += value;
    }
    item.SetColumnText(
      GetFileName().GetLexer().GetKeywords().size() + 1,
      wxString::Format("%ld", total));
  }
  break;

  default: wxFAIL;
  }
}

#if wxExUSE_EMBEDDED_SQL
bool wxExTextFileWithListView::SetSQLQuery()
{
  const size_t pos_start_of_query = GetComments().find('#');
  const size_t pos_end_of_query = GetComments().rfind('#');

  if (pos_start_of_query == wxString::npos ||
      pos_start_of_query == pos_end_of_query)
  {
    return false;
  }

  m_SQLQuery = GetComments().substr(
    pos_start_of_query + 1,
    pos_end_of_query - pos_start_of_query - 1);

  m_SQLQuery.Trim(false);
  m_SQLQuery.Trim(true);

  return true;
}
#endif

bool wxExTextFileWithListView::SetupTool(const wxExTool& tool)
{
#if wxExUSE_EMBEDDED_SQL
  if (tool.GetId() == ID_TOOL_SQL)
  {
    if (m_otl.IsConnected())
    {
      m_otl.Logoff();
    }

    // This is a static function, we cannot use this pointer.
    wxASSERT(wxTheApp != NULL);

    if (!m_otl.Logon(wxTheApp->GetTopWindow(), wxConfigBase::Get()))
    {
      return false;
    }
  }
#endif

  if (tool.IsReportType())
  {
    wxASSERT(wxTheApp != NULL);
    wxWindow* window = wxTheApp->GetTopWindow();
    m_Frame = wxDynamicCast(window, wxExFrameWithHistory);

    if (m_Frame == NULL)
    {
      wxFAIL;
      return false;
    }

    if (tool.GetId() != ID_TOOL_REPORT_KEYWORD)
    {
      m_Report = m_Frame->Activate(wxExListViewFile::GetTypeTool(tool));

      if (m_Report == NULL)
      {
        return false;
      }
    }
  }

  return true;
}

#if wxExUSE_EMBEDDED_SQL
bool Recordset::ExecQuery(const wxString& query)
{
  // If the query does not contain any space,
  // assume that it specifies an existing query in the database.
  // Otherwise the statement itself is a query, pass it through as specified.
  m_Query = (!query.Contains(" ") ? "SELECT * FROM " + query: query);

  try
  {
    m_stream.set_all_column_types(otl_all_num2str | otl_all_date2str);
    m_stream.open(1024, m_Query.c_str(), *m_db);
    UpdateTextFileFromQuery();
    return true;
  }
  catch (otl_exception& p)
  {
    wxTextEntryDialog(
      NULL,
      _("Error"),
      _("ODBC Error") + ":",
      p.msg,
      wxOK | wxCENTRE | wxTE_MULTILINE | wxRESIZE_BORDER).ShowModal();
    wxExLog::Get()->Log(p.msg);
    return false;
  }
}

void Recordset::UpdateTextFileFromQuery()
{
  m_TextFile->GoToLine(m_TextFile->GetCurrentLine() + 1);
  m_TextFile->WriteComment(QueryRunTimeText() + wxDateTime::Now().FormatISOCombined(' '));
  m_TextFile->WriteComment("USING ODBC DATABASE: " + wxConfigBase::Get()->Read(_("Datasource")));

  // Get columns.
  int desc_len;
  m_stream.describe_select(desc_len);

   // Get all rows.
  while (!m_stream.eof())
  {
    m_Records++;
    wxString line;
    char rowstr[512];

    for (int n = 0; n < desc_len; n++)
    {
      m_stream >> rowstr;
      line += rowstr;

      if (n < desc_len - 1)
      {
        line += "\t";
      }
    }

    m_TextFile->InsertLine(line);
  }
}
#endif
<|endoftext|>