1/*
2 * Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
3 *
4 * NVIDIA CORPORATION and its licensors retain all intellectual property
5 * and proprietary rights in and to this software, related documentation
6 * and any modifications thereto. Any use, reproduction, disclosure or
7 * distribution of this software and related documentation without an express
8 * license agreement from NVIDIA CORPORATION is strictly prohibited.
9 */
10#ifndef PVD_CONNECTION_MANAGER_H
11#define PVD_CONNECTION_MANAGER_H
12
13#include "physxvisualdebuggersdk/PvdConnectionFlags.h"
14#include "physxvisualdebuggersdk/PvdNetworkStreams.h"
15#include "physxvisualdebuggersdk/PvdConnection.h"
16#include "foundation/PxErrors.h"
17
18namespace physx {
19 class PxProfileZoneManager;
20}
21
22namespace physx { namespace debugger {
23
24 class PvdNetworkInStream;
25 class PvdNetworkOutStream;
26 struct PvdColor;
27 typedef const char* String;
28}}
29
30namespace physx { namespace debugger { namespace comm {
31
32 /**
33 * When PVD is connected two callbacks happen. This avoids conditions
34 * where a handler tries to initiate sending objects from another
35 * handler on its OnConnection but the first handler hasn't had an
36 * opportunity to send its class descriptions.
37 * The callbacks happen in this order:
38 * onSendClassDescriptions
39 * onPvdConnected
40 * onPvdDisconnected
41 */
42 //
43 //
44 class PvdConnectionHandler
45 {
46 protected:
47 virtual ~PvdConnectionHandler(){}
48 public:
49 virtual void onPvdSendClassDescriptions( PvdConnection& connection ) = 0;
50 virtual void onPvdConnected( PvdConnection& connection ) = 0;
51 virtual void onPvdDisconnected( PvdConnection& connection ) = 0;
52 };
53
54 /**
55 * The connection factory manager provides ways of managing a single PVD connection.
56 * Clients can be notified when the connection is created and can setup a policy
57 * for dealing with the incoming data from the PVD application if there is any.
58 *
59 * The default data provider uses a thread that does a block read on the incoming
60 * connection stream. If you would like to do something else you will need first
61 * implement you own network abstraction as the physx networking layers don't work
62 * in non-blocking mode on platforms other than windows (and they only partially work
63 * in non-blocking mode on windows).
64 */
65 class PvdConnectionManager
66 {
67 protected:
68 virtual ~PvdConnectionManager(){}
69 public:
70 /**
71 * Set the profile zone manager. This takes care of ensuring that all profiling
72 * events get forwarded to PVD.
73 */
74 virtual void setProfileZoneManager( physx::PxProfileZoneManager& inManager ) = 0;
75
76 //These will automatically get called on an active connection
77 //so you don't need to worry about it.
78 virtual void setPickable( const void* instance, bool pickable ) = 0;
79 virtual void setColor( const void* instance, const PvdColor& color ) = 0;
80 virtual void setCamera( String name, const PxVec3& position, const PxVec3& up, const PxVec3& target ) = 0;
81
82 //Send error message to PVD
83 virtual void sendErrorMessage(PxErrorCode::Enum code, String message, String file, PxU32 line) = 0;
84
85 //Is top level indicates that this object will be shown at the root of the object graph
86 //in the AllObjects display. The only object this should be set for would be the
87 //PhysX SDK object. All other objects this should be false.
88 virtual void setIsTopLevelUIElement( const void* instance, bool isTopLevel ) = 0;
89
90 /*
91 send a stream end event to pvd, pvd will do disconnect and store data when received this event.
92 */
93 virtual void sendStreamEnd() = 0;
94
95 /**
96 * Handler will be notified every time there is a new connection.
97 */
98 virtual void addHandler( PvdConnectionHandler& inHandler ) = 0;
99 /**
100 * Handler will be notified when a connection is destroyed.
101 */
102 virtual void removeHandler( PvdConnectionHandler& inHandler ) = 0;
103 /**
104 * Create a new PvdConnection and returns the interface with an extra reference.
105 *
106 * The connection type is static and can't change once the system starts.
107 * Not that something could have disconnected by the time this function returned.
108 * Such behavior would probably crash but it could happen. User need to release
109 * the returned interface after using it.
110 */
111 virtual PvdConnection* connectAddRef( PvdNetworkInStream* inInStream
112 , PvdNetworkOutStream& inOutStream
113 , TConnectionFlagsType inConnectionType = defaultConnectionFlags()
114 , bool doubleBuffered = true ) = 0;
115
116 void connect( PvdNetworkInStream* inInStream
117 , PvdNetworkOutStream& inOutStream
118 , TConnectionFlagsType inConnectionType = defaultConnectionFlags()
119 , bool doubleBuffered = true )
120 {
121 PvdConnection* theConnection = connectAddRef( inInStream, inOutStream, inConnectionType, doubleBuffered );
122 if ( NULL != theConnection )
123 theConnection->release();
124 }
125
126 //connect to PVD over the network
127 void connect( PxAllocatorCallback& allocator
128 , const char* inHost
129 , int inPort
130 , unsigned int inTimeoutInMilliseconds
131 , TConnectionFlagsType inConnectionType = defaultConnectionFlags()
132 , bool doubleBuffered = true )
133 {
134 PvdNetworkInStream* theInStream;
135 PvdNetworkOutStream* theOutStream;
136 if ( PvdNetworkStreams::connect( allocator, inHost, inPort, inTimeoutInMilliseconds, theInStream, theOutStream ) )
137 connect( theInStream, *theOutStream, inConnectionType, doubleBuffered );
138 }
139
140 //connect to PVD over the filesystem
141 void connect( PxAllocatorCallback& allocator,
142 const char* inFilename
143 , TConnectionFlagsType inConnectionType = defaultConnectionFlags()
144 , bool doubleBuffered = true)
145 {
146 PvdNetworkOutStream* fileStream = PvdNetworkOutStream::createFromFile( allocator, inFilename );
147 if ( fileStream )
148 connect( NULL, *fileStream, inConnectionType, doubleBuffered );
149 }
150
151 /**
152 * Return the object representing the current connection to PVD, if any.
153 * You need to call release on the connection after this call. This is because
154 * ...
155 * The manager releases its reference to the connection when something causes
156 * the connection to disconnect. This doesn't necessarily happen in this thread.
157 * So in order to return a connection and be sure it isn't returning a dangling pointer
158 * because another thread caused a disconnect (like because the read thread noticed
159 * the socket is dead), this object addrefs the connection if possible and the returns
160 * it. So, callers of this function need to release the (possibly disconnected connection)
161 * if they got one.
162 */
163 virtual PvdConnection* getAndAddRefCurrentConnection() = 0;
164 /**
165 * For the reasons stated above, querying isConnected is an atomic
166 * operation.
167 */
168 virtual bool isConnected() = 0;
169
170 /**
171 * If there is a current connection, disconnect from the factory.
172 */
173 virtual void disconnect() = 0;
174
175 virtual void release() = 0;
176
177 static PvdConnectionManager& create( PxAllocatorCallback& allocator, PxAllocatorCallback& nonBroadcastingAlloc, bool trackMemoryEvents = true );
178 };
179
180}}
181
182/** \brief Convenience typedef for the PvdConnectionHandler. */
183typedef debugger::comm::PvdConnectionHandler PxVisualDebuggerConnectionHandler;
184
185/** \brief Convenience typedef for the PvdConnectionManager. */
186typedef debugger::comm::PvdConnectionManager PxVisualDebuggerConnectionManager;
187}
188
189#endif
190