bullet3/examples/SharedMemory/SharedMemoryCommandProcessor.cpp
Erwin Coumans a4f1e34899 expose timeout in pybullet/shared memory API
add RobotSimulator, a C++ API similar to pybullet. (work-in-progress, only part of API implemeted)
2017-02-24 15:34:11 -08:00

218 lines
5.4 KiB
C++

#include "SharedMemoryCommandProcessor.h"
#include "PosixSharedMemory.h"
#include "Win32SharedMemory.h"
#include "Bullet3Common/b3Logging.h"
#include "Bullet3Common/b3Scalar.h"
#include "SharedMemoryBlock.h"
struct SharedMemoryCommandProcessorInternalData
{
int m_sharedMemoryKey;
bool m_isConnected;
SharedMemoryInterface* m_sharedMemory;
bool m_ownsSharedMemory;
bool m_verboseOutput;
bool m_waitingForServer;
SharedMemoryStatus m_lastServerStatus;
SharedMemoryBlock* m_testBlock1;
SharedMemoryCommandProcessorInternalData()
:m_sharedMemoryKey(SHARED_MEMORY_KEY),
m_isConnected(false),
m_sharedMemory(0),
m_ownsSharedMemory(false),
m_verboseOutput(false),
m_waitingForServer(false),
m_testBlock1(0)
{
}
};
SharedMemoryCommandProcessor::SharedMemoryCommandProcessor()
{
m_data = new SharedMemoryCommandProcessorInternalData;
m_data->m_sharedMemoryKey = SHARED_MEMORY_KEY;
#ifdef _WIN32
m_data->m_sharedMemory = new Win32SharedMemoryClient();
#else
m_data->m_sharedMemory = new PosixSharedMemory();
#endif
m_data->m_ownsSharedMemory = true;
}
SharedMemoryCommandProcessor::~SharedMemoryCommandProcessor()
{
if (m_data->m_isConnected)
{
disconnect();
}
if (m_data->m_ownsSharedMemory)
{
delete m_data->m_sharedMemory;
}
delete m_data;
}
bool SharedMemoryCommandProcessor::connect()
{
if (m_data->m_isConnected)
return true;
bool allowCreation = false;
m_data->m_testBlock1 = (SharedMemoryBlock*)m_data->m_sharedMemory->allocateSharedMemory(
m_data->m_sharedMemoryKey, SHARED_MEMORY_SIZE, allowCreation);
if (m_data->m_testBlock1) {
if (m_data->m_testBlock1->m_magicId != SHARED_MEMORY_MAGIC_NUMBER) {
b3Error("Error: please start server before client\n");
m_data->m_sharedMemory->releaseSharedMemory(m_data->m_sharedMemoryKey,
SHARED_MEMORY_SIZE);
m_data->m_testBlock1 = 0;
return false;
}
else {
if (m_data->m_verboseOutput) {
b3Printf("Connected to existing shared memory, status OK.\n");
}
m_data->m_isConnected = true;
}
}
else {
b3Error("Cannot connect to shared memory");
return false;
}
return true;
}
void SharedMemoryCommandProcessor::disconnect()
{
if (m_data->m_isConnected && m_data->m_sharedMemory)
{
m_data->m_sharedMemory->releaseSharedMemory(m_data->m_sharedMemoryKey, SHARED_MEMORY_SIZE);
}
m_data->m_isConnected = false;
}
bool SharedMemoryCommandProcessor::isConnected() const
{
return m_data->m_isConnected;
}
bool SharedMemoryCommandProcessor::processCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes)
{
if (!m_data->m_waitingForServer) {
if (&m_data->m_testBlock1->m_clientCommands[0] != &clientCmd) {
m_data->m_testBlock1->m_clientCommands[0] = clientCmd;
}
m_data->m_testBlock1->m_numClientCommands++;
m_data->m_waitingForServer = true;
}
return false;
}
bool SharedMemoryCommandProcessor::receiveStatus(struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes)
{
m_data->m_lastServerStatus.m_dataStream = 0;
m_data->m_lastServerStatus.m_numDataStreamBytes = 0;
if (!m_data->m_testBlock1)
{
//m_data->m_lastServerStatus.m_type = CMD_SHARED_MEMORY_NOT_INITIALIZED;
//return &m_data->m_lastServerStatus;
//serverStatusOut = m_data->m_lastServerStatus;
return false;
}
if (!m_data->m_waitingForServer) {
return false;
}
if (m_data->m_testBlock1->m_magicId != SHARED_MEMORY_MAGIC_NUMBER)
{
//m_data->m_lastServerStatus.m_type = CMD_SHARED_MEMORY_NOT_INITIALIZED;
//return &m_data->m_lastServerStatus;
return false;
}
if (m_data->m_testBlock1->m_numServerCommands >
m_data->m_testBlock1->m_numProcessedServerCommands)
{
b3Assert(m_data->m_testBlock1->m_numServerCommands ==
m_data->m_testBlock1->m_numProcessedServerCommands + 1);
const SharedMemoryStatus& serverCmd = m_data->m_testBlock1->m_serverCommands[0];
m_data->m_lastServerStatus = serverCmd;
m_data->m_lastServerStatus.m_dataStream = m_data->m_testBlock1->m_bulletStreamDataServerToClientRefactor;
for (int i = 0; i < m_data->m_lastServerStatus.m_numDataStreamBytes; i++)
{
bufferServerToClient[i] = m_data->m_testBlock1->m_bulletStreamDataServerToClientRefactor[i];
}
m_data->m_testBlock1->m_numProcessedServerCommands++;
// we don't have more than 1 command outstanding (in total, either server or client)
b3Assert(m_data->m_testBlock1->m_numProcessedServerCommands ==
m_data->m_testBlock1->m_numServerCommands);
if (m_data->m_testBlock1->m_numServerCommands ==
m_data->m_testBlock1->m_numProcessedServerCommands) {
m_data->m_waitingForServer = false;
}
else {
m_data->m_waitingForServer = true;
}
serverStatusOut = m_data->m_lastServerStatus;
return true;
}
return false;
}
void SharedMemoryCommandProcessor::renderScene()
{
}
void SharedMemoryCommandProcessor::physicsDebugDraw(int debugDrawFlags)
{
}
void SharedMemoryCommandProcessor::setGuiHelper(struct GUIHelperInterface* guiHelper)
{
}
void SharedMemoryCommandProcessor::setSharedMemoryInterface(class SharedMemoryInterface* sharedMem)
{
if (m_data->m_sharedMemory && m_data->m_ownsSharedMemory)
{
delete m_data->m_sharedMemory;
}
m_data->m_ownsSharedMemory = false;
m_data->m_sharedMemory = sharedMem;
}
void SharedMemoryCommandProcessor::setSharedMemoryKey(int key)
{
m_data->m_sharedMemoryKey = key;
}
void SharedMemoryCommandProcessor::setTimeOut(double /*timeOutInSeconds*/)
{
}