Recently I learned C ++/CLI and wrote some gadgets to experience its power. Yesterday I started planning to simulate the previous pipe bending machine. Program Rewrite with C ++/CLI.
The basic idea is to roughly separate the underlying 3D part from the upper GUI part. The most primitive method is to write a C ++ class, define some interfaces, and then write
Wrapper, and then use C # For calling. This method is not very good, it adds a lot of work, and there are inevitably a lot of repetitive assignments when writing wrapper Code .
The second approach is to directly use C ++/CLI to start writing, and combine native and managed parts for writing. Of course, C ++/CLI has some limitations and cannot be directly stored in the Managed class.
Nested unmanaged classes can only have unmanaged class pointers. OSG: ref_ptr, which is the smart pointer in openscenegraph.
Because it is a type and cannot be directly embedded into the Managed class, the syntax similar to the following is incorrect:
Ref class managedclass
{
OSG: ref_ptr <OSG: node> node;
}
Of course this is correct:
Ref class managedclass
{
OSG: node * node;
}
However, in this way, the protection of smart pointers is lost and Memory leakage is easily caused. Therefore, it is imperative to write a smart pointer instead of OSG: ref_ptr, but the function remains unchanged.
The reference classes of openscenegraph are inherited from OSG: object, while OSG: object inherits from OSG: reference. Therefore
You can use the ref () and unref () Methods of the class to increase or decrease referencecount. When referencecount is set to 0, the referencecount is automatically deleted.
Refer to OSG: ref_ptr and remove the uncommon parts of this class. Write a smart_ptr class to complete the smart pointer task: // ! Openscenegraph managed smart_ptr.
Template < Typename t >
Public Ref Class Smart_ptr
{
Public :
Typedef t element_type;
Smart_ptr (): _ PTR ( 0 ){}
Smart_ptr (T * PTR): _ PTR (PTR ){ If (_ PTR) _ PTR -> Ref ();}
Smart_ptr ( Const Smart_ptr % RP): _ PTR (RP. _ PTR ){ If (_ PTR) _ PTR -> Ref ();}
~Smart_ptr (){If(_ PTR) _ PTR->Unref (); _ PTR= 0;}
Smart_ptr % Operator = ( Const Smart_ptr % RP)
{
If (_ PTR = RP. _ PTR) Return * This ;
T * Tmp_ptr = _ PTR;
_ PTR = RP. _ PTR;
If (_ PTR) _ PTR -> Ref ();
// Unref second to prevent any deletion of any object which might
// Be referenced by the other object. I. e Rp is child of
// Original _ PTR.
If (Tmp_ptr) tmp_ptr -> Unref ();
Return * This ;
}
Inline smart_ptr % Operator = (T * PTR)
{
If (_ PTR = PTR) Return * This ;
T * Tmp_ptr = _ PTR;
_ PTR = PTR;
If (_ PTR) _ PTR -> Ref ();
// Unref second to prevent any deletion of any object which might
// Be referenced by the other object. I. e Rp is child of
// Original _ PTR.
If (Tmp_ptr) tmp_ptr -> Unref ();
Return * This ;
}
//T % operator * () {return * _ PTR ;}
T* Operator->(){Return_ PTR ;}
T* Get(){Return_ PTR ;}
Bool Operator ! (){ Return _ PTR = 0 ;} // Not Required
Bool Valid (){ Return _ PTR ! = 0 ;}
T*Release () {T*TMP=_ PTR;If(_ PTR) _ PTR->Unref_nodelete (); _ PTR=0;ReturnTMP ;}
Private:
T*_ PTR;
};
after such a tossing, you can finally use the smart pointer in the middle of the hosting class:
code highlighting produced by actipro codehighlighter (freeware)
http://www.CodeHighlighter.com/
--> Public ref class scene
{< br> protected :
smart_ptr OSG :: graphicscontext > GC;
smart_ptr OSG :: group > root;
smart_ptr osgviewer :: viewer > viewer;
smart_ptr OSG :: camera > camera;
.
}
There are still many problems to be solved after the obstacles of smart pointers are crossed. Common classes such as OSG: vec3 can only be rewritten for calling. Functions such as searching for a node findnode: Ref Class Nodefound
{
Public :
String ^ Name;
Smart_ptr < OSG: Node > Osgnode;
};
Nodefound ^ Findnode (string ^ Name)
{
Findnodevisitor;
Findnodevisitor. Name = Marshalstring (name );
Root -> Accept (findnodevisitor );
If (Findnodevisitor. Node = Null) Throw Gcnew exceptions: nodenotfoundexpection ();
nodefound ^ nodefound = gcnew nodefound ();
nodefound -> name = name;
nodefound -> osgnode = findnodevisitor. node;
return nodefound;
ReturnNullptr;
}
Only one new structure can be defined as the return value. Otherwise, the C # language cannot be used because it cannot resolve a smart pointer .~~~ Maybe there are other methods that can be used, such as intptr, but it may be out of the Protection of smart pointers and become dangerous.
Continue Learning ~