Jump to content
  • Advertisement
Sign in to follow this  
Sphet

[.net] C# UI with C++ Scene graph (Updated)

This topic is 3778 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello, I am starting from scratch on a new GUI application that will leverage a large C++ code base. I have a collection of objects in a C++ scene graph and I would like to make it available for visualization in a C# ui. It is, of course, a level editor. The scene graph in C++ is an abstract interface:
class CLASS_DECLSPEC IGraphNode
{
public:
	virtual ~IGraphNode() { }

	virtual const char* GetName() const;

private:
	// ...
};


I currently have a testbed with a Managed C++ wrapper like this:
public ref class WrapNode
{
public:
	WrapNode();
	~WrapNode();

private:
	IGraphNode*			node;
};


So when nodes are created in the scene graph from XML, all done in C++, the C# can get the objects, but it gets them as Wrapped Nodes. My problem is how do I managed lifespan between IGraphNodes and WrapNodes? What if an IGraphNode goes out of scope (deleted), how do I delete the corresponding WrapNode()? Can I somehow store a pointer to the WrapNode inside my IGraphNode? Not sure how do that given it is managed. I'm really new to this whole C# thing and would like to make it work, but I am not sure where the line is drawn and how to manage this kind of thing. Any examples, thoughts or musings on this would be great. [Edited by - Sphet on July 18, 2008 3:44:27 PM]

Share this post


Link to post
Share on other sites
Advertisement
You shouldn't really need to worry about this, as long as your WrapNode class free's it's IGraphNode.

As WrapNode is managed (C#), the .NET garbage collector will delete it when it's no longer any references to it.

Hope this helped, post back if you need.

Share this post


Link to post
Share on other sites
Quote:
Original post by beebs1
You shouldn't really need to worry about this, as long as your WrapNode class free's it's IGraphNode.

As WrapNode is managed (C#), the .NET garbage collector will delete it when it's no longer any references to it.

Hope this helped, post back if you need.


You don't need to worry about it PROVIDED the WrapNode "owns" the IGraphNode, and is the only one who can delete it. If someone else can delete the IGraphNode, then you'll need an alternate solution (smart/shared pointers would probably be the easiest).

Share this post


Link to post
Share on other sites
Quote:
Original post by beebs1
You shouldn't really need to worry about this, as long as your WrapNode class free's it's IGraphNode.

As WrapNode is managed (C#), the .NET garbage collector will delete it when it's no longer any references to it.

Hope this helped, post back if you need.



Well, that's my question.

If I have a WrapNode that internally poitns to an IGraphNode, how do I remove the reference to the WrapNode if the IGraphNode is deleted, but from within the C++ code?

Share this post


Link to post
Share on other sites
Quote:
Original post by emeyex
Quote:
Original post by beebs1
You shouldn't really need to worry about this, as long as your WrapNode class free's it's IGraphNode.

As WrapNode is managed (C#), the .NET garbage collector will delete it when it's no longer any references to it.

Hope this helped, post back if you need.


You don't need to worry about it PROVIDED the WrapNode "owns" the IGraphNode, and is the only one who can delete it. If someone else can delete the IGraphNode, then you'll need an alternate solution (smart/shared pointers would probably be the easiest).


Thanks - that's a good answer. Unfortunately, I have to assume that the WrapNode does NOT own the object, at least, I think I do.

I can't imagine getting away with the C++ code not destroying nodes.

Maybe my over-all architecture will work out if I do more design work, but I just don't see how to do it given that the scene graph is in C++ but I want to be able to extract properties from nodes and edit them in C#, show the selection set, etc.

I guess I could make some kind of scene-graph-iterator which can be used by C# to walk the current selection set, or the whole tree, or what have you and can be invalidated if an object is added or removed from the scene.

Here is my breakdown:

C++: Scene Graph, Scene Object Plugins ( entities, physics, lights ), Serialization, Rendering, property server, Hit Testing, Transform Modification, drag-to-parent, drag-to-link, drag-to-signal/slot
C#: Menus, docking window swith information, representation of scenegraph, buttons to create/destroy objects, Scene Object property views (plug-able).

so in there I need an interface in managed C++, or maybe Swig, whichever is easiest I guess.


S


Share this post


Link to post
Share on other sites
Do you "have" to use C#? Others' experiences may be different, but I've found that it can be a real pain (especially for maintenance) to wrap a large C++ code base and expose it to C#... requires lots of essentially duplicated glue code. I'm personally a bigger fan of using a C++-based gui toolkit (I'm using wxWidgets) to do my GUI work, so that I don't need an extra glue layer... It all depends though on how you go about it, if you can keep your points-of-contact between C# and C++ few, then it shouldn't be too bad to write a managed CLI wrapper for your C++.

That said, I love C#, and it's great for GUIs... so if you can find a good way to make it work, all the better.

Share this post


Link to post
Share on other sites
Quote:
Original post by emeyex
Do you "have" to use C#? Others' experiences may be different, but I've found that it can be a real pain (especially for maintenance) to wrap a large C++ code base and expose it to C#... requires lots of essentially duplicated glue code. I'm personally a bigger fan of using a C++-based gui toolkit (I'm using wxWidgets) to do my GUI work, so that I don't need an extra glue layer... It all depends though on how you go about it, if you can keep your points-of-contact between C# and C++ few, then it shouldn't be too bad to write a managed CLI wrapper for your C++.

That said, I love C#, and it's great for GUIs... so if you can find a good way to make it work, all the better.


I appreciate your ideas and to be honest, were I the only one in using the codebase, I would write the whole thing in C++ using MFC.

Unfortunately, people already feel stopping game programming to write UI code is a big enough pain, so I am trying to lower the barrier of entry by using C# and a couple of UI frameworks out there. Our goal is to develop the toolset into a framework so game-programmers can essentially write simple plugins either to the scenegraph or to the UI components, depending on what they need to do.

It's a good point though.

Share this post


Link to post
Share on other sites
You cannot really remove the WrapNode, but you could set its state to deleted or something as soon as IGraphNode's destructor is called. And yes, you can have managed members in an unmanaged type:


#include <vcclr.h>

ref class MyManagedClass;
class MyUnmanagedClass
{
gcroot<MyManagedClass^> myManagedObject; // Same behavior as a simple MyManagedClass^.
};

Share this post


Link to post
Share on other sites
Quote:
Original post by Expandable
You cannot really remove the WrapNode, but you could set its state to deleted or something as soon as IGraphNode's destructor is called. And yes, you can have managed members in an unmanaged type:


#include <vcclr.h>

ref class MyManagedClass;
class MyUnmanagedClass
{
gcroot<MyManagedClass^> myManagedObject; // Same behavior as a simple MyManagedClass^.
};



Thanks for that. I think I'll spend the day trying out some samples and seeing what works. I'll post my findings here.

Share this post


Link to post
Share on other sites
So,

I've done some testing and some thinking and I believe the right way to go is this:

- Write my scene graph in CLI/C++ (I think).
- Each node in the scene graph (ISceneNode) hold a pointer to the object at that node in the graph (ISceneObject), defined in CLI/C++.
- A concrete implementation of ISceneObject in the CLI/C++ and is essentially a container for native objects (SceneModelObject, SceneLightObject).
- Additionally, concrete implementations of ISceneObject can be created in C# for trivial objects, whereby their OnRenderObject() function uses a CLI/C++ ISimpleRenderer for rendering lines and boxes and such using the native C++ renderer.

All properties will be managed using C# or CLI/C++ properties employing the TypeDescriptionProvider/CustomTypeDescriptor classes for publishing.

Hit testing will be done in C# but ISceneObjects can implement their hit testing in either C#, CLI/C++ or native C++.

Right now my Assembly Dependency looks like this:

C# -> CLI/C++ -> C++

If I define a class in C# that is needed in CLI/C++, which in turn defines classes needed in C#, how do you avoid the circular references?

Thoughts??

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!