1

我正在为需要通过 openFrameworks 运行各种程序的背景的表演艺术家开发一个程序。他需要一种能够以某种方式在它们之间轻松切换的方法。是否有某种方法可以创建加载或卸载其他 openframeworks 文件的主 shell?

4

1 回答 1

5

如果您有办法从客户端终止 RunApp()(通过退出按钮),您可以通过 tcl 或 python 将调用包装在脚本语言中。您最终将获得一个交互式外壳,您可以在其中运行不同的应用程序并设置参数。

为了简单起见,我将省略一些细节并假设我们使用 boost::python 进行语言绑定。这篇文章有更详细的阅读,boost::python 文档在这里

主要思想是为 OF 创建一个领域特定的语言/一组包装器,可用于创建 OF 对象并通过 shell脚本以交互方式访问它们的方法。

Boost 对象绑定大致像这样工作(引自1):

首先在C++中定义类

struct World
{
    void set(std::string msg) { this->msg = msg; }
    std::string greet() { return msg; }
    std::string msg;
};

然后,将其公开为 python-module

#include <boost/python.hpp>
BOOST_PYTHON_MODULE(hello)
{
    class_<World>("World")
      .def("greet", &World::greet)
      .def("set", &World::set)
    ;
}

在交互式 python 会话中使用如下所示:

>>> import hello
>>> planet = hello.World()
>>> planet.set('howdy')
>>> planet.greet()
'howdy'

现在,由于可以包装任何类或方法,因此在如何实际利用 OF 方面有很多可能性。我在这个答案中指的是有两个应用程序,App1App2C++/OF 实现,然后在 python 中链接到该实现。

交互式会话看起来像这样:

>>> import myofapps
>>> a1 = myofapps.App1()
>>> a2 = myofapps.App2()
>>> a1.run() # blocked here, until the app terminates
>>> a2.run() # then start next app .. and so forth
>>> a1.run()

我不是 OF 黑客,但另一种(更简单)的可能性可能是交互式更改ofApp::draw()应用程序中 fe 的内容(在线程中运行)。这可以通过在 python 解释器中嵌入一个可参数化的自定义对象来完成:

/// custom configurator class

class MyObj {
   private int colorRed;

   // getter
   int getRed () {
      return colorRed;
   }

   // setter
   void setRed(int r) {
      colorRed = r;
   }

   /// more getters/setters code
   ...
};

/// the boost wrapping code (see top of post)
...

/// OF code here

void testApp::draw() {

    // grab a reference to MyObj (there are multiple ways to do that)
    // let's assume there's a singleton which holds the reference to it
    MyObj o = singleton.getMyObj();

    // grab values
    int red = o.getRed ();

    // configure color
    ofSetColor(red,0,0,100);

    // other OF drawing code here...
}

一旦 OF 应用程序运行,可用于在解释器中以交互方式更改颜色:

>>> import myofapps
>>> a1 = myofapps.App1()
>>> c1 = myofapps.MyObj();
>>> a1.run() # this call would have to be made non-blocking by running the 
>>>          # app in a thread and returning right away
>>> c1.setRed(100);

... after a minute set color to a different value

>>>> c1.setRed(200);
于 2012-09-20T20:15:27.600 回答