如何通过swig从ruby运行C线程

时间:2014-05-08 13:53:29

标签: c ruby opengl pthreads swig

我只是为了好玩,试图在openGL的帮助下制作一个小游戏引擎,我希望它是纯粹的C,但我想用红宝石编写游戏脚本。 所以我做了一个概念证明,知道它是否可能。它似乎还可以,但不完全。

实际上,我有一个用swig包装的C模块,并由ruby脚本加载。 在这个C模块中,我使用包含glutmainloop()的pthread_create()创建一个线程。 这个循环只是加载一个网格绘制它并使它以我们称之为rot_speed的速度转动。

因为我不希望我的ruby等待C互斥锁被解锁,所以我的ruby运行C函数,它创建的线程会改变主循环的某些值(因此它完全是ASYNC)然后就会死掉。< / p>

这是C代码的一部分:

mxfloat_t speed = { 
    .val = 1.0,
    .mx = PTHREAD_MUTEX_INITIALIZER,
};

mxint_t should_exit = { 
    .val = 0,
    .mx = PTHREAD_MUTEX_INITIALIZER,
};


void    engine_launch(void)
{
    pthread_t graphics;
    printf("starting gaphics thread...\n");
    pthread_create(&graphics, NULL, launch_graphics, NULL);
}

void    engine_stop(void)
{
    pthread_t stop_thread;
    printf("starting stop thread");
    pthread_create(&stop_thread, NULL, engine_stop_thread, NULL);
}

void    set_speed(float p)
{
    pthread_t speed_thread;
    printf("starting set speed thread speed= %f\n", p); 
    pthread_create(&speed_thread, NULL, set_speed_thread, &p);
}

void    *launch_graphics(void *p) 
{
    int c = 1;
    char *v = "Ex";

    printf("gaphics thread started\n");
    printf("Initializing Glut...\n");
    glutInitWindowSize(900,600);
    glutInitWindowPosition(100,100);
    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
    glutInit(&c, &v);

    printf("Creating window\n");
    glutCreateWindow("Assim p - Very simple OpenGL sample");
    printf("Assigning callbacks functions\n");
    glutDisplayFunc(display);
    glutReshapeFunc(reshape);
    glutIdleFunc(idle);

    printf("Loading asset...");
    if(loadasset( "../../test/models-nonbsd/X/dwarf.x")) { 
        printf(" ..failed\n");
        return NULL;
    }   
    printf(" ..loaded\n");

    glClearColor(0.1f,0.1f,0.1f,1.f);

    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);    // Uses default lighting parameters

    glEnable(GL_DEPTH_TEST);

    glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
    glEnable(GL_NORMALIZE);

    if(getenv("MODEL_IS_BROKEN"))  
        glFrontFace(GL_CW);

    glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);

    glutGet(GLUT_ELAPSED_TIME);
    printf("Starting main GL loop\n");
    glutMainLoop();
    printf("End of GL loop\n");
    printf("releasing imported objects\n");
    aiReleaseImport(scene);
    printf("End of the graphic thread\n");
    return NULL;

}

void    *engine_stop_thread(void* p)
{
    pthread_mutex_lock(&should_exit.mx);
    should_exit.val = 1;
    printf("should_exit has been set to 1\n");
    pthread_mutex_unlock(&should_exit.mx);
    (void)p;
    return NULL;
}

void    *set_speed_thread(void *p) 
{
    pthread_mutex_lock(&speed.mx);
    speed.val = *(float*)p;
    printf("speed has been set to %f\n", *(float*)p);
    pthread_mutex_unlock(&speed.mx);
    return NULL;
}

mxfloat_t和 mxint_t只是处理互斥锁的类型。

功能:    engine_launch()    engine_stop()和    set_speed(f),是我可以在ruby中使用的包装函数。

Idle函数是调用glutLeaveMainLoop()的函数,如果是should_exit

现在,一些红宝石代码:

require "ge"

Ge.engine_launch
sleep 1
Ge.set_speed 32.0 
sleep 1
Ge.set_speed 32.0 
sleep 1
Ge.set_speed 32.0 
sleep 1
Ge.set_speed 32.0 
sleep 1
Ge.engine_stop
sleep 1

这段代码给了我:

starting gaphics thread...
gaphics thread started
Initializing Glut...
Creating window
Assigning callbacks functions
Loading asset... ..loaded
Starting main GL loop
starting set speed thread speed= 32.000000
speed has been set to 0.000000
starting set speed thread speed= 32.000000
speed has been set to 0.000000
starting set speed thread speed= 32.000000
speed has been set to 0.000000
starting set speed thread speed= 32.000000
speed has been set to 0.000000
starting stop threadshould exit has been set to 1

但如果我在irb中测试:

irb(main):001:0> require 'ge'
=> true
irb(main):002:0> Ge.engine_launch
starting gaphics thread...
gaphics thread started
Initializing Glut...
=> nil
irb(main):003:0> Creating window
Assigning callbacks functions
Loading asset... ..loaded
Starting main GL loop
Ge.set_speed 32
starting set speed thread speed= 32.000000
speed has been set to 32.000000
=> nil
irb(main):004:0> Ge.set_speed 31
starting set speed thread speed= 31.000000
speed has been set to 31.000000
=> nil

(但是,irb似乎发送了某种强制我重置终端的termcap)

有人知道为什么在运行ruby脚本时没有设置速度值吗? 还有其他可能的方法来实现我想要做的事情吗? 感谢您的回答,这将有很大的帮助。

0 个答案:

没有答案