diff --git a/examples/CommonInterfaces/CommonExampleInterface.h b/examples/CommonInterfaces/CommonExampleInterface.h index 5d2c0027e..71ced8fca 100644 --- a/examples/CommonInterfaces/CommonExampleInterface.h +++ b/examples/CommonInterfaces/CommonExampleInterface.h @@ -10,12 +10,14 @@ struct CommonExampleOptions //Those are optional, some examples will use them others don't. Each example should work with them being 0. int m_option; const char* m_fileName; + class SharedMemoryInterface* m_sharedMem; CommonExampleOptions(struct GUIHelperInterface* helper, int option=0) :m_guiHelper(helper), m_option(option), - m_fileName(0) + m_fileName(0), + m_sharedMem(0) { } diff --git a/examples/ExampleBrowser/CMakeLists.txt b/examples/ExampleBrowser/CMakeLists.txt index dd49340bf..2e8de4868 100644 --- a/examples/ExampleBrowser/CMakeLists.txt +++ b/examples/ExampleBrowser/CMakeLists.txt @@ -24,6 +24,7 @@ SET(App_ExampleBrowser_SRCS ../SharedMemory/PhysicsClientExample.cpp ../SharedMemory/PosixSharedMemory.cpp ../SharedMemory/Win32SharedMemory.cpp + ../SharedMemory/InProcessMemory.cpp ../SharedMemory/PhysicsServerSharedMemory.cpp ../SharedMemory/PhysicsDirect.cpp ../SharedMemory/PhysicsDirect.h diff --git a/examples/ExampleBrowser/InProcessExampleBrowser.cpp b/examples/ExampleBrowser/InProcessExampleBrowser.cpp index c10b26eab..047f8d3b7 100644 --- a/examples/ExampleBrowser/InProcessExampleBrowser.cpp +++ b/examples/ExampleBrowser/InProcessExampleBrowser.cpp @@ -14,6 +14,7 @@ #include "ExampleEntries.h" #include "Bullet3Common/b3Logging.h" +#include "../SharedMemory/InProcessMemory.h" void ExampleBrowserThreadFunc(void* userPtr,void* lsMemory); void* ExampleBrowserMemoryFunc(); @@ -65,6 +66,7 @@ struct ExampleBrowserArgs struct ExampleBrowserThreadLocalStorage { + SharedMemoryInterface* m_sharedMem; int threadId; }; @@ -92,7 +94,9 @@ void ExampleBrowserThreadFunc(void* userPtr,void* lsMemory) ExampleEntries examples; examples.initExampleEntries(); - ExampleBrowserInterface* exampleBrowser = new DefaultBrowser(&examples); + DefaultBrowser* exampleBrowser = new DefaultBrowser(&examples); + exampleBrowser->setSharedMemoryInterface(localStorage->m_sharedMem); + bool init = exampleBrowser->init(args->m_argc,args->m_argv); clock.reset(); if (init) @@ -139,6 +143,7 @@ struct btInProcessExampleBrowserInternalData { ExampleBrowserArgs m_args; b3ThreadSupportInterface* m_threadSupport; + SharedMemoryInterface* m_sharedMem; }; @@ -146,6 +151,7 @@ btInProcessExampleBrowserInternalData* btCreateInProcessExampleBrowser(int argc, { btInProcessExampleBrowserInternalData* data = new btInProcessExampleBrowserInternalData; + data->m_sharedMem = new InProcessMemory; int numThreads = 1; int i; @@ -163,6 +169,7 @@ btInProcessExampleBrowserInternalData* btCreateInProcessExampleBrowser(int argc, ExampleBrowserThreadLocalStorage* storage = (ExampleBrowserThreadLocalStorage*) data->m_threadSupport->getThreadLocalMemory(i); b3Assert(storage); storage->threadId = i; + storage->m_sharedMem = data->m_sharedMem; } @@ -189,6 +196,11 @@ bool btIsExampleBrowserTerminated(btInProcessExampleBrowserInternalData* data) return (data->m_args.m_cs->getSharedParam(0)==eExampleBrowserHasTerminated); } +SharedMemoryInterface* btGetSharedMemoryInterface(btInProcessExampleBrowserInternalData* data) +{ + return data->m_sharedMem; +} + void btShutDownExampleBrowser(btInProcessExampleBrowserInternalData* data) { int numActiveThreads = 1; @@ -213,6 +225,7 @@ void btShutDownExampleBrowser(btInProcessExampleBrowserInternalData* data) printf("stopping threads\n"); delete data->m_threadSupport; + delete data->m_sharedMem; delete data; } diff --git a/examples/ExampleBrowser/InProcessExampleBrowser.h b/examples/ExampleBrowser/InProcessExampleBrowser.h index 40a731b3e..c294f6873 100644 --- a/examples/ExampleBrowser/InProcessExampleBrowser.h +++ b/examples/ExampleBrowser/InProcessExampleBrowser.h @@ -9,5 +9,7 @@ bool btIsExampleBrowserTerminated(btInProcessExampleBrowserInternalData* data); void btShutDownExampleBrowser(btInProcessExampleBrowserInternalData* data); +class SharedMemoryInterface* btGetSharedMemoryInterface(btInProcessExampleBrowserInternalData* data); + #endif //IN_PROCESS_EXAMPLE_BROWSER_H diff --git a/examples/ExampleBrowser/OpenGLExampleBrowser.cpp b/examples/ExampleBrowser/OpenGLExampleBrowser.cpp index bc3356380..d8756f67e 100644 --- a/examples/ExampleBrowser/OpenGLExampleBrowser.cpp +++ b/examples/ExampleBrowser/OpenGLExampleBrowser.cpp @@ -49,6 +49,7 @@ static CommonParameterInterface* s_parameterInterface=0; static CommonRenderInterface* s_instancingRenderer=0; static OpenGLGuiHelper* s_guiHelper=0; static MyProfileWindow* s_profWindow =0; +static SharedMemoryInterface* sSharedMem = 0; #define DEMO_SELECTION_COMBOBOX 13 const char* startFileName = "0_Bullet3Demo.txt"; @@ -326,6 +327,7 @@ void selectDemo(int demoIndex) int option = gAllExamples->getExampleOption(demoIndex); s_guiHelper= new OpenGLGuiHelper(s_app, sUseOpenGL2); CommonExampleOptions options(s_guiHelper, option); + options.m_sharedMem = sSharedMem; sCurrentDemo = (*func)(options); if (sCurrentDemo) { @@ -1078,3 +1080,8 @@ void OpenGLExampleBrowser::update(float deltaTime) gui->forceUpdateScrollBars(); } + +void OpenGLExampleBrowser::setSharedMemoryInterface(class SharedMemoryInterface* sharedMem) +{ + sSharedMem = sharedMem; +} diff --git a/examples/ExampleBrowser/OpenGLExampleBrowser.h b/examples/ExampleBrowser/OpenGLExampleBrowser.h index 7d181e068..99d2ef73b 100644 --- a/examples/ExampleBrowser/OpenGLExampleBrowser.h +++ b/examples/ExampleBrowser/OpenGLExampleBrowser.h @@ -17,6 +17,8 @@ public: virtual void update(float deltaTime); virtual bool requestedExit(); + + virtual void setSharedMemoryInterface(class SharedMemoryInterface* sharedMem); }; diff --git a/examples/ExampleBrowser/premake4.lua b/examples/ExampleBrowser/premake4.lua index a7b57cfae..bd9d3ae08 100644 --- a/examples/ExampleBrowser/premake4.lua +++ b/examples/ExampleBrowser/premake4.lua @@ -58,6 +58,7 @@ "../SharedMemory/PhysicsClient.cpp", "../SharedMemory/PosixSharedMemory.cpp", "../SharedMemory/Win32SharedMemory.cpp", + "../SharedMemory/InProcessMemory.cpp", "../SharedMemory/PhysicsDirect.cpp", "../SharedMemory/PhysicsDirect.h", "../SharedMemory/PhysicsDirectC_API.cpp", diff --git a/examples/SharedMemory/InProcessMemory.cpp b/examples/SharedMemory/InProcessMemory.cpp new file mode 100644 index 000000000..6a8c7eca9 --- /dev/null +++ b/examples/SharedMemory/InProcessMemory.cpp @@ -0,0 +1,49 @@ +#include "InProcessMemory.h" + + +#include "LinearMath/btHashMap.h" + +struct InProcessMemoryInternalData +{ + btHashMap m_memoryPointers; + +}; + + +InProcessMemory::InProcessMemory() +{ + m_data = new InProcessMemoryInternalData; +} + +InProcessMemory::~InProcessMemory() +{ + for (int i=0;im_memoryPointers.size();i++) + { + void** ptrptr = m_data->m_memoryPointers.getAtIndex(i); + if (ptrptr) + { + void* ptr = *ptrptr; + free(ptr); + } + } + delete m_data; +} + +void* InProcessMemory::allocateSharedMemory(int key, int size, bool allowCreation) +{ + void** ptrptr = m_data->m_memoryPointers[key]; + if (ptrptr) + { + return *ptrptr; + } + + void* ptr = malloc(size); + m_data->m_memoryPointers.insert(key,ptr); + return ptr; +} + +void InProcessMemory::releaseSharedMemory(int /*key*/, int /*size*/) +{ + //we don't release the memory here, but in the destructor instead, + //so multiple users could 'share' the memory given some key +} \ No newline at end of file diff --git a/examples/SharedMemory/InProcessMemory.h b/examples/SharedMemory/InProcessMemory.h new file mode 100644 index 000000000..40bed8114 --- /dev/null +++ b/examples/SharedMemory/InProcessMemory.h @@ -0,0 +1,19 @@ +#ifndef IN_PROCESS_MEMORY_H +#define IN_PROCESS_MEMORY_H + +#include "SharedMemoryInterface.h" + +class InProcessMemory : public SharedMemoryInterface +{ + struct InProcessMemoryInternalData* m_data; + +public: + + InProcessMemory(); + virtual ~InProcessMemory(); + + virtual void* allocateSharedMemory(int key, int size, bool allowCreation); + virtual void releaseSharedMemory(int key, int size); +}; + +#endif diff --git a/examples/SharedMemory/PhysicsClientC_API.cpp b/examples/SharedMemory/PhysicsClientC_API.cpp index 4784c87de..0ffa0d6d1 100644 --- a/examples/SharedMemory/PhysicsClientC_API.cpp +++ b/examples/SharedMemory/PhysicsClientC_API.cpp @@ -72,7 +72,7 @@ b3SharedMemoryCommandHandle b3InitPhysicsParamCommand(b3PhysicsClientHandle { PhysicsClient* cl = (PhysicsClient* ) physClient; b3Assert(cl); - b3Assert(cl->canSubmitCommand()); + b3Assert(cl->canSubmitCommand()); struct SharedMemoryCommand* command = cl->getAvailableSharedMemoryCommand(); b3Assert(command); command->m_type = CMD_SEND_PHYSICS_SIMULATION_PARAMETERS; @@ -445,9 +445,12 @@ void b3DisconnectSharedMemory(b3PhysicsClientHandle physClient) b3SharedMemoryStatusHandle b3ProcessServerStatus(b3PhysicsClientHandle physClient) { PhysicsClient* cl = (PhysicsClient* ) physClient; - const SharedMemoryStatus* stat = cl->processServerStatus(); - return (b3SharedMemoryStatusHandle) stat; - + if (cl && cl->isConnected()) + { + const SharedMemoryStatus* stat = cl->processServerStatus(); + return (b3SharedMemoryStatusHandle) stat; + } + return 0; } @@ -461,7 +464,7 @@ int b3GetStatusType(b3SharedMemoryStatusHandle statusHandle) { return status->m_type; } - return 0; + return CMD_INVALID_STATUS; } int b3GetStatusBodyIndex(b3SharedMemoryStatusHandle statusHandle) diff --git a/examples/SharedMemory/PhysicsClientSharedMemory.cpp b/examples/SharedMemory/PhysicsClientSharedMemory.cpp index 35d7d8227..65c22cdf5 100644 --- a/examples/SharedMemory/PhysicsClientSharedMemory.cpp +++ b/examples/SharedMemory/PhysicsClientSharedMemory.cpp @@ -23,6 +23,7 @@ struct BodyJointInfoCache struct PhysicsClientSharedMemoryInternalData { SharedMemoryInterface* m_sharedMemory; + bool m_ownsSharedMemory; SharedMemoryBlock* m_testBlock1; btHashMap m_bodyJointMap; @@ -43,6 +44,7 @@ struct PhysicsClientSharedMemoryInternalData { PhysicsClientSharedMemoryInternalData() : m_sharedMemory(0), + m_ownsSharedMemory(false), m_testBlock1(0), m_counter(0), m_serverLoadUrdfOK(false), @@ -95,23 +97,40 @@ PhysicsClientSharedMemory::PhysicsClientSharedMemory() #else m_data->m_sharedMemory = new PosixSharedMemory(); #endif + m_data->m_ownsSharedMemory = true; + } PhysicsClientSharedMemory::~PhysicsClientSharedMemory() { if (m_data->m_isConnected) { disconnectSharedMemory(); } - delete m_data->m_sharedMemory; + if (m_data->m_ownsSharedMemory) + { + delete m_data->m_sharedMemory; + } delete m_data; } void PhysicsClientSharedMemory::setSharedMemoryKey(int key) { m_data->m_sharedMemoryKey = key; } + +void PhysicsClientSharedMemory::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 PhysicsClientSharedMemory::disconnectSharedMemory() { - if (m_data->m_isConnected) { + 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; } + m_data->m_isConnected = false; + } bool PhysicsClientSharedMemory::isConnected() const { return m_data->m_isConnected; } @@ -146,13 +165,20 @@ const SharedMemoryStatus* PhysicsClientSharedMemory::processServerStatus() { SharedMemoryStatus* stat = 0; if (!m_data->m_testBlock1) { - return 0; + m_data->m_lastServerStatus.m_type = CMD_SHARED_MEMORY_NOT_INITIALIZED; + return &m_data->m_lastServerStatus; } if (!m_data->m_waitingForServer) { return 0; } + 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; + } + if (m_data->m_testBlock1->m_numServerCommands > m_data->m_testBlock1->m_numProcessedServerCommands) { btAssert(m_data->m_testBlock1->m_numServerCommands == @@ -446,7 +472,6 @@ bool PhysicsClientSharedMemory::submitClientCommand(const SharedMemoryCommand& c /// at the moment we allow a maximum of 1 outstanding command, so we check for this // once the server processed the command and returns a status, we clear the flag // "m_data->m_waitingForServer" and allow submitting the next command - btAssert(!m_data->m_waitingForServer); if (!m_data->m_waitingForServer) { if (&m_data->m_testBlock1->m_clientCommands[0] != &command) { diff --git a/examples/SharedMemory/PhysicsClientSharedMemory.h b/examples/SharedMemory/PhysicsClientSharedMemory.h index 05a4173db..c93f9c493 100644 --- a/examples/SharedMemory/PhysicsClientSharedMemory.h +++ b/examples/SharedMemory/PhysicsClientSharedMemory.h @@ -10,6 +10,8 @@ class PhysicsClientSharedMemory : public PhysicsClient { struct PhysicsClientSharedMemoryInternalData* m_data; protected: + virtual void setSharedMemoryInterface(class SharedMemoryInterface* sharedMem); + public: PhysicsClientSharedMemory(); virtual ~PhysicsClientSharedMemory(); diff --git a/examples/SharedMemory/PhysicsServerExample.cpp b/examples/SharedMemory/PhysicsServerExample.cpp index 8f7df0c5a..5be53767f 100644 --- a/examples/SharedMemory/PhysicsServerExample.cpp +++ b/examples/SharedMemory/PhysicsServerExample.cpp @@ -22,7 +22,7 @@ class PhysicsServerExample : public SharedMemoryCommon public: - PhysicsServerExample(GUIHelperInterface* helper); + PhysicsServerExample(GUIHelperInterface* helper, SharedMemoryInterface* sharedMem=0); virtual ~PhysicsServerExample(); @@ -133,8 +133,9 @@ public: }; -PhysicsServerExample::PhysicsServerExample(GUIHelperInterface* helper) +PhysicsServerExample::PhysicsServerExample(GUIHelperInterface* helper, SharedMemoryInterface* sharedMem) :SharedMemoryCommon(helper), +m_physicsServer(sharedMem), m_wantsShutdown(false), m_isConnected(false), m_replay(false) @@ -287,7 +288,7 @@ extern int gSharedMemoryKey; class CommonExampleInterface* PhysicsServerCreateFunc(struct CommonExampleOptions& options) { - PhysicsServerExample* example = new PhysicsServerExample(options.m_guiHelper); + PhysicsServerExample* example = new PhysicsServerExample(options.m_guiHelper, options.m_sharedMem); if (gSharedMemoryKey>=0) { example->setSharedMemoryKey(gSharedMemoryKey); diff --git a/examples/SharedMemory/PhysicsServerSharedMemory.cpp b/examples/SharedMemory/PhysicsServerSharedMemory.cpp index a00f3d1ae..a19e9904a 100644 --- a/examples/SharedMemory/PhysicsServerSharedMemory.cpp +++ b/examples/SharedMemory/PhysicsServerSharedMemory.cpp @@ -23,6 +23,8 @@ struct PhysicsServerSharedMemoryInternalData SharedMemoryInterface* m_sharedMemory; + bool m_ownsSharedMemory; + SharedMemoryBlock* m_testBlock1; int m_sharedMemoryKey; bool m_isConnected; @@ -31,6 +33,7 @@ struct PhysicsServerSharedMemoryInternalData PhysicsServerSharedMemoryInternalData() :m_sharedMemory(0), + m_ownsSharedMemory(false), m_testBlock1(0), m_sharedMemoryKey(SHARED_MEMORY_KEY), m_isConnected(false), @@ -57,16 +60,23 @@ struct PhysicsServerSharedMemoryInternalData }; -PhysicsServerSharedMemory::PhysicsServerSharedMemory() +PhysicsServerSharedMemory::PhysicsServerSharedMemory(SharedMemoryInterface* sharedMem) { m_data = new PhysicsServerSharedMemoryInternalData(); - + if (sharedMem) + { + m_data->m_sharedMemory = sharedMem; + m_data->m_ownsSharedMemory = false; + } else + { #ifdef _WIN32 m_data->m_sharedMemory = new Win32SharedMemoryServer(); #else m_data->m_sharedMemory = new PosixSharedMemory(); #endif - + m_data->m_ownsSharedMemory = true; + } + m_data->m_commandProcessor = new PhysicsServerCommandProcessor; m_data->m_commandProcessor ->createEmptyDynamicsWorld(); @@ -176,7 +186,10 @@ void PhysicsServerSharedMemory::disconnectSharedMemory(bool deInitializeSharedMe { b3Printf("m_sharedMemory\n"); } - delete m_data->m_sharedMemory; + if (m_data->m_ownsSharedMemory) + { + delete m_data->m_sharedMemory; + } m_data->m_sharedMemory = 0; m_data->m_testBlock1 = 0; } @@ -209,7 +222,10 @@ void PhysicsServerSharedMemory::releaseSharedMemory() { b3Printf("m_sharedMemory\n"); } - delete m_data->m_sharedMemory; + if (m_data->m_ownsSharedMemory) + { + delete m_data->m_sharedMemory; + } m_data->m_sharedMemory = 0; m_data->m_testBlock1 = 0; } diff --git a/examples/SharedMemory/PhysicsServerSharedMemory.h b/examples/SharedMemory/PhysicsServerSharedMemory.h index 7547bd991..3db5ff497 100644 --- a/examples/SharedMemory/PhysicsServerSharedMemory.h +++ b/examples/SharedMemory/PhysicsServerSharedMemory.h @@ -14,7 +14,7 @@ protected: public: - PhysicsServerSharedMemory(); + PhysicsServerSharedMemory(class SharedMemoryInterface* sharedMem=0); virtual ~PhysicsServerSharedMemory(); virtual void setSharedMemoryKey(int key); diff --git a/examples/SharedMemory/SharedMemoryInProcessPhysicsC_API.cpp b/examples/SharedMemory/SharedMemoryInProcessPhysicsC_API.cpp index ee00f5b34..58c161ee4 100644 --- a/examples/SharedMemory/SharedMemoryInProcessPhysicsC_API.cpp +++ b/examples/SharedMemory/SharedMemoryInProcessPhysicsC_API.cpp @@ -21,10 +21,14 @@ public: newargv[argc] = t0; newargv[argc+1] = t1; m_data = btCreateInProcessExampleBrowser(newargc,newargv); + SharedMemoryInterface* shMem = btGetSharedMemoryInterface(m_data); + + setSharedMemoryInterface(shMem); } virtual ~InProcessPhysicsClientSharedMemory() { + setSharedMemoryInterface(0); btShutDownExampleBrowser(m_data); } diff --git a/examples/SharedMemory/SharedMemoryPublic.h b/examples/SharedMemory/SharedMemoryPublic.h index 789bfbc76..6002c565b 100644 --- a/examples/SharedMemory/SharedMemoryPublic.h +++ b/examples/SharedMemory/SharedMemoryPublic.h @@ -30,7 +30,6 @@ enum EnumSharedMemoryServerStatus { CMD_SHARED_MEMORY_NOT_INITIALIZED=0, CMD_WAITING_FOR_CLIENT_COMMAND, - //CMD_CLIENT_COMMAND_COMPLETED is a generic 'completed' status that doesn't need special handling on the client CMD_CLIENT_COMMAND_COMPLETED, //the server will skip unknown command and report a status 'CMD_UNKNOWN_COMMAND_FLUSHED' @@ -50,6 +49,7 @@ enum EnumSharedMemoryServerStatus CMD_DESIRED_STATE_RECEIVED_COMPLETED, CMD_STEP_FORWARD_SIMULATION_COMPLETED, CMD_RESET_SIMULATION_COMPLETED, + CMD_INVALID_STATUS, CMD_MAX_SERVER_COMMANDS }; diff --git a/examples/SharedMemory/premake4.lua b/examples/SharedMemory/premake4.lua index 5882257b0..169849f53 100644 --- a/examples/SharedMemory/premake4.lua +++ b/examples/SharedMemory/premake4.lua @@ -29,6 +29,7 @@ files { "PhysicsServer.cpp", "PosixSharedMemory.cpp", "Win32SharedMemory.cpp", + "InProcessMemory.cpp", "PhysicsDirect.cpp", "PhysicsDirect.h", "PhysicsDirectC_API.cpp", diff --git a/test/SharedMemory/test.c b/test/SharedMemory/test.c index 4b23d6b3f..f45d67840 100644 --- a/test/SharedMemory/test.c +++ b/test/SharedMemory/test.c @@ -66,6 +66,7 @@ int main(int argc, char* argv[]) { b3SharedMemoryStatusHandle statusHandle; + int statusType; b3SharedMemoryCommandHandle command = b3LoadUrdfCommandInit(sm, urdfFileName); //setting the initial position, orientation and other arguments are optional @@ -74,6 +75,11 @@ int main(int argc, char* argv[]) startPosZ = 1; ret = b3LoadUrdfCommandSetStartPosition(command, startPosX,startPosY,startPosZ); statusHandle = b3SubmitClientCommandAndWaitStatus(sm, command); + statusType = b3GetStatusType(statusHandle); + if (statusType != CMD_URDF_LOADING_COMPLETED) + { + printf("Loading URDF failed, status type = %d\n",statusType); + } bodyIndex = b3GetStatusBodyIndex(statusHandle); } @@ -169,7 +175,16 @@ int main(int argc, char* argv[]) ///perform some simulation steps for testing for ( i=0;i<100;i++) { - b3SubmitClientCommandAndWaitStatus(sm, b3InitStepSimulationCommand(sm)); + b3SharedMemoryStatusHandle statusHandle; + int statusType; + + statusHandle = b3SubmitClientCommandAndWaitStatus(sm, b3InitStepSimulationCommand(sm)); + statusType = b3GetStatusType(statusHandle); + if (statusType != CMD_STEP_FORWARD_SIMULATION_COMPLETED) + { + printf("Step Simulation failed, Unexpected status type = %d\n",statusType); + break; + } } {