How I got IronPython scripting to run in C++/cli

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

How I got IronPython scripting to run in C++/cli

Lee-124

It seems like such a simple set of code now ... but when I was banging my head trying to get it to work, well, that is a different story.

 

This function is called after FastCAD (the engine under the hood of profantasy’s Campaign Cartographer 3) runs a method that asks the user for a script file (PythonCmd).  FastCAD places the name of the file in txtFileName as a char[].

 

All the SetVariables setup C++/cli classes that I use to expose FastCADs API.  From here I work through delegates so that I never have to discover functions in IronPython.  I could not figure out how to do that in C++/cli 3.5.  It seems easy in 4.0 with the dynamic type, but Campaign Cartographer 3s installer currently only loads the C++ 3.5 runtimes.

 

///////////////////////////////////////////////////////////////////////

void XPCALL PythonCmd2(int Result, int Result1, int Result2) {

      if(Result==X_OK)

      {

            try

            {

                  String^ filename = gcnew String(txtFileName);

                  String^ path = Assembly::GetExecutingAssembly()->Location;

                  ScriptEngine^ engine = Python::CreateEngine();

                  ScriptScope^ scope = engine->CreateScope();

                  ScriptSource^ source = engine->CreateScriptSourceFromFile(String::Concat(Path::GetDirectoryName(path), "<a href="file:///\\scripts\">\\scripts\\", filename + ".py"));

                 

                  scope->SetVariable("DrawingList", DynamicHelpers::GetPythonTypeFromType(AddIn::DrawingList::typeid));

                  scope->SetVariable("DrawingElement", DynamicHelpers::GetPythonTypeFromType(AddIn::DrawingElement::typeid));

                  scope->SetVariable("DrawingPath", DynamicHelpers::GetPythonTypeFromType(AddIn::DrawingPath::typeid));

                  scope->SetVariable("Node", DynamicHelpers::GetPythonTypeFromType(AddIn::Node::typeid));

 

                  source->Execute(scope);

            }

            catch(Exception ^e)

            {

                  Console::WriteLine(e->ToString());

                  CmdEnd();

            }

      }

      else

      {

            CmdEnd();

      }

}

///////////////////////////////////////////////////////////////////////////////

 

Here is an example ipy script that draws a diamond at the selected point.

 

When the C++/cli soure->Execute(scope) line is called, the only python line to run is the DrawingList.RequestData.

 

RequestData takes a delegate and a data type.

When the C++/cli code is done, it calls the delegate pointing to the function "diamond"

In the function diamond it retrieves the requested data with the call to DrawingList.RequestedValue() The call to DrawingList.AddElement(dp) adds the new element to the FastCAD visual Database.

And lastly the call to DrawingList.EndCommand() tells the FastCAD engine to clean up and end the running of the plugin.

 

import clr

 

def diamond(Result1, Result2, Result3):

  if(Result1 == 0):

    dp = DrawingPath()

 

    dp.drawingStuff.EntityColor = 2

    dp.drawingStuff.SecondEntityColor = 2

 

    n = DrawingList.RequestedValue()

 

    dp.Nodes.Add(Node(n.X-50,n.Y+25))

    dp.Nodes.Add(Node(n.X-25,n.Y+50))

    dp.Nodes.Add(Node(n.X+25,n.Y+50))

    dp.Nodes.Add(Node(n.X+50,n.Y+25))

    dp.Nodes.Add(Node(n.X,n.Y-40))

 

    DrawingList.AddElement(dp)

 

  DrawingList.EndCommand()

 

DrawingList.RequestData(diamond, DrawingList.RequestType.PointType)

 

 

 


_______________________________________________
Users mailing list
[hidden email]
http://lists.ironpython.com/listinfo.cgi/users-ironpython.com