예제 #1
0
파일: thread.cpp 프로젝트: basecq/OpenGTA2
LockID Thread_Manager::EnterLock(int mutexID) {
#ifndef _WIN32
	ThreadID Cur = glfwGetThreadID();
	mutexNumLocks[Cur][mutexID]++;
	if(mutexNumLocks[Cur][mutexID] == 1)
	{
		glfwLockMutex(mutexLocks[mutexID]);
	}
#else
	glfwLockMutex(mutexLocks[mutexID]);
#endif
	return mutexID;
}
예제 #2
0
void lock_mutex(kiss_mutex m)
{
	if(!kiss_init())
		return;

	glfwLockMutex(m);
}
예제 #3
0
void GLFWCALL PhysicsThreadFun( void *arg )
{
    while( running )
    {
        // Lock mutex
        glfwLockMutex( thread_sync.particles_lock );

        // Wait for particle drawing to be done
        while( running && thread_sync.p_frame > thread_sync.d_frame )
        {
            glfwWaitCond( thread_sync.d_done, thread_sync.particles_lock,
                          0.1 );
        }

        // No longer running?
        if( !running )
        {
            break;
        }

        // Update particles
        ParticleEngine( thread_sync.t, thread_sync.dt );

        // Update frame counter
        thread_sync.p_frame ++;

        // Unlock mutex and signal drawing thread
        glfwUnlockMutex( thread_sync.particles_lock );
        glfwSignalCond( thread_sync.p_done );
    }
}
예제 #4
0
/* Audio_Thread::play: start playing */
void Audio_Thread::play(const char *alias, const char *file)
{
   /* check */
   if(isRunning() == false)
      return;
   if(MMDAgent_strlen(alias) <= 0 || MMDAgent_strlen(file) <= 0)
      return;

   /* wait buffer mutex */
   glfwLockMutex(m_mutex);

   /* save character name, speaking style, and text */
   if(m_alias) free(m_alias);
   if(m_file) free(m_file);
   m_alias = MMDAgent_strdup(alias);
   m_file = MMDAgent_strdup(file);
   m_count++;

   /* start playing thread */
   if(m_count <= 1)
      glfwSignalCond(m_cond);

   /* release buffer mutex */
   glfwUnlockMutex(m_mutex);
}
예제 #5
0
파일: Message.cpp 프로젝트: KTaskn/MMDAgent
/* Message::dequeueLogString: dequeue log string */
bool Message::dequeueLogString(char *log)
{
   bool result;
   glfwLockMutex(m_logStringMutex);
   result = MessageQueue_dequeue(&m_logStringQueue, log, NULL);
   glfwUnlockMutex(m_logStringMutex);
   return result;
}
예제 #6
0
파일: Message.cpp 프로젝트: KTaskn/MMDAgent
/* Message::dequeueMessage: dequeue message */
bool Message::dequeueMessage(char *type, char *value)
{
   bool result;
   glfwLockMutex(m_messageMutex);
   result = MessageQueue_dequeue(&m_messageQueue, type, value);
   glfwUnlockMutex(m_messageMutex);
   return result;
}
예제 #7
0
파일: Message.cpp 프로젝트: ljmljz/MMDAgent
/* Message::dequeueCommand: dequeue command message */
bool Message::dequeueCommand(char *type, char *value)
{
   bool result;
   glfwLockMutex(m_mutexCommand);
   result = MessageQueue_dequeue(&m_queueCommand, type, value);
   glfwUnlockMutex(m_mutexCommand);
   return result;
}
예제 #8
0
파일: Message.cpp 프로젝트: ljmljz/MMDAgent
/* Message::dequeueLog: dequeue log message */
bool Message::dequeueLog(char *log)
{
   bool result;
   glfwLockMutex(m_mutexLog);
   result = MessageQueue_dequeue(&m_queueLog, log, NULL);
   glfwUnlockMutex(m_mutexLog);
   return result;
}
예제 #9
0
파일: Message.cpp 프로젝트: ljmljz/MMDAgent
/* Message::dequeueEvent: dequeue event message */
bool Message::dequeueEvent(char *type, char *value)
{
   bool result;
   glfwLockMutex(m_mutexEvent);
   result = MessageQueue_dequeue(&m_queueEvent, type, value);
   glfwUnlockMutex(m_mutexEvent);
   return result;
}
/* Audio_Manager::run: main loop */
void Audio_Manager::run()
{
   int i;
   Audio_Link *link;
   char *buff, *save;
   char *alias, *file;

   /* create initial threads */
   for(i = 0; i < AUDIOMANAGER_INITIALNTHREAD; i++) {
      link = new Audio_Link;
      link->audio_thread.setupAndStart(m_mmdagent);
      link->next = m_list;
      m_list = link;
   }

   while(m_kill == false) {
      /* wait playing event */
      glfwLockMutex(m_mutex);
      while(m_count <= 0) {
         glfwWaitCond(m_cond, m_mutex, GLFW_INFINITY);
         if(m_kill == true)
            return;
      }
      Audio_EventQueue_dequeue(&m_bufferQueue, &buff);
      m_count--;
      glfwUnlockMutex(m_mutex);

      if(buff != NULL) {
         alias = MMDAgent_strtok(buff, "|", &save);
         file = MMDAgent_strtok(NULL, "|", &save);

         if(alias != NULL && file != NULL) {
            /* check alias */
            for(i = 0, link = m_list; link; link = link->next, i++)
               if(link->audio_thread.checkAlias(alias))
                  break;
            if(link) {
               link->audio_thread.stop(); /* if the same alias is playing, stop immediately */
            } else {
               for(i = 0, link = m_list; link; link = link->next, i++)
                  if(link->audio_thread.isRunning() && link->audio_thread.isPlaying() == false)
                     break;
               if(link == NULL) {
                  link = new Audio_Link;
                  link->audio_thread.setupAndStart(m_mmdagent);
                  link->next = m_list;
                  m_list = link;
               }
            }
            /* set */
            link->audio_thread.play(alias, file);
         }
         free(buff); /* free buffer */
      }
   }
}
예제 #11
0
Command_st PlayerInputListener::GetNextCommand()
{
	Command_st oCommand;

	glfwLockMutex(m_oInputMutex);
		// Set the inputs
		oCommand.cMoveDirection = GetMoveDirection();
		oCommand.bStealth = GetStealth();
		oCommand.fZ = m_oPlayer.GetZ() + static_cast<float>(m_dRotationAxis);		// Get the most up-to-date player Z value
	glfwUnlockMutex(m_oInputMutex);

	return oCommand;
}
예제 #12
0
void PlayerInputListener::Reset()
{
	glfwLockMutex(m_oInputMutex);

	m_dForwardAxis = 0;
	m_dStrafeAxis = 0;
	m_dRotationAxis = 0;
	m_dStealthHalfAxis = 0;

	m_WeaponChangeTEST = -1;

	glfwUnlockMutex(m_oInputMutex);
}
예제 #13
0
/* Audio_Thread::run: main thread loop for audio */
void Audio_Thread::run()
{
   Audio audio;
   char *alias, *file;
   bool lipsync;

   while (m_kill == false) {
      /* wait event */
      glfwLockMutex(m_mutex);
      while(m_count <= 0) {
         glfwWaitCond(m_cond, m_mutex, GLFW_INFINITY);
         if(m_kill == true)
            return;
      }
      alias = MMDAgent_strdup(m_alias);
      file = MMDAgent_strdup(m_file);
      m_count--;
      glfwUnlockMutex(m_mutex);

      m_playing = true;

      /* open and start audio */
      Audio_initialize(&audio);
      if(Audio_openAndStart(&audio, alias, file) == true) {

         lipsync = startLipsync(file);

         /* send SOUND_EVENT_START */
         m_mmdagent->sendMessage(AUDIOTHREAD_EVENTSTART, "%s", alias);

         /* wait to stop audio */
         Audio_waitToStop(&audio, alias, &m_playing);

         if(lipsync) stopLipsync();

         /* send SOUND_EVENT_STOP */
         m_mmdagent->sendMessage(AUDIOTHREAD_EVENTSTOP, "%s", alias);

         /* close audio file */
         Audio_close(&audio, alias);
      }

      if(alias) free(alias);
      if(file) free(file);
      Audio_clear(&audio);
      m_playing = false;
   }
}
예제 #14
0
/* checkAlias: check playing alias */
bool Audio_Thread::checkAlias(const char *alias)
{
   bool ret;

   /* check */
   if(isRunning() == false)
      return false;

   /* wait buffer mutex */
   glfwLockMutex(m_mutex);

   /* check audio alias */
   ret = MMDAgent_strequal(m_alias, alias);

   /* release buffer mutex */
   glfwUnlockMutex(m_mutex);

   return ret;
}
예제 #15
0
/* checkAlias: check playing alias */
bool Audio_Thread::checkAlias(const char *alias)
{
   bool ret;

   /* check */
   if(isRunning() == false)
      return false;

   /* wait buffer mutex */
   glfwLockMutex(m_mutex);

   /* save character name, speaking style, and text */
   ret = MMDAgent_strequal(m_alias, alias);

   /* release buffer mutex */
   glfwUnlockMutex(m_mutex);

   return ret;
}
예제 #16
0
/* Open_JTalk_Manager::synthesis: start synthesis */
void Open_JTalk_Manager::synthesis(const char *str)
{
   /* check */
   if(isRunning() == false || MMDAgent_strlen(str) <= 0)
      return;

   /* wait buffer mutex */
   glfwLockMutex(m_mutex);

   /* enqueue character name, speaking style, and text */
   Open_JTalk_EventQueue_enqueue(&m_bufferQueue, str);
   m_count++;

   /* start synthesis event */
   if(m_count <= 1)
      glfwSignalCond(m_cond);

   /* release buffer mutex */
   glfwUnlockMutex(m_mutex);
}
예제 #17
0
WpnCommand_st PlayerInputListener::GetNextWpnCommand()
{
	WpnCommand_st oWpnCommand;

	glfwLockMutex(m_oInputMutex);
		if (-1 != m_WeaponChangeTEST) oWpnCommand.nAction = WeaponSystem::CHANGE_WEAPON;
		else if (m_bWeaponReloadTEST) oWpnCommand.nAction = WeaponSystem::RELOAD;
		else if (m_bWeaponFireTEST) oWpnCommand.nAction = WeaponSystem::FIRE;
		else oWpnCommand.nAction = WeaponSystem::IDLE;
		/*oWpnCommand.fGameTime = static_cast<float>(g_pGameSession->MainTimer().GetGameTime() - (WeaponSystem::FIRE == oWpnCommand.nAction ? 15 : 0));
		if (oWpnCommand.fGameTime < 0) oWpnCommand.fGameTime += 256;//TEST
		if (oWpnCommand.fGameTime >= 256) oWpnCommand.fGameTime -= 256;//TEST*/
		oWpnCommand.dTime = g_pGameSession->MainTimer().GetTime() - (/*WeaponSystem::FIRE == oWpnCommand.nAction*/false ? 1 : 0);
		if (WeaponSystem::FIRE == oWpnCommand.nAction) oWpnCommand.Parameter.fZ = m_oPlayer.GetZ() + static_cast<float>(m_dRotationAxis);		// Get the most up-to-date player Z value
		else if (WeaponSystem::CHANGE_WEAPON == oWpnCommand.nAction) oWpnCommand.Parameter.WeaponNumber = static_cast<uint8>(m_WeaponChangeTEST);

		//m_WeaponChangeTEST = -1;
	glfwUnlockMutex(m_oInputMutex);

	return oWpnCommand;
}
/* Audio_Manager::play: start playing */
void Audio_Manager::play(const char *str)
{
   /* check */
   if(isRunning() == false)
      return;
   if(MMDAgent_strlen(str) <= 0)
      return;

   /* wait buffer mutex */
   glfwLockMutex(m_mutex);

   /* enqueue alias and file name */
   Audio_EventQueue_enqueue(&m_bufferQueue, str);
   m_count++;

   /* start playing event */
   if(m_count <= 1)
      glfwSignalCond(m_cond);

   /* release buffer mutex */
   glfwUnlockMutex(m_mutex);
}
예제 #19
0
void debugTestThreading() {
	logWrite("Testing thread creation and access to log file (and mutex locks)");
	ThreadID Thread1 = Thread.Create(debugThread_Loop,(void*)0);
	ThreadID Thread2 = Thread.Create(debugThread_Loop,(void*)1);

	Thread.WaitForThread(Thread1);
	Thread.WaitForThread(Thread2);
	logWrite("Threads completed, killing remains...");
	Thread.Kill(Thread1);
	Thread.Kill(Thread2);

	ThreadID randomThread[TEST_MAX_THREAD_NUMBER];
	logWrite("Creating and destroying %d random threads...",TEST_MAX_THREAD_NUMBER);
	for (int i = 0; i < TEST_MAX_THREAD_NUMBER; i++) {
		randomThread[i] = Thread.Create(debugThread_InfLoop,(void*)i);		
	}
	logWrite("Waiting...");
	Thread.Sleep(3.0f);
	logWrite("Killing threads...");
	for (int i = 0; i < TEST_MAX_THREAD_NUMBER; i++) {
		Thread.Kill(randomThread[i]);
	}
	logWrite("Waiting for remaining threads...");
	for (int i = 0; i < TEST_MAX_THREAD_NUMBER; i++) {
		Thread.WaitForThread(randomThread[i]);
	}

	logWrite("Found %d processors/cores",glfwGetNumberOfProcessors());

	logWrite("Creating mutex...");
	GLFWmutex mutex = glfwCreateMutex();
	logWrite("Mutex object pointer: 0x%.8X. Trying to lock and unlock",mutex);
	glfwLockMutex(mutex);
	glfwUnlockMutex(mutex);

	logWrite("Thread test passed!\n");
}
예제 #20
0
vec2_t InputSystem::MousePosition() {
	glfwLockMutex(lock);
	vec2_t result = mousePosition;
	glfwUnlockMutex(lock);
	return result;
}
예제 #21
0
void InputSystem::Update() {
	glfwLockMutex(lock);
	wantsQuit = (glfwGetKey('Q') == GLFW_PRESS);
	seconds = glfwGetTime();
	glfwUnlockMutex(lock);
}
예제 #22
0
static void OnMouseMoved(int x, int y) {
	glfwLockMutex(lock);
	mousePosition = Vec2(x, y);
	glfwUnlockMutex(lock);
}
예제 #23
0
/* Open_JTalk_Manager::run: main loop */
void Open_JTalk_Manager::run()
{
   int i;
   Open_JTalk_Link *link;
   char *buff, *save;
   char *chara, *style, *text;
   bool ret = true;

   /* create initial threads */
   for(i = 0; i < OPENJTALKMANAGER_INITIALNTHREAD; i++) {
      link = new Open_JTalk_Link;
      if(link->open_jtalk_thread.loadAndStart(m_mmdagent, m_dicDir, m_config) == false)
         ret = false;
      link->next = m_list;
      m_list = link;
   }

   if(ret == false)
      return;

   while(m_kill == false) {
      glfwLockMutex(m_mutex);
      while(m_count <= 0) {
         glfwWaitCond(m_cond, m_mutex, GLFW_INFINITY);
         if(m_kill == true)
            return;
      }
      Open_JTalk_EventQueue_dequeue(&m_bufferQueue, &buff);
      m_count--;
      glfwUnlockMutex(m_mutex);

      if(buff != NULL) {
         chara = MMDAgent_strtok(buff, "|", &save);
         style = MMDAgent_strtok(NULL, "|", &save);
         text = MMDAgent_strtok(NULL, "|", &save);

         if(chara != NULL && style != NULL && text != NULL) {
            /* check character */
            for(i = 0, link = m_list; link; link = link->next, i++)
               if(link->open_jtalk_thread.checkCharacter(chara) == true)
                  break;
            if(link) {
               if(link->open_jtalk_thread.isSpeaking() == true)
                  link->open_jtalk_thread.stop(); /* if the same character is speaking, stop immediately */
            } else {
               for(i = 0, link = m_list; link; link = link->next, i++)
                  if(link->open_jtalk_thread.isRunning() == true && link->open_jtalk_thread.isSpeaking() == false)
                     break;
               if(link == NULL) {
                  link = new Open_JTalk_Link;
                  link->open_jtalk_thread.loadAndStart(m_mmdagent, m_dicDir, m_config);
                  link->next = m_list;
                  m_list = link;
               }
            }
            /* set */
            link->open_jtalk_thread.synthesis(chara, style, text);
         }
         free(buff); /* free buffer */
      }
   }
}
예제 #24
0
void DrawParticles( double t, float dt )
{
    int       i, particle_count;
    VERTEX    vertex_array[ BATCH_PARTICLES * PARTICLE_VERTS ], *vptr;
    float     alpha;
    GLuint    rgba;
    VEC       quad_lower_left, quad_lower_right;
    GLfloat   mat[ 16 ];
    PARTICLE  *pptr;

    // Here comes the real trick with flat single primitive objects (s.c.
    // "billboards"): We must rotate the textured primitive so that it
    // always faces the viewer (is coplanar with the view-plane).
    // We:
    //   1) Create the primitive around origo (0,0,0)
    //   2) Rotate it so that it is coplanar with the view plane
    //   3) Translate it according to the particle position
    // Note that 1) and 2) is the same for all particles (done only once).

    // Get modelview matrix. We will only use the upper left 3x3 part of
    // the matrix, which represents the rotation.
    glGetFloatv( GL_MODELVIEW_MATRIX, mat );

    // 1) & 2) We do it in one swift step:
    // Although not obvious, the following six lines represent two matrix/
    // vector multiplications. The matrix is the inverse 3x3 rotation
    // matrix (i.e. the transpose of the same matrix), and the two vectors
    // represent the lower left corner of the quad, PARTICLE_SIZE/2 *
    // (-1,-1,0), and the lower right corner, PARTICLE_SIZE/2 * (1,-1,0).
    // The upper left/right corners of the quad is always the negative of
    // the opposite corners (regardless of rotation).
    quad_lower_left.x = (-PARTICLE_SIZE/2) * (mat[0] + mat[1]);
    quad_lower_left.y = (-PARTICLE_SIZE/2) * (mat[4] + mat[5]);
    quad_lower_left.z = (-PARTICLE_SIZE/2) * (mat[8] + mat[9]);
    quad_lower_right.x = (PARTICLE_SIZE/2) * (mat[0] - mat[1]);
    quad_lower_right.y = (PARTICLE_SIZE/2) * (mat[4] - mat[5]);
    quad_lower_right.z = (PARTICLE_SIZE/2) * (mat[8] - mat[9]);

    // Don't update z-buffer, since all particles are transparent!
    glDepthMask( GL_FALSE );

    // Enable blending
    glEnable( GL_BLEND );
    glBlendFunc( GL_SRC_ALPHA, GL_ONE );

    // Select particle texture
    if( !wireframe )
    {
        glEnable( GL_TEXTURE_2D );
        glBindTexture( GL_TEXTURE_2D, particle_tex_id );
    }

    // Set up vertex arrays. We use interleaved arrays, which is easier to
    // handle (in most situations) and it gives a linear memeory access
    // access pattern (which may give better performance in some
    // situations). GL_T2F_C4UB_V3F means: 2 floats for texture coords,
    // 4 ubytes for color and 3 floats for vertex coord (in that order).
    // Most OpenGL cards / drivers are optimized for this format.
    glInterleavedArrays( GL_T2F_C4UB_V3F, 0, vertex_array );

    // Is particle physics carried out in a separate thread?
    if( multithreading )
    {
        // Wait for particle physics thread to be done
        glfwLockMutex( thread_sync.particles_lock );
        while( running && thread_sync.p_frame <= thread_sync.d_frame )
        {
            glfwWaitCond( thread_sync.p_done, thread_sync.particles_lock,
                          0.1 );
        }

        // Store the frame time and delta time for the physics thread
        thread_sync.t  = t;
        thread_sync.dt = dt;

        // Update frame counter
        thread_sync.d_frame ++;
    }
    else
    {
        // Perform particle physics in this thread
        ParticleEngine( t, dt );
    }

    // Loop through all particles and build vertex arrays.
    particle_count = 0;
    vptr = vertex_array;
    pptr = particles;
    for( i = 0; i < MAX_PARTICLES; i ++ )
    {
        if( pptr->active )
        {
            // Calculate particle intensity (we set it to max during 75%
            // of its life, then it fades out)
            alpha =  4.0f * pptr->life;
            if( alpha > 1.0f )
            {
                alpha = 1.0f;
            }

            // Convert color from float to 8-bit (store it in a 32-bit
            // integer using endian independent type casting)
            ((GLubyte *)&rgba)[0] = (GLubyte)(pptr->r * 255.0f);
            ((GLubyte *)&rgba)[1] = (GLubyte)(pptr->g * 255.0f);
            ((GLubyte *)&rgba)[2] = (GLubyte)(pptr->b * 255.0f);
            ((GLubyte *)&rgba)[3] = (GLubyte)(alpha * 255.0f);

            // 3) Translate the quad to the correct position in modelview
            // space and store its parameters in vertex arrays (we also
            // store texture coord and color information for each vertex).

            // Lower left corner
            vptr->s    = 0.0f;
            vptr->t    = 0.0f;
            vptr->rgba = rgba;
            vptr->x    = pptr->x + quad_lower_left.x;
            vptr->y    = pptr->y + quad_lower_left.y;
            vptr->z    = pptr->z + quad_lower_left.z;
            vptr ++;

            // Lower right corner
            vptr->s    = 1.0f;
            vptr->t    = 0.0f;
            vptr->rgba = rgba;
            vptr->x    = pptr->x + quad_lower_right.x;
            vptr->y    = pptr->y + quad_lower_right.y;
            vptr->z    = pptr->z + quad_lower_right.z;
            vptr ++;

            // Upper right corner
            vptr->s    = 1.0f;
            vptr->t    = 1.0f;
            vptr->rgba = rgba;
            vptr->x    = pptr->x - quad_lower_left.x;
            vptr->y    = pptr->y - quad_lower_left.y;
            vptr->z    = pptr->z - quad_lower_left.z;
            vptr ++;

            // Upper left corner
            vptr->s    = 0.0f;
            vptr->t    = 1.0f;
            vptr->rgba = rgba;
            vptr->x    = pptr->x - quad_lower_right.x;
            vptr->y    = pptr->y - quad_lower_right.y;
            vptr->z    = pptr->z - quad_lower_right.z;
            vptr ++;

            // Increase count of drawable particles
            particle_count ++;
        }

        // If we have filled up one batch of particles, draw it as a set
        // of quads using glDrawArrays.
        if( particle_count >= BATCH_PARTICLES )
        {
            // The first argument tells which primitive type we use (QUAD)
            // The second argument tells the index of the first vertex (0)
            // The last argument is the vertex count
            glDrawArrays( GL_QUADS, 0, PARTICLE_VERTS * particle_count );
            particle_count = 0;
            vptr = vertex_array;
        }

        // Next particle
        pptr ++;
    }

    // We are done with the particle data: Unlock mutex and signal physics
    // thread
    if( multithreading )
    {
        glfwUnlockMutex( thread_sync.particles_lock );
        glfwSignalCond( thread_sync.d_done );
    }

    // Draw final batch of particles (if any)
    glDrawArrays( GL_QUADS, 0, PARTICLE_VERTS * particle_count );

    // Disable vertex arrays (Note: glInterleavedArrays implicitly called
    // glEnableClientState for vertex, texture coord and color arrays)
    glDisableClientState( GL_VERTEX_ARRAY );
    glDisableClientState( GL_TEXTURE_COORD_ARRAY );
    glDisableClientState( GL_COLOR_ARRAY );

    // Disable texturing and blending
    glDisable( GL_TEXTURE_2D );
    glDisable( GL_BLEND );

    // Allow Z-buffer updates again
    glDepthMask( GL_TRUE );
}
예제 #25
0
파일: kiss.c 프로젝트: kipr/libkiss
void kiss_lock()
{
	glfwLockMutex(kiss_g_glfw_mutex);
}
예제 #26
0
파일: Message.cpp 프로젝트: KTaskn/MMDAgent
/* Message::enqueueMessage: enqueue message */
void Message::enqueueMessage(const char *type, const char *value)
{
   glfwLockMutex(m_messageMutex);
   MessageQueue_enqueue(&m_messageQueue, type, value);
   glfwUnlockMutex(m_messageMutex);
}
예제 #27
0
파일: Message.cpp 프로젝트: KTaskn/MMDAgent
/* Message::enqueueLogString: enqueue log string */
void Message::enqueueLogString(const char *log)
{
   glfwLockMutex(m_logStringMutex);
   MessageQueue_enqueue(&m_logStringQueue, log, NULL);
   glfwUnlockMutex(m_logStringMutex);
}
예제 #28
0
double InputSystem::Time() {
	glfwLockMutex(lock);
	double result = seconds;
	glfwUnlockMutex(lock);
	return seconds;
}
예제 #29
0
bool InputSystem::Quit() {
	glfwLockMutex(lock);
	bool result = wantsQuit;
	glfwUnlockMutex(lock);
	return result;
}
예제 #30
0
파일: Message.cpp 프로젝트: ljmljz/MMDAgent
/* Message::enqueueLog: enqueue log message */
void Message::enqueueLog(const char *log)
{
   glfwLockMutex(m_mutexLog);
   MessageQueue_enqueue(&m_queueLog, log, NULL);
   glfwUnlockMutex(m_mutexLog);
}