Пример #1
0
static int GM_CDECL gmfFireTeamGetInfo( gmThread *a_thread )
{
	CHECK_THIS_BOT();
	GM_CHECK_NUM_PARAMS( 0 );

	ET_FireTeamInfo ft;
	if ( InterfaceFuncs::FireTeamGetInfo( native, ft ) && ft.mInFireTeam )
	{
		DisableGCInScope gcEn( a_thread->GetMachine() );

		gmMachine *pM = a_thread->GetMachine();
		gmTableObject *tbl = pM->AllocTableObject();
		gmTableObject *mbrtbl = pM->AllocTableObject();
		tbl->Set( pM, "Members", gmVariable( mbrtbl ) );

		tbl->Set( pM, "FireTeamNum", gmVariable( ft.mFireTeamNum ) );
		tbl->Set( pM, "Leader", gmVariable::EntityVar( ft.mLeader.AsInt() ) );

		int m = 0;
		for ( int i = 0; i < ET_FireTeamInfo::MaxMembers; ++i )
		{
			if ( ft.mMembers[ i ].IsValid() )
			{
				mbrtbl->Set( pM, m++, gmVariable::EntityVar( ft.mMembers[ i ].AsInt() ) );
			}
		}
		a_thread->PushTable( tbl );
	}
	else
		a_thread->PushNull();

	return GM_OK;
}
Пример #2
0
// function: GetMG42Info
//		Returns currently mounted mg42 info for the bot
//
//
// Parameters:
//
//		GameEntity
//		Table
//
// Returns:
//		MG42 Info
static int gmfGetMG42Info( gmThread *a_thread )
{
	CHECK_THIS_BOT();
	GM_CHECK_NUM_PARAMS( 1 );

	GM_CHECK_TABLE_PARAM( tbl, 0 );

	DisableGCInScope gcEn( a_thread->GetMachine() );

	if ( !tbl )
		tbl = a_thread->GetMachine()->AllocTableObject();

	ET_MG42Info mg42Info;
	if ( tbl != NULL && InterfaceFuncs::GetMg42Properties( native, mg42Info ) )
	{
		tbl->Set( a_thread->GetMachine(), "CenterFacing", gmVariable( mg42Info.mCenterFacing ) );
		tbl->Set( a_thread->GetMachine(), "MinHorizontal", gmVariable( mg42Info.mMinHorizontalArc ) );
		tbl->Set( a_thread->GetMachine(), "MaxHorizontal", gmVariable( mg42Info.mMaxHorizontalArc ) );
		tbl->Set( a_thread->GetMachine(), "MinVertical", gmVariable( mg42Info.mMinVerticalArc ) );
		tbl->Set( a_thread->GetMachine(), "MaxVertical", gmVariable( mg42Info.mMaxVerticalArc ) );
		a_thread->PushInt( 1 );
	}
	else
	{
		a_thread->PushNull();
	}
	return GM_OK;
}
Пример #3
0
gmVariable FmodEventDesc::GetUserProperty( gmMachine* a_machine, const char* a_name )
{
	ASSERT(m_valid);

	FMOD_STUDIO_USER_PROPERTY prop;
	FMOD_RESULT result = m_desc.getUserProperty( a_name, &prop );

	if ( result != FMOD_OK )
	{
		WARN( result == FMOD_OK, "FmodEvent: unable to get user property '%s'", a_name );
		gmVariable null_var;
		null_var.Nullify();
		return null_var;
	}

	switch( prop.type )
	{
		case FMOD_STUDIO_USER_PROPERTY_TYPE_FLOAT: return gmVariable(prop.floatValue);
		case FMOD_STUDIO_USER_PROPERTY_TYPE_INTEGER: return gmVariable(prop.intValue);
		case FMOD_STUDIO_USER_PROPERTY_TYPE_BOOLEAN: return gmVariable(prop.boolValue?1:0);
		
		case FMOD_STUDIO_USER_PROPERTY_TYPE_STRING: 
		{
			gmStringObject* obj = a_machine->AllocStringObject( prop.stringValue );
			return gmVariable(obj);
		}
	}
	
	// should not get here
	gmVariable var;
	var.Nullify();
	return var;
}
Пример #4
0
void LeapController::UpdateFrameGM()
{
    // get vm
    gmMachine* vm = &VirtualMachine::Ref().GetVM();
    ASSERT(vm);

    // call LeapManager.PreUpdateData
    gmFunctionObject* preupdate_func = m_gm_leap_manager->Get(vm, "PreUpdateData").GetFunctionObjectSafe();
    ASSERT(preupdate_func);
    gmCall call_pre;
    call_pre.BeginFunction( vm, preupdate_func, gmVariable(m_gm_leap_manager) );
    call_pre.End();

    // grab current frame in GM
    gmTableObject * curr_frame_table = m_gm_leap_manager->Get(vm, "curr_frame").GetTableObjectSafe();
    ASSERT(curr_frame_table);

    // data we are using to populate GM Tables
    const LeapFrame & frame = m_frames[m_frame_index];

    UpdateInteractionBoxGM();
    UpdateFingersGM( curr_frame_table, frame );
    UpdateHandsGM( curr_frame_table, frame );
    UpdateGesturesGM( curr_frame_table, frame );

    // call LeapManager.PostUpdateData
    gmFunctionObject* postupdate_func = m_gm_leap_manager->Get(vm, "PostUpdateData").GetFunctionObjectSafe();
    ASSERT(postupdate_func);
    gmCall call_post;
    call_post.BeginFunction( vm, postupdate_func, gmVariable(m_gm_leap_manager) );
    call_post.End();
}
Пример #5
0
// function: GetCabinetData
//		Returns table of data for the cabinet
//
//
// Parameters:
//
//		GameEntity
//		Table
//
// Returns:
//		Table of Cabinet Data
static int gmfGetCabinetData( gmThread *a_thread )
{
	GM_CHECK_NUM_PARAMS( 2 );
	GameEntity gameEnt;
	GM_CHECK_GAMEENTITY_FROM_PARAM( gameEnt, 0 );
	GM_CHECK_TABLE_PARAM( tbl, 1 );

	DisableGCInScope gcEn( a_thread->GetMachine() );

	if ( !tbl )
		tbl = a_thread->GetMachine()->AllocTableObject();

	ET_CabinetData cabinetData;
	if ( tbl != NULL && InterfaceFuncs::GetCabinetData( gameEnt, cabinetData ) )
	{
		tbl->Set( a_thread->GetMachine(), "CurrentAmount", gmVariable( cabinetData.mCurrentAmount ) );
		tbl->Set( a_thread->GetMachine(), "MaxAmount", gmVariable( cabinetData.mMaxAmount ) );
		tbl->Set( a_thread->GetMachine(), "Rate", gmVariable( cabinetData.mRate ) );
		a_thread->PushInt( 1 );
	}
	else
	{
		a_thread->PushNull();
	}
	return GM_OK;
}
Пример #6
0
bool bbItem::ToScriptTable(gmMachine *_machine, gmTableObject *&_to)
{
	_to->Set(_machine, "Owner", gmVariable(mOwner));
	_to->Set(_machine, "Target", gmVariable(mTarget));
	_to->Set(_machine, "ExpireTime", gmVariable(mExpireTime));
	_to->Set(_machine, "DeleteOnExpire", gmVariable(mDeleteOnExpire ? 1 : 0));
	return true;
}
Пример #7
0
void LeapController::UpdateInteractionBoxGM()
{
    gmMachine* vm = &VirtualMachine::Ref().GetVM();
    ASSERT(vm);

    gmTableObject * box_table = m_gm_leap_manager->Get(vm, "interaction_box").GetTableObjectSafe();
    ASSERT(box_table);

    box_table->Set( vm, "center", gmVariable( m_interaction_box.center ) );
    box_table->Set( vm, "dimen", gmVariable( m_interaction_box.dimen ) );
}
Пример #8
0
void LeapController::UpdateDevicePropertiesGM()
{
    gmMachine* vm = &VirtualMachine::Ref().GetVM();
    ASSERT(vm);

    gmTableObject * device_prop_table = m_gm_leap_manager->Get(vm, "device_props").GetTableObjectSafe();
    ASSERT(device_prop_table);

    device_prop_table->Set( vm, "frustum_x_axis_angle", gmVariable( m_device_props.frustum_x_axis_angle ) );
    device_prop_table->Set( vm, "frustum_z_axis_angle", gmVariable( m_device_props.frustum_z_axis_angle ) );
    device_prop_table->Set( vm, "frustum_y_height", gmVariable( m_device_props.frustum_y_height ) );
    device_prop_table->Set( vm, "is_connected", gmVariable( m_device_props.is_connected ? 1:0 ) );
}
Пример #9
0
// function: GetCursorHint
//		Gets the current hint and hint value for the client
//
// Parameters:
//
//		table - table to store results. function sets 'type' and 'value'
//
// Returns:
//		none
static int GM_CDECL gmfGetCurrentCursorHint( gmThread *a_thread )
{
	CHECK_THIS_BOT();
	GM_CHECK_NUM_PARAMS( 1 );
	GM_CHECK_TABLE_PARAM( hint, 0 );

	int iHintType = 0, iHintValue = 0;
	InterfaceFuncs::GetCurrentCursorHint( native, iHintType, iHintValue );

	hint->Set( a_thread->GetMachine(), "type", gmVariable( iHintType ) );
	hint->Set( a_thread->GetMachine(), "value", gmVariable( iHintValue ) );

	return GM_OK;
}
Пример #10
0
void VirtualMachine::Render()
{
	if ( !m_drawManager.IsNull() )
	{
		// draw only if not debugging
		if ( !m_vm->GetDebugMode() || !m_debugger.IsDebugging() )
		{
			m_vm->GetGlobals()->Set( m_vm, "g_rendering", gmVariable(1) );
			m_vm->ExecuteFunction(m_drawFunc, 0, true, &m_drawManager);
			m_vm->GetGlobals()->Set( m_vm, "g_rendering", gmVariable(0) );		
		}
		else
		{
			m_vm->ExecuteFunction(m_clearFunc, 0, true, &m_drawManager);
		}
	}
}
Пример #11
0
void LeapController::InitGM()
{
    gmMachine* vm = &VirtualMachine::Ref().GetVM();
    ASSERT(vm);

    // grab the leap manager object
    gmVariable global_obj_key = gmVariable(vm->AllocStringObject("g_leap"));
    m_gm_leap_manager = vm->GetGlobals()->Get(global_obj_key).GetTableObjectSafe();
    ASSERT( m_gm_leap_manager );
}
Пример #12
0
void gmBindUtilityLib( gmMachine * a_machine )
{
	DisableGCInScope gcEn( a_machine );

	a_machine->GetGlobals()->Set( a_machine, GM_PATHSTRING, gmVariable( a_machine->AllocStringObject( "?;?.gm" ) ) );
	a_machine->GetGlobals()->Set( a_machine, GM_REQUIRETABLE, gmVariable( a_machine->AllocTableObject() ) );

	// Register the bot functions.
	a_machine->RegisterLibrary( s_UtilityLib, sizeof( s_UtilityLib ) / sizeof( s_UtilityLib[ 0 ] ) );

	// extra std::string utilities
	a_machine->RegisterTypeLibrary( GM_STRING, s_stringLib, sizeof( s_stringLib ) / sizeof( s_stringLib[ 0 ] ) );

	// Create the dump flag table.
	gmTableObject *pDumpTable = a_machine->AllocTableObject();
	pDumpTable->Set( a_machine, gmVariable( a_machine->AllocStringObject( "RECURSE" ) ), gmVariable( gmUtility::DUMP_RECURSE ) );
	pDumpTable->Set( a_machine, gmVariable( a_machine->AllocStringObject( "FUNCTIONS" ) ), gmVariable( gmUtility::DUMP_FUNCTIONS ) );
	pDumpTable->Set( a_machine, gmVariable( a_machine->AllocStringObject( "REFERENCES" ) ), gmVariable( gmUtility::DUMP_REFERENCES ) );
	pDumpTable->Set( a_machine, gmVariable( a_machine->AllocStringObject( "TYPEFUNCTIONS" ) ), gmVariable( gmUtility::DUMP_TYPEFUNCTIONS ) );
	pDumpTable->Set( a_machine, gmVariable( a_machine->AllocStringObject( "ALL" ) ), gmVariable( gmUtility::DUMP_ALL ) );
	a_machine->GetGlobals()->Set( a_machine, gmVariable( a_machine->AllocStringObject( "DUMP" ) ), gmVariable( pDumpTable ) );
}
Пример #13
0
static int GM_CDECL gmStringTokenize( gmThread * a_thread )
{
	GM_CHECK_NUM_PARAMS( 1 );
	GM_CHECK_STRING_PARAM( delim, 0 );

	DisableGCInScope gcEn( a_thread->GetMachine() );

	const gmVariable * var = a_thread->GetThis();
	gmStringObject * strObj = var->GetStringObjectSafe();

	StringVector tokens;
	Utils::Tokenize( strObj->GetString(), delim, tokens );
	gmTableObject *pTbl = a_thread->GetMachine()->AllocTableObject();
	for ( uint32_t i = 0; i < tokens.size(); ++i )
		pTbl->Set( a_thread->GetMachine(), i, gmVariable( a_thread->GetMachine()->AllocStringObject( tokens[ i ].c_str() ) ) );
	a_thread->PushTable( pTbl );
	return GM_OK;
}
Пример #14
0
// RAGE AGAINST THE VIRTUAL MACHINE =)
gmThread::State gmThread::Sys_Execute(gmVariable * a_return)
{
  register union
  {
    const gmuint8 * instruction;
    const gmuint32 * instruction32;
  };
  register gmVariable * top;
  gmVariable * base;
  gmVariable * operand;
  const gmuint8 * code;

  if(m_state != RUNNING) return m_state;

#if GMDEBUG_SUPPORT

  if(m_debugFlags && m_machine->GetDebugMode() && m_machine->m_isBroken)
  {
    if(m_machine->m_isBroken(this)) 
      return RUNNING;
  }

#endif // GMDEBUG_SUPPORT

  // make sure we have a stack frame
  GM_ASSERT(m_frame);
  GM_ASSERT(GetFunction()->m_type == GM_FUNCTION);

  // cache our "registers"
  gmFunctionObject * fn = (gmFunctionObject *) GM_MOBJECT(m_machine, GetFunction()->m_value.m_ref);
  code = (const gmuint8 *) fn->GetByteCode();
  if(m_instruction == NULL) instruction = code;
  else instruction = m_instruction;
  top = GetTop();
  base = GetBase();

  //
  // start byte code execution
  //
  for(;;)
  {

#ifdef GM_CHECK_USER_BREAK_CALLBACK // This may be defined in gmConfig_p.h
    // Check external source to break execution with exception eg. Check for CTRL-BREAK
    // Endless loop protection could be implemented with this, or in a similar manner.
    if( gmMachine::s_userBreakCallback && gmMachine::s_userBreakCallback(this) )
    {
      GMTHREAD_LOG("User break. Execution halted.");
      goto LabelException;
    }
#endif //GM_CHECK_USER_BREAK_CALLBACK 

    switch(*(instruction32++))
    {
      //
      // unary operator
      //

#if GM_USE_INCDECOPERATORS
      case BC_OP_INC :
      case BC_OP_DEC :
#endif
      case BC_BIT_INV :
      case BC_OP_NEG :
      case BC_OP_POS :
      case BC_OP_NOT :
      {
        operand = top - 1; 
        gmOperatorFunction op = OPERATOR(operand->m_type, (gmOperator) instruction32[-1]); 
        if(op) 
        { 
          op(this, operand); 
        } 
        else if((fn = CALLOPERATOR(operand->m_type, (gmOperator) instruction32[-1]))) 
        { 
          operand[2] = operand[0]; 
          operand[0] = gmVariable(GM_NULL, 0); 
          operand[1] = gmVariable(GM_FUNCTION, fn->GetRef()); 
          SetTop(operand + 3); 
          State res = PushStackFrame(1, &instruction, &code); 
          top = GetTop();
          base = GetBase();
          if(res == RUNNING) break;
          if(res == SYS_YIELD) return RUNNING;
          if(res == SYS_EXCEPTION) goto LabelException;
          if(res == KILLED) { m_machine->Sys_SwitchState(this, KILLED); GM_ASSERT(0); } // operator should not kill a thread
          return res;
        } 
        else 
        { 
          GMTHREAD_LOG("unary operator %s undefined for type %s", gmGetOperatorName((gmOperator) instruction32[-1]), m_machine->GetTypeName(operand->m_type)); 
          goto LabelException; 
        } 
        break;
      }

      //
      // operator
      //

      case BC_OP_ADD :
      case BC_OP_SUB :
      case BC_OP_MUL :
      case BC_OP_DIV :
      case BC_OP_REM :
      case BC_BIT_OR :
      case BC_BIT_XOR :
      case BC_BIT_AND :
      case BC_BIT_SHL :
      case BC_BIT_SHR :
      case BC_OP_LT :
      case BC_OP_GT :
      case BC_OP_LTE :
      case BC_OP_GTE :
      case BC_OP_EQ :
      case BC_OP_NEQ :
      {
        operand = top - 2; 
        --top; 
        
        // NOTE: Classic logic for operators.  Higher type processes the operation.
        register gmType t1 = operand[1].m_type; 
        if(operand->m_type > t1) t1 = operand->m_type; 
        
        gmOperatorFunction op = OPERATOR(t1, (gmOperator) instruction32[-1]); 
        if(op) 
        { 
          op(this, operand); 
        } 
        else if((fn = CALLOPERATOR(t1, (gmOperator) instruction32[-1]))) 
        { 
          operand[2] = operand[0]; 
          operand[3] = operand[1]; 
          operand[0] = gmVariable(GM_NULL, 0); 
          operand[1] = gmVariable(GM_FUNCTION, fn->GetRef()); 
          SetTop(operand + 4); 
          State res = PushStackFrame(2, &instruction, &code); 
          top = GetTop(); 
          base = GetBase();
          if(res == RUNNING) break;
          if(res == SYS_YIELD) return RUNNING;
          if(res == SYS_EXCEPTION) goto LabelException;
          if(res == KILLED) { m_machine->Sys_SwitchState(this, KILLED); GM_ASSERT(0); } // operator should not kill a thread
          return res;
        } 
        else 
        { 
          GMTHREAD_LOG("operator %s undefined for type %s and %s", gmGetOperatorName((gmOperator) instruction32[-1]), m_machine->GetTypeName(operand->m_type), m_machine->GetTypeName((operand + 1)->m_type)); 
          goto LabelException; 
        } 

        break;
      }
      case BC_GETIND :
      {
        operand = top - 2; 
        --top; 
        gmOperatorFunction op = OPERATOR(operand->m_type, (gmOperator) instruction32[-1]); 
        if(op) 
        { 
          op(this, operand); 
        } 
        else if((fn = CALLOPERATOR(operand->m_type, (gmOperator) instruction32[-1]))) 
        { 
          operand[2] = operand[0]; 
          operand[3] = operand[1]; 
          operand[0] = gmVariable(GM_NULL, 0); 
          operand[1] = gmVariable(GM_FUNCTION, fn->GetRef()); 
          SetTop(operand + 4); 
          State res = PushStackFrame(2, &instruction, &code); 
          top = GetTop(); 
          base = GetBase();
          if(res == RUNNING) break;
          if(res == SYS_YIELD) return RUNNING;
          if(res == SYS_EXCEPTION) goto LabelException;
          if(res == KILLED) { m_machine->Sys_SwitchState(this, KILLED); GM_ASSERT(0); } // operator should not kill a thread
          return res;
        } 
        else 
        { 
          GMTHREAD_LOG("operator %s undefined for type %s and %s", gmGetOperatorName((gmOperator) instruction32[-1]), m_machine->GetTypeName(operand->m_type), m_machine->GetTypeName((operand + 1)->m_type)); 
          goto LabelException; 
        } 

        break;
      }
      case BC_SETIND : 
      { 
        operand = top - 3; 
        top -= 3; 
        gmOperatorFunction op = OPERATOR(operand->m_type, O_SETIND); 
        if(op) 
        { 
          op(this, operand); 
        } 
        else if((fn = CALLOPERATOR(operand->m_type, O_SETIND))) 
        { 
          operand[4] = operand[2]; 
          operand[3] = operand[1]; 
          operand[2] = operand[0]; 
          operand[0] = gmVariable(GM_NULL, 0); 
          operand[1] = gmVariable(GM_FUNCTION, fn->GetRef()); 
          SetTop(operand + 5); 
          State res = PushStackFrame(3, &instruction, &code); 
          top = GetTop(); 
          base = GetBase(); 
          if(res == RUNNING) break; 
          if(res == SYS_YIELD) return RUNNING; 
          if(res == SYS_EXCEPTION) goto LabelException; 
          if(res == KILLED) { m_machine->Sys_SwitchState(this, KILLED); GM_ASSERT(0); } // operator should not kill a thread 
          return res; 
        } 
        else 
        { 
          GMTHREAD_LOG("setind failed."); 
          goto LabelException; 
        } 
        break; 
      } 
      case BC_NOP :
      {
        break;
      }
      case BC_LINE :
      {

#if GMDEBUG_SUPPORT

        if(m_machine->GetDebugMode() && m_machine->m_line)
        {
          SetTop(top);
          m_instruction = instruction;
          if(m_machine->m_line(this)) return RUNNING;
        }

#endif // GMDEBUG_SUPPORT

        break;
      }
      case BC_GETDOT :
      {
        operand = top - 1;
        gmptr member = OPCODE_PTR(instruction);
        top->m_type = GM_STRING;
        top->m_value.m_ref = member;
        gmType t1 = operand->m_type;
        gmOperatorFunction op = OPERATOR(t1, O_GETDOT);
        if(op)
        {
          op(this, operand);
          if(operand->m_type) break;
        }
        if(t1 == GM_NULL)
        {
          GMTHREAD_LOG("getdot failed.");
          goto LabelException;
        }
        *operand = m_machine->GetTypeVariable(t1, gmVariable(GM_STRING, member));
        break;
      }
      case BC_SETDOT :
      {
        operand = top - 2;
        gmptr member = OPCODE_PTR(instruction);
        top->m_type = GM_STRING;
        top->m_value.m_ref = member;
        top -= 2;
        gmOperatorFunction op = OPERATOR(operand->m_type, O_SETDOT);
        if(op)
        {
          op(this, operand);
        }
        else
        {
          GMTHREAD_LOG("setdot failed.");
          goto LabelException;
        }
        break;
      }
      case BC_BRA :
      {
        instruction = code + OPCODE_PTR_NI(instruction);
        break;
      }
      case BC_BRZ :
      {
#if GM_BOOL_OP
        operand = top - 1;
        --top;
        if (operand->m_type > GM_USER)
        {
          // Look for overridden operator.
          gmOperatorFunction op = OPERATOR(operand->m_type, O_BOOL);

          if (op)
          {
            op(this, operand);
          }
          else if ((fn = CALLOPERATOR(operand->m_type, O_BOOL)))
          {
            operand[2] = operand[0];
            operand[0] = gmVariable(GM_NULL, 0);
            operand[1] = gmVariable(GM_FUNCTION, fn->GetRef());
            SetTop(operand + 3);
            // Return to the same instruction after making the call but it will be testing the results of the call.
            --instruction32;
            State res = PushStackFrame(1, &instruction, &code);
            top = GetTop();
            base = GetBase();
            if(res == RUNNING) break;
            if(res == SYS_YIELD) return RUNNING;
            if(res == SYS_EXCEPTION) goto LabelException;
            if(res == KILLED) { m_machine->Sys_SwitchState(this, KILLED); GM_ASSERT(0); } // operator should not kill a thread
            return res;
          }
        }

        if(operand->m_value.m_int == 0)
        {
          instruction = code + OPCODE_PTR_NI(instruction);
        }
        else instruction += sizeof(gmptr);
#else // !GM_BOOL_OP
        --top;
        if(top->m_value.m_int == 0)
        {
          instruction = code + OPCODE_PTR_NI(instruction);
        }
        else instruction += sizeof(gmptr);
#endif // !GM_BOOL_OP
        break;
      }
      case BC_BRNZ :
      {
#if GM_BOOL_OP
        operand = top - 1;
        --top;
        if (operand->m_type > GM_USER)
        {
          // Look for overridden operator.
          gmOperatorFunction op = OPERATOR(operand->m_type, O_BOOL);

          if (op)
          {
            op(this, operand);
          }
          else if ((fn = CALLOPERATOR(operand->m_type, O_BOOL)))
          {
            operand[2] = operand[0];
            operand[0] = gmVariable(GM_NULL, 0);
            operand[1] = gmVariable(GM_FUNCTION, fn->GetRef());
            SetTop(operand + 3);
            // Return to the same instruction after making the call but it will be testing the results of the call.
            --instruction32;
            State res = PushStackFrame(1, &instruction, &code);
            top = GetTop();
            base = GetBase();
            if(res == RUNNING) break;
            if(res == SYS_YIELD) return RUNNING;
            if(res == SYS_EXCEPTION) goto LabelException;
            if(res == KILLED) { m_machine->Sys_SwitchState(this, KILLED); GM_ASSERT(0); } // operator should not kill a thread
            return res;
          }
        }

        if(operand->m_value.m_int != 0)
        {
          instruction = code + OPCODE_PTR_NI(instruction);
        }
        else instruction += sizeof(gmptr);
#else // !GM_BOOL_OP
        --top;
        if(top->m_value.m_int != 0)
        {
          instruction = code + OPCODE_PTR_NI(instruction);
        }
        else instruction += sizeof(gmptr);
#endif // !GM_BOOL_OP
        break;
      }
      case BC_BRZK :
      {
#if GM_BOOL_OP
        operand = top - 1;
        if (operand->m_type > GM_USER)
        {
          // Look for overridden operator.
          gmOperatorFunction op = OPERATOR(operand->m_type, O_BOOL);

          if (op)
          {
            op(this, operand);
          }
          else if ((fn = CALLOPERATOR(operand->m_type, O_BOOL)))
          {
            operand[2] = operand[0];
            operand[0] = gmVariable(GM_NULL, 0);
            operand[1] = gmVariable(GM_FUNCTION, fn->GetRef());
            SetTop(operand + 3);
            // Return to the same instruction after making the call but it will be testing the results of the call.
            --instruction32;
            State res = PushStackFrame(1, &instruction, &code);
            top = GetTop();
            base = GetBase();
            if(res == RUNNING) break;
            if(res == SYS_YIELD) return RUNNING;
            if(res == SYS_EXCEPTION) goto LabelException;
            if(res == KILLED) { m_machine->Sys_SwitchState(this, KILLED); GM_ASSERT(0); } // operator should not kill a thread
            return res;
          }
        }

        if(operand->m_value.m_int == 0)
        {
          instruction = code + OPCODE_PTR_NI(instruction);
        }
        else instruction += sizeof(gmptr);
#else // !GM_BOOL_OP
        if(top[-1].m_value.m_int == 0)
        {
          instruction = code + OPCODE_PTR_NI(instruction);
        }
        else instruction += sizeof(gmptr);
#endif // !GM_BOOL_OP
        break;
      }
      case BC_BRNZK :
      {
#if GM_BOOL_OP
        operand = top - 1;
        if (operand->m_type > GM_USER)
        {
          // Look for overridden operator.
          gmOperatorFunction op = OPERATOR(operand->m_type, O_BOOL);

          if (op)
          {
            op(this, operand);
          }
          else if ((fn = CALLOPERATOR(operand->m_type, O_BOOL)))
          {
            operand[2] = operand[0];
            operand[0] = gmVariable(GM_NULL, 0);
            operand[1] = gmVariable(GM_FUNCTION, fn->GetRef());
            SetTop(operand + 3);
            // Return to the same instruction after making the call but it will be testing the results of the call.
            --instruction32;
            State res = PushStackFrame(1, &instruction, &code);
            top = GetTop();
            base = GetBase();
            if(res == RUNNING) break;
            if(res == SYS_YIELD) return RUNNING;
            if(res == SYS_EXCEPTION) goto LabelException;
            if(res == KILLED) { m_machine->Sys_SwitchState(this, KILLED); GM_ASSERT(0); } // operator should not kill a thread
            return res;
          }
        }

        if(operand->m_value.m_int != 0)
        {
          instruction = code + OPCODE_PTR_NI(instruction);
        }
        else instruction += sizeof(gmptr);
#else // !GM_BOOL_OP
        if(top[-1].m_value.m_int != 0)
        {
          instruction = code + OPCODE_PTR_NI(instruction);
        }
        else instruction += sizeof(gmptr);
#endif // !GM_BOOL_OP
        break;
      }
      case BC_CALL :
      {
        SetTop(top);
        
        int numParams = (int) OPCODE_INT(instruction);

        State res = PushStackFrame(numParams, &instruction, &code);
        top = GetTop(); 
        base = GetBase();

        if(res == RUNNING)
        {

#if GMDEBUG_SUPPORT

          if(m_debugFlags && m_machine->GetDebugMode() && m_machine->m_call)
          {
            m_instruction = instruction;
            if(m_machine->m_call(this)) return RUNNING;
          }

#endif // GMDEBUG_SUPPORT

          break;
        }
        if(res == SYS_YIELD) return RUNNING;
        if(res == SYS_EXCEPTION) goto LabelException;
        if(res == KILLED)
        {
          if(a_return) *a_return = m_stack[m_top - 1];
          m_machine->Sys_SwitchState(this, KILLED);
        }
        return res;
      }
      case BC_RET :
      {
        PUSHNULL;
      }
      case BC_RETV :
      {
        SetTop(top);
        int res = Sys_PopStackFrame(instruction, code);
        top = GetTop();
        base = GetBase();

        if(res == RUNNING) 
        {

#if GMDEBUG_SUPPORT

          if(m_debugFlags && m_machine->GetDebugMode() && m_machine->m_return)
          {
            m_instruction = instruction;
            if(m_machine->m_return(this)) return RUNNING;
          }

#endif // GMDEBUG_SUPPORT

          break;
        }
        if(res == KILLED)
        {
          if(a_return) *a_return = *(top - 1);
          m_machine->Sys_SwitchState(this, KILLED);
          return KILLED;
        }
        if(res == SYS_EXCEPTION) goto LabelException;
        break;
      }
#if GM_USE_FORK
    // duplicates the current thread and just the local stack frame
    // and branches around the forked section of code
     case BC_FORK :
     {
        int id;
        gmThread* newthr = GetMachine()->CreateThread(&id);
        GM_ASSERT( newthr );

        // make sure there is enough room
        newthr->Touch( m_size - m_base + 2 - GMTHREAD_SLACKSPACE);
        // copy stack and vars
        memcpy( newthr->m_stack, &m_stack[ m_base - 2 ], sizeof( gmVariable ) * (m_top - m_base + 2 ) );

        newthr->m_top = m_top - m_base + 2;
        newthr->m_frame = m_machine->Sys_AllocStackFrame();
        newthr->m_frame->m_prev = 0;
        newthr->m_frame->m_returnAddress = 0;
        newthr->m_frame->m_returnBase = 0;

        newthr->m_base = 2;
        newthr->m_instruction = instruction + sizeof(gmptr); // skip branch on other thread
        newthr->PushInt( GetId() );

        instruction = code + OPCODE_PTR_NI( instruction );   // branch

        top->m_type = GM_INT;
        top->m_value.m_int = newthr->GetId();
        ++top;
        break;
     }
#endif //GM_USE_FORK
      case BC_FOREACH :
      {
        gmuint32 localvalue = OPCODE_INT(instruction);
        gmuint32 localkey = localvalue >> 16;
        localvalue &= 0xffff;

        // iterator is at tos-1, table is at tos -2, push int 1 if continuing loop. write key and value into localkey and localvalue
        if(top[-2].m_type != GM_TABLE)
        {
#if GM_USER_FOREACH
          gmTypeIteratorCallback itrfunc = m_machine->GetUserTypeIteratorCallback(top[-2].m_type);
          if (!itrfunc)
          {
            GMTHREAD_LOG("foreach expression has no iterator function");
            goto LabelException;
          }

          gmTypeIterator it = (gmTypeIterator) top[-1].m_value.m_int;
          gmUserObject *obj = (gmUserObject*)GM_MOBJECT(m_machine, top[-2].m_value.m_ref);
          // Do callback for getnext
          gmVariable localvar;
          gmVariable localkeyvar;
          itrfunc(this, obj, it, &localkeyvar, &localvar);
          if (it != GM_TYPE_ITR_NULL)
          {
            base[localkey] = localkeyvar;
            base[localvalue] = localvar;
            top->m_type = GM_INT; top->m_value.m_int = 1;
          }
          else
          {
            top->m_type = GM_INT; top->m_value.m_int = 0;
          }
          top[-1].m_value.m_int = it;
          ++top;
#else //GM_USER_FOREACH (original)
          GMTHREAD_LOG("foreach expression is not table type");
          goto LabelException;
#endif //GM_USER_FOREACH
        }
        else
        {
          GM_ASSERT(top[-1].m_type == GM_INT);
          gmTableIterator it = (gmTableIterator) top[-1].m_value.m_int;
          gmTableObject * table = (gmTableObject *) GM_MOBJECT(m_machine, top[-2].m_value.m_ref);
          gmTableNode * node = table->GetNext(it);
          top[-1].m_value.m_int = it;
          if(node)
          {
            base[localkey] = node->m_key;
            base[localvalue] = node->m_value;
            top->m_type = GM_INT; top->m_value.m_int = 1;
          }
          else
          {
            top->m_type = GM_INT; top->m_value.m_int = 0;
          }
          ++top;
        }
        break;
      }
      case BC_POP :
      {
        --top;
        break;
      }
      case BC_POP2 :
      {
        top -= 2;
        break;
      }
      case BC_DUP :
      {
        top[0] = top[-1]; 
        ++top;
        break;
      }
      case BC_DUP2 :
      {
        top[0] = top[-2];
        top[1] = top[-1];
        top += 2;
        break;
      }
      case BC_SWAP :
      {
        top[0] = top[-1];
        top[-1] = top[-2];
        top[-2] = top[0];
        break;
      }
      case BC_PUSHNULL :
      {
        PUSHNULL;
        break;
      }
      case BC_PUSHINT :
      {
        top->m_type = GM_INT;
        top->m_value.m_int = OPCODE_INT(instruction);
        ++top;
        break;
      }
      case BC_PUSHINT0 :
      {
        top->m_type = GM_INT;
        top->m_value.m_int = 0;
        ++top;
        break;
      }
      case BC_PUSHINT1 :
      {
        top->m_type = GM_INT;
        top->m_value.m_int = 1;
        ++top;
        break;
      }
      case BC_PUSHFP :
      {
        top->m_type = GM_FLOAT;
        top->m_value.m_float = OPCODE_FLOAT(instruction);
        ++top;
        break;
      }
      case BC_PUSHSTR :
      {
        top->m_type = GM_STRING;
        top->m_value.m_ref = OPCODE_PTR(instruction);
        ++top;
        break;
      }
      case BC_PUSHTBL :
      {
        SetTop(top);
        top->m_type = GM_TABLE;
        top->m_value.m_ref = m_machine->AllocTableObject()->GetRef();
        ++top;
        break;
      }
      case BC_PUSHFN :
      {
        top->m_type = GM_FUNCTION;
        top->m_value.m_ref = OPCODE_PTR(instruction);
        ++top;
        break;
      }
      case BC_PUSHTHIS :
      {
        *top = *GetThis();
        ++top;
        break;
      }
      case BC_GETLOCAL :
      {
        gmuint32 offset = OPCODE_INT(instruction);
        *(top++) = base[offset];
        break;
      }
      case BC_SETLOCAL :
      {
        gmuint32 offset = OPCODE_INT(instruction);

        // Write barrier old local objects
        {
          gmGarbageCollector* gc = m_machine->GetGC();
          if( !gc->IsOff() && base[offset].IsReference() )
          {
            gmObject * object = GM_MOBJECT(m_machine, base[offset].m_value.m_ref);
            gc->WriteBarrier(object);
          }
        }

        base[offset] = *(--top);
        break;
      }
      case BC_GETGLOBAL :
      {
        top->m_type = GM_STRING;
        top->m_value.m_ref = OPCODE_PTR(instruction);
        *top = m_machine->GetGlobals()->Get(*top); ++top;
        break;
      }
      case BC_SETGLOBAL :
      {
        top->m_type = GM_STRING;
        top->m_value.m_ref = OPCODE_PTR(instruction);
        m_machine->GetGlobals()->Set(m_machine, *top, *(top-1)); --top;
        break;
      }
      case BC_GETTHIS :
      {
        gmptr member = OPCODE_PTR(instruction);
        const gmVariable * thisVar = GetThis();
        *top = *thisVar;
        top[1].m_type = GM_STRING;
        top[1].m_value.m_ref = member;
        gmOperatorFunction op = OPERATOR(thisVar->m_type, O_GETDOT);
        if(op)
        {
          op(this, top);
          if(top->m_type) { ++top; break; }
        }
        if(thisVar->m_type == GM_NULL)
        {
          GMTHREAD_LOG("getthis failed. this is null");
          goto LabelException;
        }
        *top = m_machine->GetTypeVariable(thisVar->m_type, top[1]);
        ++top;
        break;
      }
      case BC_SETTHIS :
      {
        gmptr member = OPCODE_PTR(instruction);
        const gmVariable * thisVar = GetThis();
        operand = top - 1;
        *top = *operand;
        *operand = *thisVar;
        top[1].m_type = GM_STRING;
        top[1].m_value.m_ref = member;
        --top;
        gmOperatorFunction op = OPERATOR(thisVar->m_type, O_SETDOT);
        if(op)
        {
          op(this, operand);
        }
        else
        {
          GMTHREAD_LOG("setthis failed.");
          goto LabelException;
        }
        break;
      }
      default :
      {
        break;
      }
    }
  }

LabelException:

  //
  // exception handler
  //
  m_instruction = instruction;

  // spit out error info
  LogLineFile();
  LogCallStack();

  // call machine exception handler
  if(gmMachine::s_machineCallback)
  {
    if(gmMachine::s_machineCallback(m_machine, MC_THREAD_EXCEPTION, this))
    {
#if GMDEBUG_SUPPORT
      // if we are being debugged, put this thread into a limbo state, waiting for delete.
      if(m_machine->GetDebugMode() && m_machine->m_debugUser)
      {
        m_machine->Sys_SwitchState(this, EXCEPTION);
        return EXCEPTION;
      }
#endif
    }
  }

  // kill the thread
  m_machine->Sys_SwitchState(this, KILLED);
  return KILLED;
}
Пример #15
0
gmThread::State gmThread::PushStackFrame(int a_numParameters, const gmuint8 ** a_ip, const gmuint8 ** a_cp)
{
  // calculate new stack base
  int base = m_top - a_numParameters;

  if( base == 2 ) // When initial thread function is ready, signal thread creation
  {
    // This may not be the best place to signal, but we at least want a valid 'this'
    m_base = base; // Init so some thread queries work
    m_machine->Sys_SignalCreateThread(this);
  }

  gmVariable * fnVar = &m_stack[base - 1];
  if(fnVar->m_type != GM_FUNCTION) 
  {
    m_machine->GetLog().LogEntry("attempt to call non function type");
    return SYS_EXCEPTION; 
  }
  gmFunctionObject * fn = (gmFunctionObject *) GM_MOBJECT(m_machine, fnVar->m_value.m_ref);

  if(fn->m_cFunction)
  {
    //
    // Its a native function call, call it now as we cannot stack wind natives.  this avoids
    // pushing a gmStackFrame.
    //

    m_numParameters = (short) a_numParameters;
    int lastBase = m_base;
    int lastTop = m_top;
    m_base = base;

    int result = fn->m_cFunction(this);

    // Write barrier old local objects at native pop time
    {
      gmGarbageCollector* gc = m_machine->GetGC();
      if( !gc->IsOff() )
      {
        for(int index = m_base; index < m_top; ++index)
        {
          if(m_stack[index].IsReference())
          {
            gmObject * object = GM_MOBJECT(m_machine, m_stack[index].m_value.m_ref);
            gc->WriteBarrier(object);
          }
        }
      }
    }

    // handle state
    if(result == GM_SYS_STATE)
    {
      // this is special case, a bit messy.
      return PushStackFrame(a_numParameters - GM_STATE_NUM_PARAMS, a_ip, a_cp);
    }

    // NOTE: It is not currently safe for a C binding to kill this thread.
    //       Since we cant unwind mixed script and native functions anyway, 
    //       perhaps the safest thing would be for ALWAYS delay killed threads 
    //       from deletion.

    // push a null if the function did not return anything
    if(lastTop == m_top)
    {
      m_stack[m_base - 2] = gmVariable(GM_NULL, 0);
    }
    else
    {
      m_stack[m_base - 2] = m_stack[m_top - 1];
    }

    // Restore the stack
    m_top = m_base - 1;
    m_base = lastBase;

    // check the call result
    if(result != GM_OK)
    {
      const gmuint8 * returnAddress = (a_ip) ? *a_ip : NULL;

      if(result == GM_SYS_YIELD)
      {
        m_machine->Sys_RemoveSignals(this);
        m_instruction = returnAddress;
        return SYS_YIELD;
      }
      else if(result == GM_SYS_BLOCK)
      {
        m_instruction = returnAddress;
        m_machine->Sys_SwitchState(this, BLOCKED);
        return BLOCKED;
      }
      else if(result == GM_SYS_SLEEP)
      {
        m_instruction = returnAddress;
        m_machine->Sys_SwitchState(this, SLEEPING);
        return SLEEPING;
      }
      else if(result == GM_SYS_KILL)
      {
        return KILLED;
      }
      return SYS_EXCEPTION;
    }

    if(!m_frame) // C called C function, no stack frame, so signal killed.
    {
      return KILLED;
    }

    // return result
    return RUNNING;
  }

  //
  // Its a script function call, push a stack frame
  //

  int clearSize = fn->GetNumParamsLocals() - a_numParameters;
  if(!Touch(clearSize + fn->GetMaxStackSize())) 
  {
    m_machine->GetLog().LogEntry("stack overflow");
    return SYS_EXCEPTION;
  }

  // zero missing params and locals.
  if(a_numParameters <= fn->GetNumParams())
  {
    memset(GetTop(), 0, sizeof(gmVariable) * clearSize);
  }
  else
  {
    memset(&m_stack[base + fn->GetNumParams()], 0, sizeof(gmVariable) * fn->GetNumLocals());
  }

  // push a new stack frame
  gmStackFrame * frame = m_machine->Sys_AllocStackFrame();
  frame->m_prev = m_frame;
  m_frame = frame;

  // cache new frame variables
  m_frame->m_returnBase = m_base;

  if(a_ip)
  {
    m_frame->m_returnAddress = *a_ip;
    *a_ip = (const gmuint8 *) fn->GetByteCode();
    *a_cp = *a_ip;
  }
  else
  {
    m_frame->m_returnAddress = NULL;
  }
  m_base = base;
  m_top = base + fn->GetNumParamsLocals();

  return RUNNING;
}
Пример #16
0
void LeapController::UpdateFingersGM( gmTableObject* a_frame_table, const LeapFrame & a_frame )
{
    gmMachine* vm = &VirtualMachine::Ref().GetVM();
    ASSERT(vm);

    gmTableObject * fingers_table = a_frame_table->Get(vm, "fingers").GetTableObjectSafe();
    ASSERT(fingers_table);

    // populate fingers
    for( size_t i = 0; i < a_frame.fingers.size(); ++i )
    {
        const LeapFinger & finger = a_frame.fingers[i];

        // create the finger
        gmTableObject * finger_obj = AllocFreeObj("pool_fingers");

        // if none in pool
        if ( finger_obj == nullptr )
            continue;

        finger_obj->Set( vm, "id", gmVariable( finger.id ) );
        finger_obj->Set( vm, "hand_id", gmVariable( finger.hand_id ) );
        finger_obj->Set( vm, "hand_index", gmVariable( finger.hand_index ) );
        finger_obj->Set( vm, "finger_size", gmVariable( finger.finger_size ) );
        finger_obj->Set( vm, "dir", gmVariable( finger.dir ) );
        finger_obj->Set( vm, "tip_pos", gmVariable( finger.tip_pos ) );
        finger_obj->Set( vm, "tip_pos_stabilized", gmVariable( finger.tip_pos_stabilized ) );
        finger_obj->Set( vm, "tip_vel", gmVariable( finger.tip_vel ) );
        finger_obj->Set( vm, "age", gmVariable( finger.age ) );
        finger_obj->Set( vm, "dist_to_boundary", gmVariable( finger.dist_to_boundary ) );

        fingers_table->Set( vm, gmVariable(finger.id), gmVariable(finger_obj) );
    }
}
Пример #17
0
void VirtualMachine::RunMain()
{
	IniReader ini(RESOURCE_PATH("common/ini/main.ini"));

	int debugMode = 1;
	int runGmLibs = 0;
#ifdef FNK_FINAL
	debugMode = 0;
	runGmLibs = 1;
#endif

	int fps = ini.GetInt("Window", "FPS");
	int gcWorkPerIncrement = ini.GetInt("VirtualMachine", "GC_WorkPerIncrement");
	int gcDestructsPerIncrement = ini.GetInt("VirtualMachine", "GC_DestructPerIncrement");
	int memUsageSoft = ini.GetInt("VirtualMachine", "MemUsageSoft");
	int memUsageHard = ini.GetInt("VirtualMachine", "MemUsageHard");

	m_vm->GetGC()->SetWorkPerIncrement(gcWorkPerIncrement);
	m_vm->GetGC()->SetDestructPerIncrement(gcDestructsPerIncrement);
	m_vm->SetDesiredByteMemoryUsageSoft(memUsageSoft);
	m_vm->SetDesiredByteMemoryUsageHard(memUsageHard);

	m_vm->SetDebugMode(debugMode == 1);
	m_bUseGmByteCode = runGmLibs == 1;
	m_dt = 1.0f/fps;

	// print current setting
	char buffer[128];
	sprintf_s(buffer, "Running at %d hz, VM Debug Mode: %d, VM Run Byte-Code: %d", fps, debugMode, runGmLibs );
	m_console.Log(buffer);
	sprintf_s(buffer, "GC Works Per Increment: %d, GC Destructs Per Increment: %d", gcWorkPerIncrement, gcDestructsPerIncrement );
	m_console.Log(buffer);
	sprintf_s(buffer, "Mem Usage Soft: %d bytes, Mem Usage Hard: %d bytes", memUsageSoft, memUsageHard );
	m_console.Log(buffer);

	// attach debugger
	if ( m_vm->GetDebugMode() ) m_debugger.Open(m_vm);

	RegisterLibs(m_vm);

	// set dt
	m_vm->GetGlobals()->Set( m_vm, "g_dt", gmVariable(m_dt) );
	m_vm->GetGlobals()->Set( m_vm, "g_rendering", gmVariable(0) );
    m_vm->GetGlobals()->Set( m_vm, "g_resourcePathPrefix", gmVariable(m_vm->AllocStringObject(RESOURCE_PATH(""))) );

	m_threadId = gmCompileStr(m_vm, kEntryFile);	
	printf("'%s' Main thread: %d\n", kEntryFile, m_threadId );

	// get draw manager
	gmVariable drawManagerKey = gmVariable(m_vm->AllocStringObject("g_drawManager"));
	gmTableObject* drawManager = m_vm->GetGlobals()->Get(drawManagerKey).GetTableObjectSafe();
	m_drawManager.Nullify();

	if ( drawManager )
	{
		m_drawManager = gmVariable(gmVariable(drawManager));		

		// grab draw functions
		gmVariable drawKey = gmVariable(m_vm->AllocStringObject("Draw"));
		m_drawFunc = drawManager->Get(drawKey).GetFunctionObjectSafe();
		gmVariable clearKey = gmVariable(m_vm->AllocStringObject("Clear"));
		m_clearFunc = drawManager->Get(clearKey).GetFunctionObjectSafe();
	}
}
Пример #18
0
void LeapController::UpdateHandsGM( gmTableObject* a_frame_table, const LeapFrame & a_frame )
{
    gmMachine* vm = &VirtualMachine::Ref().GetVM();
    ASSERT(vm);

    gmTableObject * hands_table = a_frame_table->Get(vm, "hands").GetTableObjectSafe();
    ASSERT(hands_table);
    gmTableObject * fingers_table = a_frame_table->Get(vm, "fingers").GetTableObjectSafe();
    ASSERT(fingers_table);

    // populate hands
    for( size_t i = 0; i < a_frame.hands.size(); ++i )
    {
        const LeapHand & hand = a_frame.hands[i];

        // create the finger
        gmTableObject * hand_obj = AllocFreeObj("pool_hands");

        // if none in pool
        if ( hand_obj == nullptr )
            continue;

        // populate finger ids
        gmTableObject * hand_obj_fingers_ids = hand_obj->Get( vm, "fingers" ).GetTableObjectSafe();
        hand_obj_fingers_ids->ClearTable(vm, false);

        // go through each hand
        ASSERT(hand.fingers_count >= 0);
        const int hand_num_fingers = min( hand.fingers_count, LEAP_MAX_NUM_FINGERS_PER_HAND );
        for ( int j = 0; j < hand_num_fingers; ++j )
        {
            int finger_index = hand.fingers_index[j];
            const LeapFinger & finger = a_frame.fingers[finger_index];
            int finger_id = finger.id;

            // grab finger object
            gmVariable finger_obj = fingers_table->Get(gmVariable(finger_id));

            // quick fix to ignore finger if null
            if ( finger_obj.IsNull() ) continue;
            ASSERT(!finger_obj.IsNull());

            // make sure the id doesnt already exist
            ASSERT( hand_obj_fingers_ids->Get(gmVariable(finger_id)).IsNull() );

            hand_obj_fingers_ids->Set(vm, gmVariable(finger_id), finger_obj );
        }

        hand_obj->Set( vm, "id", gmVariable( hand.id ) );
        hand_obj->Set( vm, "dir", gmVariable( hand.dir ) );
        hand_obj->Set( vm, "palm_normal", gmVariable( hand.palm_normal ) );
        hand_obj->Set( vm, "palm_pos", gmVariable( hand.palm_pos ) );
        hand_obj->Set( vm, "palm_vel", gmVariable( hand.palm_vel ) );
        hand_obj->Set( vm, "sphere_center", gmVariable( hand.sphere_center ) );
        hand_obj->Set( vm, "sphere_radius", gmVariable( hand.sphere_radius ) );
        hand_obj->Set( vm, "age", gmVariable( hand.age ) );
        hand_obj->Set( vm, "dist_to_boundary", gmVariable( hand.dist_to_boundary ) );

        hands_table->Set( vm, gmVariable(hand.id), gmVariable(hand_obj) );
    }
}
Пример #19
0
  / (_ / _ `/  ' \/ -_) /|_/ / _ \/ _ \/  '_/ -_) // /\ \/ __/ __/ / _ \/ __/
  \___/\_,_/_/_/_/\__/_/  /_/\___/_//_/_/\_\\__/\_, /___/\__/_/ /_/ .__/\__/
                                               /___/             /_/
                                             
  See Copyright Notice in gmMachine.h

*/

#include "gmConfig.h"
#include "gmVariable.h"
#include "gmThread.h"
#include "gmStringObject.h"
#include "gmUserObject.h"

// Init statics and constants
gmVariable gmVariable::s_null = gmVariable(GM_NULL, 0);


const char * gmVariable::AsString(gmMachine * a_machine, char * a_buffer, int a_len) const
{
  switch(m_type)
  {
    case GM_NULL : 
      _gmsnprintf(a_buffer, a_len, "null");
      break;
    case GM_INT :
      _gmsnprintf(a_buffer, a_len, "%d", m_value.m_int);
      break;
    case GM_FLOAT :
      _gmsnprintf(a_buffer, a_len, "%g", m_value.m_float);
      break;
Пример #20
0
void LeapController::UpdateGesturesGM( gmTableObject* a_frame_table, const LeapFrame & a_frame )
{
    gmMachine* vm = &VirtualMachine::Ref().GetVM();
    ASSERT(vm);

    gmTableObject * gestures_table = a_frame_table->Get(vm, "gestures").GetTableObjectSafe();
    ASSERT(gestures_table);

    // populate hands
    for( size_t i = 0; i < a_frame.gestures.size(); ++i )
    {
        const LeapGesture & gesture = a_frame.gestures[i];

        // create the finger
        gmTableObject * gesture_obj = AllocFreeObj("pool_gestures");

        // if none in pool
        if ( gesture_obj == nullptr )
            continue;

        gesture_obj->ClearTable(vm);

        // set basic gesture properties
        gesture_obj->Set( vm, "id", gmVariable( gesture.id ) );
        gesture_obj->Set( vm, "duration", gmVariable( gesture.duration ) );
        gesture_obj->Set( vm, "type", gmVariable( gesture.type ) );
        gesture_obj->Set( vm, "state", gmVariable( gesture.state ) );

        switch( gesture.type )
        {
        case LEAPGESTURE_CIRCLE:
        {
            gesture_obj->Set( vm, "finger_id", gmVariable( gesture.data.circle.finger_id ) );
            gesture_obj->Set( vm, "center", gmVariable( gesture.data.circle.center.toV3() ) );
            gesture_obj->Set( vm, "normal", gmVariable( gesture.data.circle.normal.toV3() ) );
            gesture_obj->Set( vm, "progress", gmVariable( gesture.data.circle.progress) );
            gesture_obj->Set( vm, "radius", gmVariable( gesture.data.circle.radius ) );
            break;
        }

        case LEAPGESTURE_SWIPE:
        {
            gesture_obj->Set( vm, "finger_id", gmVariable( gesture.data.swipe.finger_id ) );
            gesture_obj->Set( vm, "dir", gmVariable( gesture.data.swipe.dir.toV3() ) );
            gesture_obj->Set( vm, "pos", gmVariable( gesture.data.swipe.pos.toV3() ) );
            gesture_obj->Set( vm, "start_pos", gmVariable( gesture.data.swipe.start_pos.toV3() ) );
            gesture_obj->Set( vm, "speed", gmVariable( gesture.data.swipe.speed ) );
            break;
        }

        case LEAPGESTURE_SCREEN_TAP:
        {
            gesture_obj->Set( vm, "finger_id", gmVariable( gesture.data.screen_tap.finger_id ) );
            gesture_obj->Set( vm, "dir", gmVariable( gesture.data.screen_tap.dir.toV3() ) );
            gesture_obj->Set( vm, "pos", gmVariable( gesture.data.screen_tap.pos.toV3() ) );
            break;
        }

        case LEAPGESTURE_KEY_TAP:
        {
            gesture_obj->Set( vm, "finger_id", gmVariable( gesture.data.key_tap.finger_id ) );
            gesture_obj->Set( vm, "dir", gmVariable( gesture.data.key_tap.dir.toV3() ) );
            gesture_obj->Set( vm, "pos", gmVariable( gesture.data.key_tap.pos.toV3() ) );
            break;
        }

        default:
        {
            ASSERT(false);
        }
        }

        gestures_table->Set( vm, gmVariable(gesture.id), gmVariable(gesture_obj) );
    }
}
Пример #21
0
void OscHandler::UpdateAddressValues( gmMachine * a_vm )
{
	// an example address data is like:
	// "/address" = { value = v2(1.0f), age = 0.0f };

	ASSERT( m_socket.isOk() );

	const int timeout = 1;  /* timeout, in ms */
	
	while ( m_socket.receiveNextPacket( timeout ) ) 
	{
		m_packet_reader.init( m_socket.packetData(), m_socket.packetSize());
		oscpkt::Message *msg;

		while (m_packet_reader.isOk() && (msg = m_packet_reader.popMessage()) != 0) 
		{
			ASSERT(msg->isOk());

			// grab parameters
			const std::string & address = msg->addressPattern();
			const std::string & type_tags = msg->typeTags();
			oscpkt::Message::ArgReader arg_reader = msg->match( address );
			const size_t num_args = arg_reader.nbArgRemaining();
			
			// grab the table that corresponds to this address
			gmVariable address_table_var = m_data_table->Get( a_vm, address.c_str() );

			// if address not registered
			if ( address_table_var.IsNull() )
			{
				TRACE( "OSC address '%s' not registered!\n",  address.c_str() );
				continue;
			}

			// var at address must be be a table
			ASSERT( address_table_var.IsTable() );
			gmTableObject * address_table = address_table_var.GetTableObjectSafe();
			gmVariable curr_address_val = address_table->Get( a_vm, "val" );

			ASSERT( !curr_address_val.IsNull() );

			// result value
			gmVariable next_address_val;
			next_address_val.Nullify();

			if ( num_args == 0 ) continue;
			else if ( num_args == 1 ) // handle 1 arg
			{
				if ( arg_reader.isBool() )
				{
					bool val;
					arg_reader.popBool(val);
					next_address_val.SetInt( val ? 1 : 0 );
				}
				else if ( arg_reader.isInt32() )
				{
					int val;
					arg_reader.popInt32(val);
					next_address_val.SetInt( val );
				}
				else if ( arg_reader.isInt64() )
				{
					// downcasted 64->32 bit int
					int64_t val;
					arg_reader.popInt64(val);
					next_address_val.SetInt( (int)val );
				}
				else if ( arg_reader.isFloat() )
				{
					// downcasted 64->32 bit int
					float val;
					arg_reader.popFloat(val);
					next_address_val.SetFloat( val );
				}
				else if ( arg_reader.isDouble() )
				{
					// downcasted 64->32 bit
					double val;
					arg_reader.popDouble(val);
					next_address_val.SetFloat( (float)val );
				}

				else if ( arg_reader.isStr() )
				{
					std::string val;
					arg_reader.popStr(val);
					next_address_val.SetString( a_vm, val.c_str() );
				}
				else
				{
					TRACE("OSC unrecognzed arg type for of address '%s'", address.c_str(), num_args );
				}
			}
			else if ( num_args == 2 ) // can only be v2 or v2i
			{
				if ( type_tags == "ii" )
				{
					v2i result;

					if ( GetArgIntVal( arg_reader, result.x ) && GetArgIntVal( arg_reader, result.y ) )
					{
						next_address_val.SetV2i(result);
					}
					else
					{
						TRACE("OSC unable to grab v2i from address '%s'", address.c_str() );
					}
				}
				else
				{
					v2 result;

					if ( GetArgFloatOrIntVal( arg_reader, result.x ) && GetArgFloatOrIntVal( arg_reader, result.y ) )
					{
						next_address_val.SetV2(result);
					}
					else
					{
						TRACE("OSC unable to grab v2 from address '%s'", address.c_str() );
					}
				}
			}

			else if ( num_args == 3 ) // handle 3 args, should be v3()
			{
				v3 result;

				if ( GetArgFloatOrIntVal( arg_reader, result.x ) && GetArgFloatOrIntVal( arg_reader, result.y ) && GetArgFloatOrIntVal( arg_reader, result.z ) )
				{
					next_address_val.SetV3(result);
				}
				else
				{
					TRACE("OSC: unable to grab v3 from address '%s'", address.c_str() );
				}
			}
			else
			{
				TRACE("OSC: unrecognzed number of args for '%s': %d\n", address.c_str(), num_args );
			}

			if ( curr_address_val.GetType() != next_address_val.GetType() )
			{
				// was not able to grab value
				if ( next_address_val.IsNull() ) 
				{
					TRACE("OSC: unable to parse value for address '%s'\n", address.c_str() );
				}

				TRACE("OSC: address '%s' expected type '%s' but instead got '%s'\n", address.c_str(), a_vm->GetTypeName(curr_address_val.GetType()), a_vm->GetTypeName(next_address_val.GetType()) );
			}
			else
			{
				// set the address variable and reset the age timer
				address_table->Set( a_vm, "val", next_address_val );
				address_table->Set( a_vm, "age", gmVariable(0.0f) );
			}
		}
	}
}
Пример #22
0
bool ScriptCommandExecutor::Exec( const StringVector & args, const gmVariable &_this )
{
	const bool bPrintUsage = args.size() > 1 && args[ 1 ] == "?";
	if ( mCommandTable )
	{
		DisableGCInScope gcEn( mMachine );

		gmVariable vEntry = mCommandTable->Get( mMachine, args[ 0 ].c_str() );

		gmFunctionObject *pFn = vEntry.GetFunctionObjectSafe();
		if ( !pFn )
		{
			// See if it's new style, and in a table.
			gmTableObject *pTbl = vEntry.GetTableObjectSafe();
			if ( pTbl )
			{
				pFn = pTbl->Get( mMachine, "Func" ).GetFunctionObjectSafe();

				bool bRunImmediate = false;
				if ( !pTbl->Get( mMachine, "RunImmediate" ).GetBoolSafe( bRunImmediate, false ) )
					bRunImmediate = false;

				if ( bPrintUsage )
				{
					gmVariable vHelp = pTbl->Get( mMachine, "Help" );
					const char *pHelpString = vHelp.GetCStringSafe( 0 );
					if ( pHelpString )
					{
						EngineFuncs::ConsoleMessage( pHelpString );
					}
					else
					{
						gmTableObject *pUsageTbl = vHelp.GetTableObjectSafe();
						if ( pUsageTbl )
						{
							gmTableIterator tIt;
							gmTableNode *pNode = pUsageTbl->GetFirst( tIt );
							while ( pNode )
							{
								const char *pHelp = pNode->m_value.GetCStringSafe( 0 );
								if ( pHelp )
									EngineFuncs::ConsoleMessage( pHelp );
								pNode = pUsageTbl->GetNext( tIt );
							}
						}
					}
					return true;
				}
			}
		}
		if ( bPrintUsage )
		{
			EngineFuncs::ConsoleError( va( "No Usage Info For Command: %s", args[ 0 ].c_str() ) );
			return true;
		}

		if ( pFn )
		{
			gmCall call;
			if ( call.BeginFunction( mMachine, pFn, _this, true ) )
			{
				// Add all the params
				gmTableObject *pParamTable = mMachine->AllocTableObject();
				if ( args.size() > 1 )
				{
					for ( uint32_t i = 1; i < args.size(); ++i )
					{
						char *endPtr;
						const char *startPtr = args[ i ].c_str();
						long iNum = strtol( startPtr, &endPtr, 10 );
						double dNum;
						if ( endPtr != startPtr && !*endPtr )
						{
							pParamTable->Set( mMachine, i - 1, gmVariable( (int)iNum ) );
						}
						else if ( Utils::ConvertString( args[ i ], dNum ) )
						{
							pParamTable->Set( mMachine, i - 1, gmVariable( (float)dNum ) );
						}
						else
						{
							pParamTable->Set( mMachine, i - 1, gmVariable( mMachine->AllocStringObject( args[ i ].c_str() ) ) );
						}
					}
				}
				call.AddParamTable( pParamTable );
				call.End();
				return true;
			}
		}
		return false;
	}
	return false;
}