open source

This commit is contained in:
lvfulong
2020-11-11 16:17:13 +08:00
parent 4d989f3ecb
commit bc4ca748de
2441 changed files with 623057 additions and 2 deletions
+273
View File
@@ -0,0 +1,273 @@
/**
@file JCAudioManager.cpp
@brief
@author James
@version 1.0
@date 2014_11_26
*/
//包含头文件
#include "JCAudioManager.h"
#include "resource/Audio/JCWaveParser.h"
#include "util/Log.h"
#include "../JCConch.h"
namespace laya
{
//------------------------------------------------------------------------------
JCAudioManager* JCAudioManager::m_sAudioManager = NULL;
std::mutex JCAudioManager::m_mutex;
//------------------------------------------------------------------------------
JCAudioManager::JCAudioManager(JCFileResManager* pFileResManger)
{
m_bStopMp3 = false;
m_bMuteMp3 = false;
m_nVolumeMp3 = 1.0f;
createMp3player();
m_pWavPlayer = new JCAudioWavPlayer(pFileResManger);
}
//------------------------------------------------------------------------------
JCAudioManager::~JCAudioManager( void )
{
ClearAllAudioBufferPlay();
if( m_pMp3Player != NULL )
{
delete m_pMp3Player;
m_pMp3Player = NULL;
}
if( m_pWavPlayer != NULL )
{
m_pWavPlayer->ClearAllWaveInfo();
delete m_pWavPlayer;
m_pWavPlayer = NULL;
}
}
//------------------------------------------------------------------------------
void JCAudioManager::update()
{
m_pWavPlayer->checkWavePlayEnd();
}
//------------------------------------------------------------------------------
JCAudioManager* JCAudioManager::GetInstance( void )
{
if( m_sAudioManager == NULL )
{
std::lock_guard<std::mutex> lk(m_mutex);
m_sAudioManager = new JCAudioManager(JCConch::s_pConch->m_pFileResMgr);
}
return m_sAudioManager;
}
//------------------------------------------------------------------------------
void JCAudioManager::ClearAllWork(){
if( m_sAudioManager != NULL )
{
m_sAudioManager->m_bMuteMp3 = false;
JCAudioWavPlayer* pWavPlayer = m_sAudioManager->m_pWavPlayer;
if( pWavPlayer != NULL )
{
int nALCount = pWavPlayer->m_pOpenALSource.size();
for (int i = 0; i < nALCount; i++)
{
if( pWavPlayer->m_pOpenALSource[i]->m_bPlaying == true )
{
alSourceStop( pWavPlayer->m_pOpenALSource[i]->m_nOpenALSouceID );
pWavPlayer->m_pOpenALSource[i]->m_pAudio = NULL;
pWavPlayer->m_pOpenALSource[i]->m_bPlaying = false;
}
}
pWavPlayer->ClearAllWaveInfo();
}
m_sAudioManager->ClearAllAudioBufferPlay();
}
}
void JCAudioManager::DelInstance( void )
{
if( m_sAudioManager != NULL )
{
std::lock_guard<std::mutex> lk(m_mutex);
m_sAudioManager->m_pWavPlayer->ClearAllWaveInfo();
m_sAudioManager->ClearAllAudioBufferPlay();
delete m_sAudioManager;
m_sAudioManager = NULL;
}
}
//------------------------------------------------------------------------------
void JCAudioManager::createMp3player()
{
#ifdef WIN32
m_pMp3Player = new JCAudioMp3Player();
#elif ANDROID
m_pMp3Player = new JCAudioMp3Media();
#elif __APPLE__
m_pMp3Player = new JCAudioMp3Player();
#endif
}
//------------------------------------------------------------------------------
void JCAudioManager::setMp3Mute( bool p_bMute )
{
m_bMuteMp3 = p_bMute;
if( m_pMp3Player != NULL )
{
m_pMp3Player->setMute( p_bMute );
}
}
//------------------------------------------------------------------------------
bool JCAudioManager::getMp3Mute( void )
{
return m_bMuteMp3;
}
//------------------------------------------------------------------------------
bool JCAudioManager::getMp3Stopped()
{
return m_bStopMp3;
}
//------------------------------------------------------------------------------
void JCAudioManager::setMp3Volume( float p_nVolume )
{
m_nVolumeMp3 = p_nVolume;
if( m_pMp3Player != NULL )
{
m_pMp3Player->setVolume( p_nVolume );
}
}
//------------------------------------------------------------------------------
float JCAudioManager::getMp3Volume( void )
{
return m_nVolumeMp3;
}
//------------------------------------------------------------------------------
void JCAudioManager::playMp3( const char* p_sUrl,int p_nTimes, int nCurrentTime,JCAudioInterface* p_pJSAudio )
{
m_bStopMp3 = false;
//每次播放mp3都是重新new
if( m_pMp3Player == NULL )
{
createMp3player();
}
else
{
delete m_pMp3Player;
createMp3player();
}
if( m_pMp3Player == NULL )return;
m_pMp3Player->play( p_sUrl,p_nTimes, (float)nCurrentTime,p_pJSAudio );
if( m_bMuteMp3 )
{
m_pMp3Player->setMute(true);
}
else
{
m_pMp3Player->setVolume( (float)m_nVolumeMp3 );
}
}
void JCAudioManager::delMp3Obj(JCAudioInterface* p_pJSAudio)
{
if(m_pMp3Player)
m_pMp3Player->delAudio(p_pJSAudio);
}
//------------------------------------------------------------------------------
void JCAudioManager::pauseMp3()
{
LOGI("JCAudioManager::pauseMp3");
if( m_pMp3Player != NULL )
{
m_pMp3Player->pause();
}
}
//------------------------------------------------------------------------------
void JCAudioManager::stopMp3()
{
LOGI("JCAudioManager::stopMp3");
m_bStopMp3 = true;
if( m_pMp3Player != NULL )
{
m_pMp3Player->stop();
}
}
//------------------------------------------------------------------------------
void JCAudioManager::resumeMp3()
{
m_bStopMp3 = false;
if( m_pMp3Player != NULL )
{
m_pMp3Player->resume();
}
}
//------------------------------------------------------------------------------
OpenALSourceInfo* JCAudioManager::playWav(JCAudioInterface* p_pAudio, const std::string& p_sUrl, bool bIsOgg)
{
return m_pWavPlayer->playAudio(p_pAudio, p_sUrl, bIsOgg);
}
void JCAudioManager::stopWav(OpenALSourceInfo* pOpenALInfo)
{
m_pWavPlayer->stop(pOpenALInfo);
}
void JCAudioManager::stopAllWav()
{
m_pWavPlayer->stopAll();
}
void JCAudioManager::setWavVolume(OpenALSourceInfo* pOpenALInfo, float nVolume)
{
m_pWavPlayer->setVolume(pOpenALInfo, nVolume);
}
void JCAudioManager::setAllWavVolume(float nVolume)
{
m_pWavPlayer->setAllVolume(nVolume);
}
//------------------------------------------------------------------------------
bool JCAudioManager::ClearAllAudioBufferPlay( void )
{
return true;
}
//------------------------------------------------------------------------------
void JCAudioManager::delWav(JCAudioInterface* p_pAudio)
{
m_pWavPlayer->delAudio(p_pAudio);
}
//------------------------------------------------------------------------------
JCWaveInfo* JCAudioManager::AddWaveInfo( const std::string& p_sUrl,unsigned char* p_pBuffer,int p_nSize,const char* p_sFilePath,void* p_pExternalMark,bool p_bIsOgg )
{
return m_pWavPlayer->AddWaveInfo( p_sUrl,p_pBuffer,p_nSize,p_sFilePath,p_pExternalMark,p_bIsOgg );
}
//------------------------------------------------------------------------------
JCWaveInfo* JCAudioManager::AddWaveInfo( const std::string& p_sUrl,JCBuffer& p_pBuffer,int p_nSize,void* p_pExternalMark,bool p_bIsOgg )
{
return m_pWavPlayer->AddWaveInfo( p_sUrl,(unsigned char*)p_pBuffer.m_pPtr,p_nSize,NULL,p_pExternalMark,p_bIsOgg );
}
//------------------------------------------------------------------------------
JCWaveInfo* JCAudioManager::FindWaveInfo( const std::string& p_sUrl )
{
return m_pWavPlayer->FindWaveInfo( p_sUrl );
}
//------------------------------------------------------------------------------
void JCAudioManager::setCurrentTime(double nCurrentTime)
{
if( m_pMp3Player != NULL )
{
m_pMp3Player->setCurrentTime(nCurrentTime);
}
}
//------------------------------------------------------------------------------
double JCAudioManager::getCurrentTime()
{
if( m_pMp3Player != NULL )
{
return m_pMp3Player->getCurrentTime();
}
return 0.0f;
}
//------------------------------------------------------------------------------
double JCAudioManager::getDuration()
{
if( m_pMp3Player != NULL )
{
return m_pMp3Player->getDuration();
}
return 0.0f;
}
}
//-----------------------------END FILE--------------------------------
+146
View File
@@ -0,0 +1,146 @@
/**
@file JCAudioManager.h
@brief
@author James
@version 1.0
@date 2014_11_26
*/
#ifndef __JCAudioManager_H__
#define __JCAudioManager_H__
//包含头文件
#ifdef ANDROID
#include "android/JCAudioMp3Media.h"
#elif WIN32
#include "windows/JCAudioMp3Player.h"
#elif __APPLE__
#include "ios/JCAudioMp3Player.h"
#endif
#include "resource/Audio/JCAudioWavPlayer.h"
#include <map>
#include <vector>
#include "resource/Audio/JCWaveInfo.h"
#include "buffer/JCBuffer.h"
#include "resource/Audio/JCMp3Interface.h"
#include <mutex>
namespace laya
{
/**
* @brief
*/
class JCAudioManager
{
public:
/** @brief构造函数
*/
JCAudioManager( JCFileResManager* pFileResManger );
/** @brief析构函数
*/
~JCAudioManager( void );
/*
* getInstace()
*/
static JCAudioManager* GetInstance( void );
static void ClearAllWork();
static void DelInstance( void );
public:
//以下是mp3的接口
void createMp3player();
//设置全局的静音
void setMp3Mute( bool p_bMute );
//获得全局的静音
bool getMp3Mute( void );
//获得MP3是不是停止播放了
bool getMp3Stopped();
//全局音量
void setMp3Volume( float p_nVolume );
//获得音量
float getMp3Volume( void );
void playMp3( const char* p_sUrl,int p_nTimes,int nCurrentTime,JCAudioInterface* p_pJSAudio );
void delMp3Obj(JCAudioInterface* p_pJSAudio); //如果js对象删除了,就要调用这个
void pauseMp3();
void stopMp3();
void resumeMp3();
void setCurrentTime(double nCurrentTime);
double getCurrentTime();
double getDuration();
public:
/** @brief 清空所有
*/
bool ClearAllAudioBufferPlay( void );
/** @brief 播放声音
* @param[in] 声音interface
*/
OpenALSourceInfo* playWav(JCAudioInterface* p_pAudio, const std::string& p_sUrl,bool bIsOgg);
/** @brief 删除wav
* @param[in] 声音的interface
*/
void delWav(JCAudioInterface* p_pAudio);
void stopWav(OpenALSourceInfo* pOpenALInfo );
void stopAllWav();
void setWavVolume(OpenALSourceInfo* pOpenALInfo,float nVolume );
void setAllWavVolume( float nVolume );
/** @brief 添加资源
* @return
*/
JCWaveInfo* AddWaveInfo( const std::string& p_sUrl,unsigned char* p_pBuffer,int p_nSize,const char* p_sFilePath,void* p_pExternalMark,bool p_bIsOgg );
JCWaveInfo* AddWaveInfo( const std::string& p_sUrl,JCBuffer& p_pBuffer,int p_nSize,void* p_pExternalMark,bool p_bIsOgg );
JCWaveInfo* FindWaveInfo( const std::string& p_sUrl );
void update();
public:
JCMp3Interface* m_pMp3Player;
JCAudioWavPlayer* m_pWavPlayer; //播放wav
protected:
bool m_bMuteMp3; //MP3是否静音
float m_nVolumeMp3; //MP3的音量
bool m_bStopMp3; //是否停止了mp3的播放
protected:
static JCAudioManager* m_sAudioManager; //静态的this指针
static std::mutex m_mutex;
};
}
#endif //__JCAudioManager_H__
//-----------------------------END FILE--------------------------------
@@ -0,0 +1,123 @@
/**
@file JCAudioMp3Media.cpp
@brief
@author dt
@version 1.0
@date 2014_12_24
*/
//包含头文件
#include <vector>
#include "JCAudioMp3Media.h"
#include "util/Log.h"
#include "../../CToJavaBridge.h"
namespace laya
{
//------------------------------------------------------------------------------
JCAudioMp3Media::JCAudioMp3Media()
{
m_nCurrentVolume = 1.0;
m_pJSAudio = NULL;
}
//------------------------------------------------------------------------------
JCAudioMp3Media::~JCAudioMp3Media( void )
{
m_pJSAudio = NULL;
}
//------------------------------------------------------------------------------
void JCAudioMp3Media::play( const char* p_sUrl,int p_nTimes,float nCurrentTime,JCAudioInterface* p_pJSAudio )
{
m_pJSAudio = p_pJSAudio;
CToJavaBridge::JavaRet ret;
CToJavaBridge::GetInstance()->callMethod("layaair.game.utility.LayaAudioMusic", "playBackgroundMusic", p_sUrl, p_nTimes,(int)(nCurrentTime*1000),ret);
}
//------------------------------------------------------------------------------
void JCAudioMp3Media::delAudio( JCAudioInterface* p_pJSAudio )
{
if( m_pJSAudio == p_pJSAudio){
m_pJSAudio = NULL;
}
}
//------------------------------------------------------------------------------
void JCAudioMp3Media::pause()
{
CToJavaBridge::JavaRet ret;
CToJavaBridge::GetInstance()->callMethod("layaair.game.utility.LayaAudioMusic", "pauseBackgroundMusic", ret);
}
//------------------------------------------------------------------------------
void JCAudioMp3Media::stop()
{
CToJavaBridge::JavaRet ret;
CToJavaBridge::GetInstance()->callMethod("layaair.game.utility.LayaAudioMusic", "stopBackgroundMusic", ret);
m_pJSAudio = NULL;
}
//------------------------------------------------------------------------------
void JCAudioMp3Media::resume()
{
CToJavaBridge::JavaRet ret;
CToJavaBridge::GetInstance()->callMethod("layaair.game.utility.LayaAudioMusic", "resumeBackgroundMusic", ret);
}
//------------------------------------------------------------------------------
void JCAudioMp3Media::setVolume( float p_nVolume )
{
m_nCurrentVolume = p_nVolume;
/*if( p_nVolume < -10000 ) p_nVolume = -10000;
if( p_nVolume > 0 ) p_nVolume = 0;
p_nVolume = (p_nVolume+10000)/10000.0;*/
CToJavaBridge::JavaRet ret;
CToJavaBridge::GetInstance()->callMethod("layaair.game.utility.LayaAudioMusic", "setBackgroundMusicVolume",p_nVolume, ret);
}
//------------------------------------------------------------------------------
void JCAudioMp3Media::setMute( bool p_bMute )
{
if( p_bMute == true )
{
float nTemp = m_nCurrentVolume;
setVolume( 0.0f );
m_nCurrentVolume = nTemp;
}
else
{
setVolume( m_nCurrentVolume );
}
}
//------------------------------------------------------------------------------
void JCAudioMp3Media::onPlayEnd()
{
if( m_pJSAudio )
{
m_pJSAudio->onPlayEnd();
}
}
void JCAudioMp3Media::setCurrentTime(double nCurrentTime)
{
CToJavaBridge::JavaRet ret;
CToJavaBridge::GetInstance()->callMethod("layaair.game.utility.LayaAudioMusic", "setCurrentTime", (float)nCurrentTime, ret);
}
//------------------------------------------------------------------------------
double JCAudioMp3Media::getCurrentTime()
{
CToJavaBridge::JavaRet ret;
if (CToJavaBridge::GetInstance()->callMethod("layaair.game.utility.LayaAudioMusic", "getCurrentTime", ret, CToJavaBridge::JavaRet::RT_Float))
{
return (double)ret.floatRet;
}
return 0.0f;
}
//------------------------------------------------------------------------------
double JCAudioMp3Media::getDuration()
{
CToJavaBridge::JavaRet ret;
if (CToJavaBridge::GetInstance()->callMethod("layaair.game.utility.LayaAudioMusic", "getDuration", ret, CToJavaBridge::JavaRet::RT_Float))
{
return (double)ret.floatRet;
}
return 0.0f;
}
//------------------------------------------------------------------------------
}
//-----------------------------END FILE--------------------------------
@@ -0,0 +1,66 @@
/**
@file JCAudioMp3Play.h
@brief
@author dt
@version 1.0
@date 2014_12_24
*/
#ifndef __JCAudioMp3Media_H__
#define __JCAudioMp3Media_H__
//包含头文件
#include <stdio.h>
#include <string>
#include <string.h>
#include "resource/Audio/JCMp3Interface.h"
namespace laya
{
/**
* @brief
*/
class JCAudioMp3Media : public JCMp3Interface
{
public:
//构造函数
JCAudioMp3Media();
//析构函数
~JCAudioMp3Media( void );
void play( const char* p_sUrl,int p_nTimes,float nCurrentTime,JCAudioInterface* p_pJSAudio );
void delAudio( JCAudioInterface* p_pJSAudio );
void pause();
void stop();
void resume();
void setVolume( float p_nVolume );
void setMute( bool p_bMute );
void onPlayEnd();
void setCurrentTime(double nCurrentTime);
double getCurrentTime();
double getDuration();
private:
JCAudioInterface* m_pJSAudio;
float m_nCurrentVolume;
};
}
#endif //__JCAudioMp3Play_H__
//-----------------------------END FILE--------------------------------
@@ -0,0 +1,208 @@
/**
@file JCAudioMp3Player.cpp
@brief
@author wyw
@version 1.0
@date 2012_11_14
*/
//包含头文件
#include "JCAudioMp3Player.h"
#include <android/log.h>
#include "../../../util/Log.h"
#include "../JCAudioManager.h"
namespace laya
{
//------------------------------------------------------------------------------
JCAudioMp3Player::JCAudioMp3Player( const char* p_sFilePath )
{
m_pPlayerObject=NULL;
m_pPlayerPlay=NULL;
m_pPlayerSeek=NULL;
m_pPlayerMuteSolo=NULL;
m_pPlayerVolume=NULL;
m_sUrlName = p_sFilePath;
m_nCurrentVolume = 0;
m_bInit = false;
}
//------------------------------------------------------------------------------
JCAudioMp3Player::~JCAudioMp3Player( void )
{
shutdown();
}
//------------------------------------------------------------------------------
void JCAudioMp3Player::shutdown( void )
{
if( m_pPlayerObject != NULL )
{
(*m_pPlayerObject)->Destroy(m_pPlayerObject);
m_pPlayerObject = NULL;
m_pPlayerPlay = NULL;
m_pPlayerSeek = NULL;
m_pPlayerMuteSolo = NULL;
m_pPlayerVolume = NULL;
}
}
//------------------------------------------------------------------------------
bool JCAudioMp3Player::createAudioPlayer( std::string p_sUrl )
{
if( m_bInit == true ) return true;
m_bInit = true;
SLresult pResult;
//设置数据来源
SLchar* sUrl = (SLchar*)p_sUrl.c_str();
SLDataLocator_URI kLocUri = { SL_DATALOCATOR_URI, sUrl };
SLDataFormat_MIME kFormatMime = { SL_DATAFORMAT_MIME, NULL, SL_CONTAINERTYPE_UNSPECIFIED };
SLDataSource kAudioSrc = { &kLocUri, &kFormatMime };
//sink
#ifdef ANDROIDSLES
SLDataLocator_OutputMix loc_outmix = { SL_DATALOCATOR_OUTPUTMIX, JCAudioManager::GetInstance()->getMixObject() };
SLDataSink audioSnk = {&loc_outmix, NULL};
#endif
//创建声音
const SLInterfaceID ids[3] = {SL_IID_SEEK, SL_IID_MUTESOLO, SL_IID_VOLUME};
const SLboolean req[3] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE};
#ifdef ANDROIDSLES
pResult = (*JCAudioManager::GetInstance()->getEngine())->CreateAudioPlayer( JCAudioManager::GetInstance()->getEngine(), &m_pPlayerObject, &kAudioSrc,&audioSnk, 3, ids, req );
#endif
if( pResult != SL_RESULT_SUCCESS )
{
LOGE("createAudioPlayer err=CreateAudioPlayer");
return false;
}
//realize播放对象
pResult = (*m_pPlayerObject)->Realize(m_pPlayerObject, SL_BOOLEAN_FALSE);
if( pResult != SL_RESULT_SUCCESS )
{
(*m_pPlayerObject)->Destroy( m_pPlayerObject );
m_pPlayerObject = NULL;
LOGE("createAudioPlayer err=RealizePlayer");
return false;
}
//获得play
pResult = (*m_pPlayerObject)->GetInterface(m_pPlayerObject, SL_IID_PLAY, &m_pPlayerPlay);
if( pResult != SL_RESULT_SUCCESS )
{
LOGE("createAudioPlayer err=GetPlayer");
return false;
}
//获得seek
pResult = (*m_pPlayerObject)->GetInterface(m_pPlayerObject, SL_IID_SEEK, &m_pPlayerSeek);
if( pResult != SL_RESULT_SUCCESS )
{
LOGE("createAudioPlayer err=GetSeek");
return false;
}
//获得mutesolo
pResult = (*m_pPlayerObject)->GetInterface(m_pPlayerObject, SL_IID_MUTESOLO, &m_pPlayerMuteSolo);
if( pResult != SL_RESULT_SUCCESS )
{
LOGE("createAudioPlayer err=GetMuteSolo");
return false;
}
//获得设置音量的
pResult = (*m_pPlayerObject)->GetInterface(m_pPlayerObject, SL_IID_VOLUME, &m_pPlayerVolume);
if( pResult != SL_RESULT_SUCCESS )
{
LOGE("createAudioPlayer err=GetVolume");
return false;
}
return true;
}
//------------------------------------------------------------------------------
bool JCAudioMp3Player::setPlayingAudioPlayer( short p_nState )
{
if( m_bInit == false ) createAudioPlayer( m_sUrlName );
if (m_pPlayerPlay != NULL )
{
if( p_nState == SL_PLAYSTATE_PLAYING )
{
(*m_pPlayerPlay)->SetPlayState( m_pPlayerPlay, SL_PLAYSTATE_STOPPED );
(*m_pPlayerPlay)->SetPlayState( m_pPlayerPlay, SL_PLAYSTATE_PLAYING );
}
else
{
(*m_pPlayerPlay)->SetPlayState( m_pPlayerPlay, p_nState );
}
return true;
}
return false;
}
//------------------------------------------------------------------------------
bool JCAudioMp3Player::setLoopingAudioPlayer( bool p_bLoop )
{
if( m_bInit == false ) createAudioPlayer( m_sUrlName );
if ( m_pPlayerSeek != NULL )
{
(*m_pPlayerSeek)->SetLoop(m_pPlayerSeek, (SLboolean) p_bLoop, 0,SL_TIME_UNKNOWN);
return true;
}
return false;
}
//------------------------------------------------------------------------------
bool JCAudioMp3Player::setChannelMuteAudioPlayer( int p_nChannel,bool p_nMute )
{
if( m_bInit == false ) createAudioPlayer( m_sUrlName );
if ( m_pPlayerMuteSolo != NULL )
{
(*m_pPlayerMuteSolo)->SetChannelMute( m_pPlayerMuteSolo, p_nChannel, p_nMute );
return true;
}
return false;
}
//------------------------------------------------------------------------------
bool JCAudioMp3Player::setChannelSoloAudioPlayer( int p_nChannel,bool p_nSolo )
{
if( m_bInit == false ) createAudioPlayer( m_sUrlName );
if ( m_pPlayerMuteSolo != NULL )
{
(*m_pPlayerMuteSolo)->SetChannelSolo( m_pPlayerMuteSolo, p_nChannel, p_nSolo );
return true;
}
return false;
}
//------------------------------------------------------------------------------
bool JCAudioMp3Player::setVolumeAudioPlayer( int p_nVolume )
{
if( m_bInit == false ) createAudioPlayer( m_sUrlName );
m_nCurrentVolume = p_nVolume;
if ( m_pPlayerVolume != NULL )
{
(*m_pPlayerVolume)->SetVolumeLevel(m_pPlayerVolume, p_nVolume );
return true;
}
return false;
}
//------------------------------------------------------------------------------
bool JCAudioMp3Player::setMute( bool p_bMute )
{
if( m_bInit == false ) createAudioPlayer( m_sUrlName );
if ( m_pPlayerVolume != NULL )
{
(*m_pPlayerVolume)->SetMute(m_pPlayerVolume, p_bMute );
if( p_bMute == true )
{
(*m_pPlayerVolume)->SetVolumeLevel(m_pPlayerVolume, -10000 );
}
else
{
(*m_pPlayerVolume)->SetVolumeLevel(m_pPlayerVolume, m_nCurrentVolume );
}
return true;
}
return false;
}
//------------------------------------------------------------------------------
}
//-----------------------------END FILE--------------------------------
@@ -0,0 +1,83 @@
/**
@file JCAudioMp3Play.h
@brief
@author wyw
@version 1.0
@date 2012_11_14
*/
#ifndef __JCAudioMp3Player_H__
#define __JCAudioMp3Player_H__
//包含头文件
#include <stdio.h>
#include <string>
#include <string.h>
#include <SLES/OpenSLES.h>
#include <SLES/OpenSLES_Android.h>
#include <sys/types.h>
namespace laya
{
/**
* @brief
*/
class JCAudioMp3Player
{
public:
//构造函数
JCAudioMp3Player( const char* p_sFilePath );
//析构函数
~JCAudioMp3Player( void );
//释放资源
void shutdown( void );
//创建player
bool createAudioPlayer( std::string p_sUrl );
//设置播放
bool setPlayingAudioPlayer( short p_nState );
//设置是否循环
bool setLoopingAudioPlayer( bool p_bLoop );
//设置左右声道的静音
bool setChannelMuteAudioPlayer( int p_nChannel,bool p_nMute );
//设置左右声道是否独唱
bool setChannelSoloAudioPlayer( int p_nChannel,bool p_nSolo );
//设置音量
bool setVolumeAudioPlayer( int p_nVolume );
//设置静音
bool setMute( bool p_bMute );
protected:
bool m_bInit; //是否初始化
std::string m_sUrlName; //url
SLObjectItf m_pPlayerObject; //播放声音的object
SLPlayItf m_pPlayerPlay; //播放用的
SLSeekItf m_pPlayerSeek; //设置是否循环用的
SLMuteSoloItf m_pPlayerMuteSolo; //设置静音 独唱等用的
SLVolumeItf m_pPlayerVolume; //设置音量用的
int m_nCurrentVolume; //当前音量,为了解决三星设置静音不好用的问题
};
}
#endif //__JCAudioMp3Play_H__
//-----------------------------END FILE--------------------------------
@@ -0,0 +1,110 @@
/**
@file JCAudioMp3Media.cpp
@brief
@author dt
@version 1.0
@date 2014_12_24
*/
//包含头文件
#include "JCAudioMp3Player.h"
#include "util/Log.h"
#include "CToObjectC.h"
namespace laya
{
//------------------------------------------------------------------------------
JCAudioMp3Player::JCAudioMp3Player()
{
m_nCurrentVolume = 1.0;
m_pJSAudio = NULL;
}
//------------------------------------------------------------------------------
JCAudioMp3Player::~JCAudioMp3Player( void )
{
m_pJSAudio = NULL;
}
//------------------------------------------------------------------------------
void JCAudioMp3Player::play( const char* p_sUrl,int p_nTimes,float nCurrentTime,JCAudioInterface* p_pJSAudio )
{
m_pJSAudio = p_pJSAudio;
CToObjectCPlayMp3Audio( p_sUrl,p_nTimes,nCurrentTime );
}
//------------------------------------------------------------------------------
void JCAudioMp3Player::delAudio( JCAudioInterface* p_pJSAudio )
{
if( m_pJSAudio == p_pJSAudio)
{
m_pJSAudio = NULL;
}
}
//------------------------------------------------------------------------------
void JCAudioMp3Player::pause()
{
CToObjectCPauseMp3();
}
//------------------------------------------------------------------------------
void JCAudioMp3Player::stop()
{
m_pJSAudio = NULL;
CToObjectCStopMp3();
}
//------------------------------------------------------------------------------
void JCAudioMp3Player::resume()
{
CToObjectCResumeMp3();
}
//------------------------------------------------------------------------------
void JCAudioMp3Player::setVolume( float p_nVolume )
{
m_nCurrentVolume = p_nVolume;
/*
if( p_nVolume < -10000 ) p_nVolume = -10000;
if( p_nVolume >0 ) p_nVolume = 0;
//10000 到 0 ,转换到 0 - 1
float nVolume = (p_nVolume+10000)/10000.0;
*/
CToObjectCSetMp3Volume( p_nVolume );
}
//------------------------------------------------------------------------------
void JCAudioMp3Player::setMute( bool p_bMute )
{
if( p_bMute == true )
{
float nTemp = m_nCurrentVolume;
setVolume( 0.0f );
m_nCurrentVolume = nTemp;
}
else
{
setVolume( m_nCurrentVolume );
}
}
//------------------------------------------------------------------------------
void JCAudioMp3Player::onPlayEnd()
{
if( m_pJSAudio )
{
m_pJSAudio->onPlayEnd();
}
}
void JCAudioMp3Player::setCurrentTime(double nCurrentTime)
{
CToObjectCSetCurrentTime(nCurrentTime);
}
//------------------------------------------------------------------------------
double JCAudioMp3Player::getCurrentTime()
{
return CToObjectCGetCurrentTime();
}
//------------------------------------------------------------------------------
double JCAudioMp3Player::getDuration()
{
return CToObjectCGetDuration();
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
}
//-----------------------------END FILE--------------------------------
@@ -0,0 +1,66 @@
/**
@file JCAudioMp3Player.h
@brief
@author wyw
@version 1.0
@date 2015_6_2
*/
#ifndef __JCAudioMp3Player_H__
#define __JCAudioMp3Player_H__
//包含头文件
#include <stdio.h>
#include <string>
#include "CToObjectC.h"
#include "resource/Audio/JCMp3Interface.h"
namespace laya
{
/**
* @brief
*/
class JCAudioMp3Player : public JCMp3Interface
{
public:
//构造函数
JCAudioMp3Player();
//析构函数
~JCAudioMp3Player( void );
void play( const char* p_sUrl,int p_nTimes,float nCurrentTime,JCAudioInterface* p_pJSAudio );
void delAudio( JCAudioInterface* p_pJSAudio );
void pause();
void stop();
void resume();
void setVolume( float p_nVolume );
void setMute( bool p_bMute );
void onPlayEnd();
void setCurrentTime(double nCurrentTime);
double getCurrentTime();
double getDuration();
private:
JCAudioInterface* m_pJSAudio;
float m_nCurrentVolume;
};
}
#endif //__JCAudioMp3Play_H__
//-----------------------------END FILE--------------------------------
@@ -0,0 +1,95 @@
/**
@file JCAudioMp3Player.h
@brief
@author James
@version 1.0
@date 2014_11_26
*/
#ifndef __JCAudioMp3Player_H__
#define __JCAudioMp3Player_H__
//包含头文件
#include <windows.h>
#include <xaudio2.h>
#include <strsafe.h>
#include <shellapi.h>
#include <mmsystem.h>
#include <conio.h>
#include <stdio.h>
#include <dshow.h>
#include "resource/Audio/JCMp3Interface.h"
#include <string>
namespace laya
{
class JCAudioMp3Player : public JCMp3Interface
{
public:
JCAudioMp3Player();
~JCAudioMp3Player();
bool Mp3Init();
void release();
public:
void play( const char* p_sUrl,int p_nTimes,float nCurrentTime,JCAudioInterface* p_pJSAudio );
void delAudio( JCAudioInterface* p_pJSAudio );
void setVolume( float p_nVolume );
void pause();
void stop();
void resume();
void setMute(bool p_bMute);
void onPlayEnd();
void setCurrentTime(double nCurrentTime);
double getCurrentTime();
double getDuration();
private:
friend DWORD WINAPI handleMp3ListenerThread( void* p_pParam );
void releaseThread();
public:
IGraphBuilder* m_pGraphBuilder;
IMediaControl* m_pMediaControl;
IMediaEvent* m_pMediaEvent;
IMediaPosition* m_pMediaPos;
IBasicAudio* m_pBasicAudio;
IMediaSeeking* m_pMediaSeeking;
public:
DWORD m_nNotifyThreadID;
HANDLE m_hNotifyThread;
private:
std::string m_sUrl;
int m_nPlayTimes;
int m_nPlayCount;
double m_fPos;
float m_fCurrentVolume;
};
}
#endif //__JCAudioMp3Player_H__
//-----------------------------END FILE--------------------------------
@@ -0,0 +1,225 @@
/**
@file JCAudioMp3Player.cpp
@brief
@author James
@version 1.0
@date 2014_11_26
*/
#include "JCAudioMp3Player.h"
#include "util/JCCommonMethod.h"
//------------------------------------------------------------------------------
namespace laya
{
//------------------------------------------------------------------------------
JCAudioMp3Player::JCAudioMp3Player()
{
m_pGraphBuilder = NULL;
m_pMediaControl = NULL;
m_pMediaEvent = NULL;
m_pMediaPos = NULL;
m_pBasicAudio = NULL;
m_pMediaSeeking = NULL;
m_nPlayTimes = -1;
m_sUrl = "";
m_nPlayCount = 0;
m_fPos = 0;
m_nNotifyThreadID = 0;
m_fCurrentVolume = 1;
}
//------------------------------------------------------------------------------
JCAudioMp3Player::~JCAudioMp3Player()
{
release();
}
//------------------------------------------------------------------------------
DWORD WINAPI handleMp3ListenerThread( void* p_pParam )
{
JCAudioMp3Player* pThis =(JCAudioMp3Player*)p_pParam;
if( pThis->m_nPlayTimes == 1 ) return -1;
MSG msg;
while( true )
{
PeekMessage( &msg, NULL, 0, 0, PM_REMOVE );
if( msg.message == WM_QUIT )
{
return 0;
}
long nEventCode, param1, param2;
if( SUCCEEDED( pThis->m_pMediaEvent->GetEvent( &nEventCode, &param1, &param2, 1 ) ) )
{
if( pThis->m_nPlayTimes == -1 )
{
if( nEventCode == EC_COMPLETE )
{
pThis->m_pMediaPos-> put_CurrentPosition(0);
}
}
else if( pThis->m_nPlayTimes > 1 )
{
if(nEventCode == EC_COMPLETE)
{
pThis->m_nPlayCount++;
if( pThis->m_nPlayCount >= pThis->m_nPlayTimes )
{
return 0;
}
pThis->m_pMediaPos-> put_CurrentPosition(0);
}
}
}
pThis->m_pMediaEvent->FreeEventParams( nEventCode, param1, param2 );
Sleep( 500 );
}
return 0;
}
//------------------------------------------------------------------------------
bool JCAudioMp3Player::Mp3Init()
{
CoInitialize(0);
if( FAILED( CoCreateInstance( CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void**)&m_pGraphBuilder) ) )
{
return FALSE;
}
m_pGraphBuilder->QueryInterface(IID_IMediaControl, (void**)&m_pMediaControl);
m_pGraphBuilder->QueryInterface(IID_IMediaEvent, (void**)&m_pMediaEvent);
m_pGraphBuilder->QueryInterface(IID_IMediaPosition, (void**)&m_pMediaPos);
m_pGraphBuilder->QueryInterface(IID_IBasicAudio,(void **)&m_pBasicAudio);
m_pGraphBuilder->QueryInterface(IID_IMediaSeeking,(void **)&m_pMediaSeeking);
return true;
if( m_nNotifyThreadID == 0 )
{
//´´½¨Ò»¸öÏ߳̽ÓÊÕnotifyÏûÏ¢
m_hNotifyThread = CreateThread( NULL, 0, handleMp3ListenerThread, this, 0, &m_nNotifyThreadID );
}
return true;
}
//------------------------------------------------------------------------------
void JCAudioMp3Player::play( const char* p_sUrl,int p_nTimes, float nCurrentTime,JCAudioInterface* p_pJSAudio )
{
m_sUrl = p_sUrl;
Mp3Init();
m_nPlayCount = 0;
m_nPlayTimes = p_nTimes;
WCHAR sWfilename[MAX_PATH] = {0};
mbstowcs( sWfilename, p_sUrl, MAX_PATH );
m_pMediaControl->RenderFile( sWfilename );
m_pMediaControl->Run();
}
void JCAudioMp3Player::delAudio( JCAudioInterface* p_pJSAudio ){
}
//------------------------------------------------------------------------------
void JCAudioMp3Player::pause()
{
if( m_pMediaControl != NULL )
{
m_pMediaPos->get_CurrentPosition( &m_fPos );
m_pMediaControl->Pause();
}
}
//------------------------------------------------------------------------------
void JCAudioMp3Player::resume()
{
if( m_pMediaControl != NULL )
{
m_pMediaPos->get_CurrentPosition( &m_fPos );
m_pMediaControl->Run();
}
}
//------------------------------------------------------------------------------
void JCAudioMp3Player::stop()
{
if( m_pMediaControl != NULL )
{
m_pMediaControl->Stop();
}
}
//------------------------------------------------------------------------------
void JCAudioMp3Player::setVolume( float p_nVolume )
{
p_nVolume=p_nVolume*10000.0f-10000.0f;
m_fCurrentVolume = p_nVolume;
if( m_pBasicAudio != NULL )
{
m_pBasicAudio->put_Volume( (long)p_nVolume );
}
}
//------------------------------------------------------------------------------
void JCAudioMp3Player::setMute(bool p_bMute)
{
if( m_pBasicAudio != NULL )
{
m_pBasicAudio->put_Volume( (long)(p_bMute?-10000:m_fCurrentVolume) );
}
}
//------------------------------------------------------------------------------
void JCAudioMp3Player::releaseThread()
{
if( m_nNotifyThreadID != 0 )
{
PostThreadMessage( m_nNotifyThreadID, WM_QUIT, 0, 0 );
WaitForSingleObject( m_hNotifyThread, INFINITE );
CloseHandle( m_hNotifyThread );
}
}
//------------------------------------------------------------------------------
void JCAudioMp3Player::release()
{
releaseThread();
m_fPos = 0;
m_nPlayCount = 0;
if( m_pMediaControl )
{
m_pMediaControl->Stop();
}
if( m_pMediaEvent )
{
m_pMediaEvent->Release();
m_pMediaEvent = NULL;
}
if( m_pMediaControl )
{
m_pMediaControl->Release();
m_pMediaControl = NULL;
}
if( m_pMediaPos )
{
m_pMediaPos->Release();
m_pMediaPos = NULL;
}
if( m_pBasicAudio )
{
m_pBasicAudio->Release();
m_pBasicAudio = NULL;
}
if( m_pGraphBuilder )
{
m_pGraphBuilder->Release();
m_pGraphBuilder = NULL;
}
CoUninitialize();
}
//------------------------------------------------------------------------------
void JCAudioMp3Player::onPlayEnd()
{
}
void JCAudioMp3Player::setCurrentTime(double nCurrentTime)
{
}
double JCAudioMp3Player::getCurrentTime()
{
return 0.0f;
}
double JCAudioMp3Player::getDuration()
{
return 0.0f;
}
//------------------------------------------------------------------------------
}
//-----------------------------END FILE--------------------------------
@@ -0,0 +1,685 @@
"\x00\x00\xfd\xff\x01\x00\x01\x00\xf9\xff\xfb\xff\x02\x00\x05\x00"
"\x01\x00\x03\x00\x06\x00\x0a\x00\x0a\x00\x09\x00\x04\x00\x04\x00"
"\x06\x00\x06\x00\x00\x00\xff\xff\x05\x00\x08\x00\x01\x00\xfe\xff"
"\xff\xff\x03\x00\x04\x00\xfe\xff\xf9\xff\xfd\xff\x04\x00\xfe\xff"
"\x03\x00\x04\x00\x01\x00\xfb\xff\xfb\xff\xfc\xff\xfb\xff\x03\x00"
"\xfc\xff\xf9\xff\xfc\xff\x01\x00\x06\x00\x00\x00\xf9\xff\xfa\xff"
"\x04\x00\x06\x00\xfe\xff\xfa\xff\xfd\xff\x01\x00\xfe\xff\xfe\xff"
"\xfe\xff\xfd\xff\xfd\xff\xfd\xff\xfe\xff\xff\xff\xfd\xff\xfa\xff"
"\xfe\xff\x00\x00\x03\x00\xfe\xff\xfc\xff\xfb\xff\xfe\xff\x01\x00"
"\x02\x00\x01\x00\xff\xff\x09\x00\x0c\x00\x10\x00\x07\x00\x07\x00"
"\x04\x00\x00\x00\x02\x00\xf5\xff\xf7\xff\x02\x00\x08\x00\xfe\xff"
"\xfe\xff\x05\x00\x06\x00\x05\x00\x00\x00\xfb\xff\xf9\xff\xf6\xff"
"\xf7\xff\xfd\xff\x02\x00\xff\xff\xff\xff\x08\x00\x07\x00\x08\x00"
"\x04\x00\xfe\xff\x02\x00\x0b\x00\x0c\x00\x05\x00\x04\x00\x03\x00"
"\xfe\xff\xfe\xff\xfb\xff\xf3\xff\xe8\xff\xee\xff\xfd\xff\x04\x00"
"\xfc\xff\x00\x00\x01\x00\xff\xff\xfe\xff\xf2\xff\xf3\xff\xfa\xff"
"\x04\x00\xf7\xff\xfe\xff\x09\x00\x0d\x00\x0b\x00\x08\x00\x01\x00"
"\xff\xff\x0c\x00\x0b\x00\x07\x00\x01\x00\x05\x00\x08\x00\x0b\x00"
"\x05\x00\xfe\xff\xf6\xff\xf9\xff\xfb\xff\xfa\xff\xf8\xff\x02\x00"
"\x05\x00\x06\x00\x01\x00\x00\x00\x0c\x00\x0b\x00\x02\x00\xf8\xff"
"\x01\x00\xfb\xff\xfa\xff\x06\x00\x07\x00\xfb\xff\x02\x00\x06\x00"
"\x00\x00\x01\x00\x04\x00\xf4\xff\xfa\xff\x00\x00\xf8\xff\xf6\xff"
"\x02\x00\xfd\xff\xf0\xff\xfe\xff\x00\x00\xff\xff\xfc\xff\x00\x00"
"\xf6\xff\x01\x00\x08\x00\x03\x00\xfc\xff\x06\x00\x0d\x00\x01\x00"
"\x04\x00\x05\x00\x01\x00\xf7\xff\xff\xff\xfc\xff\xff\xff\x03\x00"
"\x00\x00\xfc\xff\x06\x00\x07\x00\xff\xff\xfa\xff\xfa\xff\x02\x00"
"\x00\x00\x00\x00\xf5\xff\xfa\xff\xff\xff\x06\x00\xfc\xff\xf9\xff"
"\xff\xff\x04\x00\x08\x00\x06\x00\x01\x00\xf7\xff\xfe\xff\xfc\xff"
"\xfe\xff\x02\x00\x07\x00\xfb\xff\xfc\xff\x08\x00\x0b\x00\x05\x00"
"\x0a\x00\x08\x00\x00\x00\x08\x00\x11\x00\x0e\x00\xfd\xff\xf1\xff"
"\xef\xff\xfe\xff\x02\x00\xf8\xff\xf2\xff\xfb\xff\xfe\xff\x0a\x00"
"\xfd\xff\xfa\xff\xf9\xff\xee\xff\xf7\xff\xff\xff\x05\x00\xfc\xff"
"\xf6\xff\xfd\xff\x0f\x00\x0a\x00\x05\x00\xf7\xff\xf5\xff\xf8\xff"
"\x09\x00\x10\x00\xff\xff\xfd\xff\xf4\xff\xff\xff\xfe\xff\xff\xff"
"\xfe\xff\xef\xff\xfa\xff\x06\x00\x17\x00\x11\x00\x13\x00\x11\x00"
"\xfe\xff\x05\x00\x0b\x00\xfe\xff\xee\xff\x07\x00\x0b\x00\xff\xff"
"\x01\x00\x0b\x00\x0a\x00\x08\x00\x0b\x00\x02\x00\xf4\xff\xfa\xff"
"\x0c\x00\x00\x00\x03\x00\x09\x00\xf5\xff\xf6\xff\x06\x00\xfc\xff"
"\xf0\xff\xff\xff\x05\x00\xf0\xff\x0a\x00\x23\x00\x08\x00\xfd\xff"
"\x03\x00\xf7\xff\xee\xff\x03\x00\xfc\xff\xe2\xff\xf4\xff\xfe\xff"
"\xff\xff\x10\x00\x19\x00\xf6\xff\xe7\xff\xf6\xff\xf3\xff\xe5\xff"
"\xee\xff\xea\xff\xdc\xff\xf3\xff\xf9\xff\x02\x00\x02\x00\x00\x00"
"\xe6\xff\xef\xff\x02\x00\x09\x00\x09\x00\x0b\x00\x09\x00\x00\x00"
"\x08\x00\x07\x00\x11\x00\x12\x00\x1a\x00\x17\x00\x2f\x00\x35\x00"
"\x2c\x00\x2d\x00\x20\x00\x03\x00\x02\x00\x12\x00\x0e\x00\x11\x00"
"\x21\x00\x1d\x00\x13\x00\x25\x00\x1c\x00\x05\x00\xf9\xff\xf4\xff"
"\xdd\xff\xf1\xff\x0c\x00\x15\x00\x1d\x00\x32\x00\x2a\x00\x1a\x00"
"\x1f\x00\xfe\xff\xcf\xff\xcf\xff\xeb\xff\xde\xff\xf4\xff\x03\x00"
"\x00\x00\x10\x00\x17\x00\xf0\xff\xcc\xff\xc7\xff\x8c\xff\x58\xff"
"\x5c\xff\x4e\xff\x0f\xff\xf6\xfe\xd6\xfe\xb5\xfe\xc5\xfe\xd6\xfe"
"\xe1\xfe\x08\xff\x5e\xff\x9a\xff\xe2\xff\x43\x00\x92\x00\xca\x00"
"\x10\x01\x32\x01\x42\x01\x6c\x01\x7e\x01\x72\x01\x6e\x01\x71\x01"
"\x56\x01\x53\x01\x53\x01\x30\x01\x05\x01\xfb\x00\xca\x00\x8c\x00"
"\x62\x00\x1b\x00\xbe\xff\x8e\xff\x67\xff\x40\xff\x44\xff\x61\xff"
"\x6a\xff\x80\xff\xab\xff\xb4\xff\xc6\xff\xca\xff\xb2\xff\x80\xff"
"\x79\xff\x6f\xff\x7d\xff\xa1\xff\xb5\xff\xb4\xff\xe1\xff\xfb\xff"
"\x0c\x00\x1e\x00\x30\x00\x16\x00\xfe\xff\xf4\xff\xe8\xff\xef\xff"
"\xbf\xff\x85\xff\xf1\xfe\x8a\xfe\x08\xfe\xca\xfd\x68\xfd\x26\xfd"
"\xd2\xfc\xe2\xfc\x88\xfd\xb4\xfe\x28\x00\x6c\x01\xa8\x02\x51\x03"
"\xb6\x03\x8a\x03\x0f\x03\x00\x02\x11\x01\x34\x00\xed\xff\x2d\x00"
"\x01\x01\xdc\x01\xb0\x02\x38\x03\x22\x03\xbb\x02\xf8\x01\x1e\x01"
"\xfb\xff\x1f\xff\x2d\xfe\xb0\xfd\x80\xfd\xbb\xfd\x0e\xfe\xac\xfe"
"\x3b\xff\xb0\xff\x13\x00\x58\x00\x82\x00\x81\x00\x73\x00\x01\x00"
"\xa3\xff\x2f\xff\xf6\xfe\xc5\xfe\x12\xff\x5d\xff\xee\xff\x7a\x00"
"\xff\x00\x56\x01\xa1\x01\x90\x01\x17\x01\x8f\x00\xc5\xff\xf5\xfe"
"\x20\xfe\xa3\xfd\x1a\xfd\xe4\xfc\xe0\xfc\xfe\xfc\x3c\xfd\xca\xfd"
"\x1b\xfe\xa0\xfe\x0b\xff\xbf\xff\xfc\xff\xbb\x00\x01\x01\x7d\x01"
"\xed\x01\x5c\x02\xa0\x02\xac\x02\xd3\x02\x5c\x02\x42\x02\xc1\x01"
"\xb7\x01\x4b\x01\x9e\x01\x4c\x01\x60\x01\xf1\x00\xbc\x00\xff\xff"
"\x89\xff\xf7\xfe\x72\xfe\x21\xfe\xe5\xfd\xf6\xfd\xfe\xfd\xcb\xfe"
"\x3f\xff\x10\x00\x65\x00\xec\x00\xc1\x00\xe9\x00\xa9\x00\xa0\x00"
"\x86\x00\xb3\x00\xc7\x00\xf4\x00\x27\x01\x42\x01\x41\x01\x22\x01"
"\xfb\x00\xac\x00\x7a\x00\x49\x00\x19\x00\xf6\xff\xd6\xff\x82\xff"
"\x20\xff\xdc\xfe\x7d\xfe\xec\xfd\x8f\xfd\x31\xfd\x05\xfd\x8c\xfc"
"\x7a\xfc\xcb\xfb\x94\xfb\x71\xfb\xe9\xfb\xb7\xfc\x67\xfe\x20\x00"
"\xd7\x01\x78\x03\x76\x04\xb6\x04\x40\x04\x97\x03\x32\x02\x2c\x01"
"\x57\x00\x49\x00\x87\x00\xb4\x01\xa1\x02\x84\x03\xea\x03\xe3\x03"
"\x11\x03\x15\x02\xc9\x00\x49\xff\xfd\xfd\xde\xfc\x50\xfc\x49\xfc"
"\x22\xfd\x0a\xfe\x55\xff\x29\x00\xb0\x00\x9b\x00\xa6\x00\x5a\x00"
"\x51\x00\x30\x00\x18\x00\xe5\xff\xdc\xff\xe5\xff\x29\x00\xa3\x00"
"\x27\x01\xaa\x01\xfa\x01\xec\x01\xa2\x01\x39\x01\xb5\x00\x3a\x00"
"\xc2\xff\x35\xff\x9f\xfe\x6e\xfe\x27\xfe\x54\xfe\x7b\xfe\x0e\xff"
"\x29\xff\x62\xff\x4d\xff\xc7\xff\x29\xff\xe1\xff\xb6\xff\x6d\x00"
"\xe0\xff\xd8\x00\x1a\x00\x92\x00\xce\xfe\x16\xfe\x8c\xfb\x76\xf5"
"\x4e\xf5\xf5\xf3\x3a\xf8\x59\xfc\x7e\x04\xd5\x07\x35\x0d\x3e\x0e"
"\x34\x0d\xcf\x09\xe1\x04\xe2\xfe\x5e\xf9\xb5\xf6\x01\xf5\x0f\xf8"
"\x37\xfb\x42\x01\x82\x05\x2a\x0b\x35\x0d\xcb\x0e\x1b\x0c\x3c\x08"
"\x47\x01\x1c\xfb\x82\xf5\x95\xf2\xab\xf2\x76\xf5\x3c\xfa\x42\xff"
"\x72\x04\xd0\x07\x77\x0a\xb7\x0a\x00\x0a\x88\x06\x30\x02\x0d\xfc"
"\x7a\xf6\xef\xf1\x1d\xf1\xad\xf2\xb5\xf7\x05\xfe\x5c\x04\xed\x08"
"\x41\x0b\xe1\x0a\x16\x08\x89\x04\x10\x00\x2b\xfc\x78\xf9\x94\xf8"
"\x18\xf9\xa9\xfb\x51\xfe\x6d\x01\x74\x03\x95\x04\x83\x04\xd8\x03"
"\x70\x02\x75\x01\x98\x00\xe5\xff\x52\xff\xee\xfe\x27\xfe\x2e\xfe"
"\x21\xfe\x80\xfe\xef\xff\xbf\x00\xea\x00\x2b\x01\xf6\xff\x99\xfd"
"\xd9\xfc\x1c\xfb\xc9\xf9\xb5\xf8\xb9\xf9\x1b\xf8\xf1\xfa\x93\xfd"
"\xf1\x00\xdf\x04\xc5\x07\xaf\x08\x27\x08\xb0\x07\xbf\x04\x9c\x03"
"\x48\x01\xfa\xff\x48\xfe\x8c\xfe\x4d\xfe\x46\x00\x2a\x02\x76\x04"
"\xf0\x05\x0b\x07\x82\x06\x3f\x05\x56\x03\x85\x00\xb2\xfd\xb0\xfa"
"\x90\xf8\x06\xf7\x71\xf7\xc5\xf8\xda\xfb\xea\xfe\x36\x02\x40\x04"
"\xbd\x04\x9c\x03\x88\x01\xb2\xfe\x03\xfc\x27\xfa\x8c\xf9\xaf\xf9"
"\xaf\xfb\xde\xfd\x7a\x00\x01\x03\xcf\x04\xa4\x05\xcd\x05\xfd\x04"
"\x7f\x03\x2b\x02\xb3\x00\x8f\xff\x29\xff\xdd\xfe\x91\xfe\xd1\xfe"
"\xc4\xfe\x0e\xff\xcd\xff\x94\x00\xdd\x00\x9e\x01\xb5\x01\xbc\x01"
"\x82\x01\x62\x01\x5a\x00\x44\x00\x39\x00\x00\x00\x95\x00\x74\xff"
"\x9f\xfd\x1c\xfb\x77\xf7\xc7\xf4\x18\xf3\xf3\xf3\x37\xf7\x8f\xfc"
"\x4c\x03\x54\x09\x4a\x0e\x10\x10\x74\x0f\x65\x0b\x13\x06\xe6\xff"
"\x85\xfa\x9e\xf6\x44\xf5\xea\xf5\xcd\xf8\x5d\xfd\x67\x02\xd1\x07"
"\xe7\x0b\x63\x0e\x35\x0e\xb0\x0b\x99\x06\xa4\x00\x6c\xfa\x6c\xf5"
"\x39\xf2\x78\xf1\xcb\xf2\x2c\xf6\xc8\xfa\x10\x00\x4d\x05\x44\x09"
"\xcb\x0b\x89\x0b\xf6\x08\x34\x04\xa3\xfe\x95\xf8\x44\xf4\x03\xf2"
"\xc6\xf2\x3e\xf6\xcf\xfb\xe2\x01\x9b\x07\x56\x0b\xc5\x0c\xd9\x0b"
"\xb3\x08\xd2\x04\x9d\x00\xc2\xfd\x75\xfb\x53\xfb\x26\xfb\xa8\xfc"
"\x60\xfd\x7e\xff\x0a\x00\x15\x02\x18\x02\x2c\x04\xae\x03\xa3\x04"
"\xdd\x03\x79\x03\xe7\x02\x16\x02\xe4\x00\x5b\xfa\x81\xf6\xee\xed"
"\x55\xec\x7b\xe9\xb9\xee\x75\xf3\x4b\xfe\x09\x07\x51\x10\xee\x15"
"\x6b\x17\xf3\x14\x31\x0e\xdb\x06\x06\xfe\x1b\xf9\xeb\xf3\x15\xf3"
"\xad\xf1\xcf\xf4\x85\xf7\x8d\xfe\x4e\x04\xd2\x0b\xc8\x0f\xb9\x12"
"\xe9\x10\x08\x0d\x2c\x06\xbe\xfe\xa1\xf7\x30\xf2\x3e\xef\xc7\xee"
"\x5f\xf1\x5f\xf5\x6a\xfb\x14\x01\x4e\x07\x53\x0b\xbf\x0e\x91\x0e"
"\x65\x0d\x91\x08\x8a\x03\xb1\xfc\x6b\xf7\xcb\xf2\xe7\xf0\x70\xf1"
"\x42\xf4\x05\xf9\x74\xfe\x43\x04\x93\x08\xdf\x0b\xb1\x0c\x47\x0c"
"\x3c\x09\xac\x05\x88\x00\x2f\xfc\x7e\xf8\xdf\xf6\xb7\xf6\x1b\xf9"
"\x3b\xfc\x81\x00\xd5\x03\x88\x06\x2c\x07\x31\x07\xe3\x05\x08\x04"
"\x9c\x02\x3c\x01\x38\x01\x63\xff\x95\xff\x88\xf8\x92\xf5\x15\xf0"
"\xac\xed\xd6\xed\x0c\xf1\x8e\xf5\x16\xfc\x34\x04\x7c\x09\xd3\x0f"
"\x26\x11\xf4\x10\x3a\x0d\x97\x09\xa7\x03\xda\x00\x90\xfd\xed\xfb"
"\xbb\xfa\x8b\xfa\x0a\xfa\xab\xfb\x4e\xfd\xdd\xff\x10\x03\xca\x05"
"\xd7\x07\x8c\x08\xf2\x07\x94\x05\x18\x03\x85\xff\x95\xfc\x1d\xfa"
"\xec\xf8\xa6\xf8\x37\xfa\xd7\xfb\x3c\xfe\x40\x00\x0a\x02\xa0\x02"
"\x18\x03\xdc\x01\x04\x01\xc1\xff\xb4\xfe\x5b\xfe\x5e\xfe\x53\xfe"
"\xc1\xfe\xc8\xfe\xd2\xfe\xf2\xfe\x63\xff\xd8\xff\xe5\x00\x07\x02"
"\xd3\x02\xa8\x03\xe4\x03\x43\x03\x40\x02\xac\x00\xea\xfe\xc1\xfd"
"\x24\xfd\x50\xfd\xc2\xfd\xe4\xfe\x48\xff\x5c\x00\x61\x00\x1c\x01"
"\xf9\x00\x41\x02\x5d\x02\xcf\x03\x4a\x03\x22\x04\xd5\xff\x6f\xfc"
"\xef\xf8\xbd\xf3\x17\xf3\xb0\xf1\x4e\xf3\x59\xf5\xbb\xfb\x9b\xff"
"\x34\x06\xf1\x09\x15\x0c\x50\x0c\xbe\x0b\x33\x09\x98\x07\x1e\x06"
"\xa0\x03\x45\x02\x4a\x00\x3d\xfe\xb8\xfc\x5b\xfc\x73\xfb\xb3\xfc"
"\x76\xfd\x05\xff\x30\x00\xc0\x01\xc4\x01\x85\x02\xee\x01\x6f\x01"
"\xd6\x00\x27\x00\x67\xff\x83\xff\x59\xff\x59\xff\x7d\xff\xb6\xfe"
"\xaa\xfd\xed\xfc\x0f\xfc\x8e\xfb\x75\xfc\x3c\xfd\x51\xff\x5b\x01"
"\x23\x03\xf9\x03\x4e\x04\x61\x03\x36\x02\xd5\x00\x85\xff\xb6\xfe"
"\xfb\xfe\x36\xff\x2d\x00\x2f\x01\x70\x01\x38\x01\xc1\x00\x3b\xff"
"\xc2\xfe\x44\xfe\x26\xfe\xb0\xfe\xb2\xff\x10\x00\x01\x01\x54\x01"
"\xae\x01\xfd\x01\x52\x02\x92\x02\x12\x00\x75\xff\xa0\xfb\xcf\xf9"
"\x69\xf7\x49\xf6\x3a\xf5\xae\xf6\x12\xf9\x4b\xfc\x10\x01\x2f\x04"
"\x17\x07\x55\x08\x3b\x09\x7e\x08\xab\x08\x54\x07\x68\x06\x0a\x05"
"\xf6\x03\x81\x02\xa3\x01\x4c\x00\x0a\xff\xbc\xfd\x95\xfc\xd4\xfb"
"\x7a\xfb\xb0\xfb\x12\xfc\xef\xfc\xcd\xfd\xdc\xfe\xce\xff\xbd\x00"
"\x80\x01\x5d\x02\xec\x02\x20\x03\x02\x03\x30\x02\xee\x00\xb3\xff"
"\xdf\xfd\x78\xfc\x6c\xfb\x25\xfb\xd8\xfb\x6d\xfd\x78\xff\x7e\x01"
"\x4f\x03\x5e\x04\x6d\x04\xd5\x03\x70\x02\x45\x01\x24\x00\x2e\x00"
"\xc4\xff\xe5\xff\x04\x00\x72\xff\x3f\xff\x69\xfe\xe4\xfd\x66\xfd"
"\xe2\xfd\x36\xfe\xf0\xff\xe1\x00\x3e\x02\xe6\x02\x82\x00\xd0\xfe"
"\xc0\xfb\x30\xf9\xf5\xf7\x84\xf7\x4c\xf7\x19\xf9\xaf\xfb\x27\xfe"
"\xeb\x01\x57\x04\xc9\x05\x11\x07\x5f\x07\x1c\x07\x9e\x07\x4c\x07"
"\xc0\x06\x27\x06\xae\x04\xff\x02\x9f\x01\xdd\xff\x8f\xfe\xbd\xfd"
"\xfa\xfc\xce\xfc\xed\xfc\xf9\xfc\x47\xfd\x90\xfd\x94\xfd\x9d\xfd"
"\xa6\xfd\x93\xfd\x02\xfe\xae\xfe\xa1\xff\x18\x01\x75\x02\x67\x03"
"\xf5\x03\x88\x03\x4f\x02\x01\x01\x64\xff\x2b\xfe\xac\xfd\x85\xfd"
"\x0a\xfe\xde\xfe\x7b\xff\x2f\x00\xa1\x00\xe8\x00\x0a\x01\x58\x01"
"\x5f\x01\xb8\x01\x85\x01\x78\x01\x85\x00\x3e\x00\x50\xff\x95\xfe"
"\xcc\xfe\x90\xfe\x0b\x00\x64\x00\x52\x01\x5b\x01\x09\x01\xd4\x00"
"\x1f\x00\xd0\x00\x5b\x00\x96\x01\x3e\x00\x47\xfe\x69\xfc\xff\xf8"
"\x48\xf7\x7a\xf5\x2e\xf5\x7d\xf5\x8b\xf8\x28\xfb\x39\xff\xc4\x02"
"\x08\x05\xb3\x06\x95\x07\x9f\x07\xa2\x07\x3d\x08\xee\x07\x26\x08"
"\xd8\x07\xb6\x06\x67\x05\x00\x04\xad\x01\x07\x00\x54\xfe\x05\xfd"
"\x1a\xfc\xe5\xfb\x40\xfb\x90\xfb\xe5\xfb\x18\xfc\xc1\xfc\x58\xfd"
"\xb5\xfd\x98\xfe\x54\xff\x1f\x00\x35\x01\xeb\x01\x2c\x02\x2a\x02"
"\xcd\x01\x95\x00\xce\xff\x96\xfe\xaa\xfd\x98\xfd\xf6\xfd\xa4\xfe"
"\xd8\xff\xb3\x00\x37\x01\xad\x01\xce\x01\xc1\x01\x0f\x02\x34\x02"
"\x39\x02\x6f\x02\x48\x02\xf3\x01\x48\x01\x53\x00\x90\xff\xb5\xfe"
"\xdc\xfe\xb1\xfe\x8a\xff\xbc\xff\x6d\x00\x48\x00\x79\x00\xf5\xff"
"\x7e\xff\x4d\xfe\x9b\xfb\xd4\xfa\xf5\xf7\x2d\xf7\x38\xf6\x68\xf6"
"\x12\xf7\xa9\xf9\xfd\xfb\x26\xff\x77\x02\x9a\x04\xb5\x06\xf5\x07"
"\x95\x08\xc9\x08\x62\x09\xd3\x08\xbc\x08\xe1\x07\xa3\x06\x16\x05"
"\xbe\x03\xcf\x01\x81\x00\x0f\xff\xbb\xfd\x9f\xfc\xe8\xfb\x0e\xfb"
"\xd4\xfa\xe1\xfa\x07\xfb\x9d\xfb\x5c\xfc\x16\xfd\x19\xfe\x53\xff"
"\x52\x00\x62\x01\x1f\x02\x36\x02\x06\x02\xe2\x01\x05\x01\xbf\x00"
"\x05\x00\x8b\xff\x45\xff\x48\xff\x3d\xff\x98\xff\xe1\xff\x07\x00"
"\x6b\x00\xd4\x00\x2a\x01\xbe\x01\x1a\x02\x2a\x02\x3d\x02\xf2\x01"
"\x62\x01\xe4\x00\x6a\x00\xb6\xff\x06\x00\x65\xff\xb6\xff\x81\xff"
"\x56\xff\x40\xff\x42\xff\x16\xff\xc4\xfe\xdc\xfd\x06\xfc\xf8\xfa"
"\xdd\xf8\xe0\xf7\x59\xf7\x79\xf7\x53\xf8\x79\xfa\xb0\xfc\x62\xff"
"\x27\x02\xf9\x03\x88\x05\xbe\x06\x3f\x07\xe9\x07\xa1\x08\x92\x08"
"\x74\x08\xde\x07\x9f\x06\x6b\x05\x3d\x04\x85\x02\x49\x01\xc0\xff"
"\x16\xfe\xc9\xfc\xbc\xfb\xb9\xfa\x8b\xfa\xb9\xfa\xd1\xfa\xb0\xfb"
"\x7d\xfc\x1c\xfd\x5d\xfe\x6b\xff\x2e\x00\x33\x01\xb7\x01\x86\x01"
"\x8c\x01\x2e\x01\x6f\x00\x61\x00\x01\x00\xd1\xff\x53\x00\xb8\x00"
"\x29\x01\xb8\x01\xd2\x01\x80\x01\x73\x01\xf4\x00\xc3\x00\xcb\x00"
"\xde\x00\xbe\x00\xbc\x00\x36\x00\xba\xff\x6d\xff\xce\xfe\xc6\xfe"
"\xde\xfe\x59\xff\x08\x00\x46\x00\x7e\x00\x29\xff\x76\xfd\xbc\xfb"
"\x37\xf9\x54\xf8\xa1\xf7\xe5\xf7\x62\xf8\x07\xfa\x66\xfb\x8e\xfd"
"\xe8\xff\xaa\x01\xd6\x03\xac\x05\xeb\x06\x1f\x08\x2f\x09\x1d\x09"
"\x21\x09\x5f\x08\x17\x07\xc3\x05\x99\x04\x01\x03\xfb\x01\xb9\x00"
"\x40\xff\xed\xfd\xc4\xfc\x6a\xfb\xbd\xfa\x4c\xfa\x14\xfa\x66\xfa"
"\x08\xfb\xba\xfb\xe7\xfc\x55\xfe\x7b\xff\x08\x01\x39\x02\xe5\x02"
"\x7a\x03\xa8\x03\xa1\x02\x09\x02\x37\x01\x26\x00\xdb\xff\x9e\xff"
"\x5b\xff\x50\xff\x73\xff\x04\xff\x59\xff\x84\xff\x7d\xff\x18\x00"
"\x8f\x00\x9f\x00\x2b\x01\x3a\x01\xb0\x00\xea\x00\x82\x00\x76\x00"
"\x75\x00\x62\x01\xce\x00\x41\x02\x6f\x01\xbc\x01\x45\x01\x18\x01"
"\xbd\x00\x99\x00\x3b\x00\xac\xfc\xb1\xfc\x1a\xf8\xa1\xf6\x15\xf4"
"\x11\xf4\xbd\xf3\x32\xf6\x76\xf8\x0a\xfb\x35\xff\x1d\x01\xe3\x03"
"\xcf\x05\xc2\x07\x5a\x08\x70\x0a\x91\x0a\x47\x0b\x22\x0b\x86\x0a"
"\xb1\x08\xae\x07\x39\x05\x6c\x03\xb3\x01\xfd\xff\x24\xfe\x02\xfd"
"\x7d\xfb\x2e\xfa\xbe\xf9\xfa\xf8\x15\xf9\xa6\xf9\x85\xfa\x82\xfb"
"\x5d\xfd\x7e\xfe\x20\x00\x95\x01\x79\x02\xf8\x02\x81\x03\x94\x02"
"\x92\x01\x81\x00\x17\xff\x34\xfe\xf8\xfd\xc3\xfd\x3e\xfe\x0d\xff"
"\x19\xff\x76\xff\x4a\x00\xcf\x00\x7a\x01\x13\x02\x91\x02\xe4\x02"
"\x2d\x03\x76\x02\x36\x02\x67\x01\x1a\x01\xa7\x00\x58\x01\x26\x01"
"\x91\x01\xd6\x01\x8c\x01\xf8\x00\x1c\x00\xd1\xff\x99\xff\xd3\xff"
"\xed\xfb\x4d\xfa\x9e\xf7\x94\xf5\x8b\xf3\x58\xf3\x42\xf3\x35\xf6"
"\x86\xf9\x37\xfc\x40\x00\x35\x03\x22\x05\x9e\x06\x5a\x08\x82\x08"
"\x7c\x0a\xd8\x0a\xc4\x0a\x43\x0a\xad\x09\xa2\x07\x8e\x06\xa4\x04"
"\xc8\x02\x57\x01\xf3\xff\x2c\xfe\x2f\xfd\xeb\xfb\x75\xfa\x09\xfa"
"\xa6\xf9\x8d\xf9\x55\xfa\x56\xfb\x44\xfc\xea\xfd\x00\xff\x1a\x00"
"\x86\x01\x45\x02\x7e\x02\xca\x02\x18\x01\xef\xff\x86\xfe\x57\xfd"
"\xde\xfc\x6a\xfd\xf7\xfd\x8a\xff\x25\x01\x74\x01\x1a\x02\x0b\x03"
"\x10\x03\x3d\x03\x18\x03\xb5\x02\x8d\x02\x6d\x02\x44\x01\xcc\x00"
"\xb8\x00\x9c\xff\xf9\xff\xee\xff\x82\x00\xd6\x00\x37\x01\x6a\x00"
"\x05\x00\xa7\xff\x41\xfe\x56\xfb\x33\xf8\xfa\xf5\x71\xf4\xfe\xf3"
"\x7b\xf3\xe9\xf4\xdf\xf7\x43\xfc\x13\x00\xd9\x03\xe7\x06\xa0\x08"
"\xce\x09\x62\x0a\xa1\x0a\x98\x0a\x24\x0a\xca\x08\x2a\x07\x3c\x05"
"\x52\x03\xb6\x01\x95\x00\x23\xff\x09\xfe\x27\xfd\x55\xfc\x82\xfb"
"\x4b\xfb\x16\xfb\x62\xfb\x1c\xfc\x8b\xfc\x43\xfd\x2b\xfe\x0b\xff"
"\xdc\xff\x10\x01\xa3\x01\x74\x02\x90\x02\x47\x02\xfb\x00\x71\xff"
"\x5c\xfd\x91\xfc\xdc\xfb\x34\xfd\xba\xfc\x4e\xff\x7c\x03\x04\x04"
"\x96\x06\x97\x04\x4c\x05\xb0\x04\xb6\x03\x5d\x01\xc3\x00\x1b\xff"
"\xde\xfe\x59\xfe\x16\xfe\xc2\xfe\x6b\xff\x92\xff\x55\x00\xd0\x01"
"\xd6\x01\x22\x03\x2c\x01\xc5\x00\x7a\xf9\x7c\xf7\x3c\xf1\x2e\xf0"
"\xb3\xef\x2b\xf1\x74\xf4\x8c\xf9\xc3\xff\xd8\x04\x7b\x0b\x63\x0d"
"\x80\x0f\x11\x0e\xa8\x0c\x01\x09\xed\x07\xe9\x03\x9f\x01\x8a\xfe"
"\x9a\xfc\x67\xfb\x21\xfd\x32\xfe\x22\x01\x39\x03\x27\x04\x59\x04"
"\xc4\x03\x6a\x02\xc1\x00\xa8\xff\xc2\xfd\x99\xfc\xfb\xfa\x63\xf9"
"\x55\xf8\xcd\xf8\x4a\xf9\xe1\xfb\x76\xfe\x23\x01\x01\x03\xbc\x03"
"\x65\x02\xf2\x01\xb6\x00\x2b\x00\xcc\x00\x1f\x01\x59\x01\x7c\x02"
"\x2e\x02\x97\x02\x49\x02\xe5\x01\x0c\x01\x83\x01\xff\x00\xcd\x01"
"\x80\x01\xfd\x01\x65\x01\xa1\x01\xd4\x00\x17\x01\x68\x00\x8e\x00"
"\x12\x00\x42\x00\x70\x00\xf2\xff\xe8\xfe\x27\xf5\x29\xf3\x24\xeb"
"\x8c\xeb\xb9\xec\xb8\xf2\x25\xf8\x0d\x01\x64\x07\xfe\x0c\xf4\x12"
"\xa9\x12\xde\x11\xf8\x0c\x7b\x07\x10\x00\x5e\xfd\xc7\xf7\xe0\xf6"
"\xda\xf5\xa6\xf7\x5b\xfb\xb1\x02\x3c\x08\xbb\x0e\xbe\x11\xa8\x11"
"\xef\x0e\xc4\x09\xb5\x02\x38\xfc\x87\xf6\x21\xf1\xc0\xee\x68\xed"
"\xcf\xee\x28\xf3\xef\xf9\x56\x01\x89\x09\xe6\x0e\xd9\x11\x03\x11"
"\xfb\x0c\x84\x05\xa5\xfd\x53\xf5\x98\xef\xf5\xec\xc3\xed\xe9\xf1"
"\x78\xf8\x03\x00\x86\x07\xa3\x0d\x3b\x11\xce\x11\x28\x0f\x57\x0a"
"\x61\x04\xf8\xfe\xe2\xfa\x80\xf8\xc8\xf7\xfd\xf7\x2a\xfa\x9e\xfd"
"\x03\x01\xc3\x04\xf7\x07\xbf\x08\xb8\x08\x49\x08\xf2\x06\x2c\xff"
"\x4b\xf4\x35\xec\x81\xe5\x5d\xe4\xdf\xe7\x3c\xee\xbd\xf6\xd2\x00"
"\xa6\x09\xcc\x11\x11\x17\x51\x17\xdc\x13\x20\x0d\x29\x04\xcc\xfc"
"\x69\xf7\x3f\xf3\xce\xf1\x2a\xf3\x8c\xf7\x19\xff\x40\x08\x84\x10"
"\x1f\x16\x4b\x17\x67\x14\x0c\x0e\xba\x05\x70\xfd\x9d\xf6\xb2\xf1"
"\x84\xee\x59\xed\xcd\xee\x7d\xf2\xd6\xf8\x29\x00\xe7\x07\xb3\x0d"
"\x74\x10\xa1\x0e\xc9\x09\x74\x02\xfa\xfa\x69\xf5\x11\xf2\xe9\xf1"
"\x4e\xf4\x29\xf8\xdb\xfc\x28\x02\x3e\x06\x32\x0a\xa5\x0b\x05\x0c"
"\xce\x09\x7b\x07\x02\x03\xb4\xff\x96\xfb\x57\xfa\x26\xf9\x7c\xfa"
"\x39\xfb\x27\xfd\x27\xff\xce\x02\xf4\x04\xdc\x08\x60\x07\x58\xfc"
"\x16\xf9\xaa\xed\xcb\xec\xcc\xec\x29\xf3\xf5\xf7\x1a\x01\x6d\x05"
"\x1b\x0b\xb5\x0e\xbf\x0e\x3b\x0e\xd8\x09\xe4\x06\x39\xfe\x91\xfc"
"\x9b\xf5\x24\xf6\x05\xf5\xad\xf9\xba\xfd\x50\x05\x7d\x0a\xa0\x0f"
"\xc6\x10\x92\x0f\xfc\x0b\xbc\x05\x82\xff\x9c\xf8\x5e\xf4\xe4\xef"
"\x12\xf0\x49\xf0\xae\xf5\xf4\xfa\xd5\x03\xa7\x0a\x36\x11\x62\x12"
"\xf3\x11\x4f\x0b\xb7\x04\xe3\xf9\x88\xf1\x85\xeb\x7f\xe9\x88\xed"
"\x90\xf3\x3f\xfd\x6e\x04\x82\x0c\xe9\x0f\x27\x12\x4d\x0f\xba\x0b"
"\x11\x03\x89\xfd\x65\xf6\x6e\xf5\xa7\xf4\x36\xf9\x9c\xfb\x1e\x01"
"\x5e\x02\x8b\x05\x82\x06\xca\x09\x61\x0b\x50\x0c\xfb\x09\x08\x08"
"\x32\x07\x2e\xee\x76\xeb\x66\xdc\xef\xdc\x5e\xdd\x84\xea\x21\xf3"
"\x2c\x02\xb2\x0f\xfa\x19\xf8\x21\x2c\x20\x77\x1d\x5a\x0f\xd9\x03"
"\xb5\xf4\xe1\xef\x25\xe7\xe6\xea\x7e\xeb\x51\xf5\x3f\xfe\x63\x0c"
"\xd6\x15\x88\x1f\x22\x1f\x1a\x1c\x36\x12\x05\x06\xdb\xf9\x2d\xef"
"\xa6\xe8\x0f\xe4\x33\xe5\x22\xe8\x03\xf2\xa7\xfb\xb9\x09\x2b\x14"
"\xb4\x1c\xa6\x1d\xc8\x1a\xec\x0e\x1e\x03\xe3\xf3\x11\xe8\xb6\xe0"
"\x87\xdf\x38\xe4\xe6\xed\x7a\xfa\xfd\x05\x97\x10\x1c\x18\x58\x1a"
"\x1e\x18\xc7\x11\xef\x06\x48\xfc\xad\xf2\x69\xee\xf7\xee\x31\xf3"
"\x77\xf9\x5b\x00\xab\x04\x0b\x09\xb0\x0b\x3b\x0f\xf0\x0f\xe6\x0f"
"\x16\x0b\xef\x04\x0e\xfe\xe4\xf9\x99\xf2\xbb\xe3\x6d\xe2\x11\xde"
"\xa6\xe1\xeb\xe8\x53\xf6\x51\x01\xbc\x0e\x47\x19\xcd\x1e\xb8\x1f"
"\xe0\x19\x59\x11\xc6\x02\x8e\xf7\x26\xed\xbc\xe9\x8d\xe7\x26\xed"
"\x7a\xf3\x70\xff\x57\x0b\xd4\x18\xf3\x1f\xf5\x22\x82\x1d\x0f\x14"
"\x28\x06\x7a\xf9\x41\xee\x69\xe7\xb0\xe4\xc4\xe4\x1c\xea\xe5\xf1"
"\x29\xfd\x7c\x08\x9d\x14\x59\x1a\xcf\x1c\xd6\x16\x8c\x0e\x43\xfd"
"\x59\xf1\xd8\xe4\x54\xe0\xc1\xe1\x4c\xea\x8a\xf5\x6d\x02\x82\x0d"
"\x6d\x15\x48\x18\xbf\x16\x82\x10\xcd\x07\x01\xff\xaa\xf7\x28\xf4"
"\xba\xf2\x56\xf6\x02\xf9\x63\xfe\xe2\xff\x10\x05\xb4\x05\x7e\x0c"
"\x1f\x0c\x8d\x10\x6e\x09\x6b\x0d\x84\xf8\xe4\xe9\x78\xe1\xb8\xd9"
"\xd1\xde\xa9\xe5\x4b\xf8\xfa\xfd\xbe\x0f\xdd\x14\xad\x1e\xc2\x1a"
"\xaa\x1d\xf9\x10\xa8\x06\xdd\xf8\x75\xf0\xb0\xe8\xaf\xe8\x37\xed"
"\xd9\xf3\xe5\x00\x24\x0b\xa9\x16\x4b\x1a\x16\x1d\x27\x16\xee\x10"
"\xf7\x03\x67\xfc\xc9\xef\x34\xeb\x3b\xe5\x90\xe6\x42\xe9\xdb\xf2"
"\x96\xfc\x6e\x09\x94\x14\x54\x1b\x2d\x1d\xca\x18\x2d\x0f\x86\x01"
"\xf9\xf5\xd5\xe8\xd6\xe3\xac\xe0\xa5\xe5\x0b\xef\xdf\xfb\xad\x08"
"\x1a\x12\x94\x18\x79\x19\x90\x15\xe1\x0e\xb8\x04\x94\xfa\x9f\xf2"
"\x22\xef\x8b\xee\x4a\xf3\x1d\xf8\x32\xff\x7d\x02\x3c\x08\x1a\x0a"
"\x6b\x0e\xe3\x0e\x74\x0f\x94\x0b\xdf\x06\xba\xfe\x76\xfc\x3f\xf1"
"\x16\xe2\x54\xe2\x9a\xdd\x25\xe4\xe6\xe9\x12\xfc\xc8\x03\x4d\x13"
"\x27\x1c\x40\x21\xac\x1d\x4f\x19\x0e\x0e\x72\xfe\xbb\xf4\x9e\xeb"
"\x25\xe9\xc3\xe7\xe9\xee\x3c\xf4\xe8\x01\x57\x0c\x0d\x1a\x03\x1f"
"\xcb\x21\xe5\x1a\x83\x11\x62\x02\x9f\xf6\x45\xeb\x72\xe5\x25\xe4"
"\xa0\xe5\xb6\xeb\x07\xf4\x15\x00\x06\x0b\x2e\x17\xd3\x1c\xbd\x1e"
"\x1e\x19\xad\x0c\xae\xfa\x02\xed\x8a\xe1\x2e\xdf\xa5\xe2\x9b\xee"
"\x7e\xf9\xdf\x06\x5c\x0f\x35\x15\x87\x15\x8a\x14\xcd\x0d\x19\x07"
"\x8a\xfe\x1b\xf8\x6f\xf3\x7e\xf2\x13\xf5\x88\xf8\x20\xfe\x2c\x01"
"\x81\x05\x69\x06\x6a\x0b\x10\x0b\x59\x0f\xa8\x0a\xba\x0e\x8f\xf4"
"\xa9\xeb\x26\xde\xe4\xdb\x95\xde\x47\xeb\x10\xfd\x3a\x02\xe3\x11"
"\xcc\x13\x8a\x1b\x81\x15\x0a\x1b\xc2\x0b\x57\x05\x7d\xf6\xc8\xf1"
"\x15\xe8\x09\xeb\x40\xef\x2c\xf8\x8b\x03\x47\x0d\x89\x16\x94\x17"
"\xd7\x19\xbb\x12\x1d\x0f\x6c\x03\x48\xfe\xbc\xf1\x9e\xed\x72\xe5"
"\xb0\xe7\xfe\xe8\x3e\xf4\x7d\xfe\x76\x0b\x03\x15\xd6\x19\xbb\x19"
"\x8c\x14\x50\x0c\x73\x00\x7c\xf5\xde\xe9\x0c\xe4\x3e\xe1\x0c\xe9"
"\x00\xf2\x88\x00\x17\x0b\x40\x14\x66\x17\xd4\x16\x5f\x11\xa1\x0a"
"\x51\x00\x65\xf8\xfe\xf2\x99\xf1\xd5\xf2\xd7\xf7\xff\xfb\x54\x00"
"\x52\x03\xbc\x07\xfa\x09\xb7\x0d\xd0\x0d\xd5\x0b\xf9\x06\xf8\x05"
"\x96\xf8\xcd\xe6\x18\xe5\xa6\xdd\x61\xe3\x01\xe8\x87\xfa\x9c\xff"
"\x18\x0d\xdc\x15\x02\x1c\x67\x1a\x57\x18\x7d\x10\x9b\x00\x0c\xf8"
"\x7b\xee\xa5\xed\xce\xea\x12\xf4\x3c\xf7\xe2\x01\x5c\x08\xb7\x13"
"\xa4\x16\x20\x1a\xa2\x16\xba\x0f\x25\x05\x41\xfb\xe8\xf1\x8f\xea"
"\x97\xe9\xeb\xe8\xb2\xee\x1a\xf3\x0a\xfe\x13\x05\x73\x10\x5e\x15"
"\x5a\x1a\x5a\x16\xc8\x10\x53\x01\xf8\xf2\x49\xe7\x7e\xe1\xb1\xe4"
"\xe0\xec\xd6\xfb\x3b\x05\x77\x10\x20\x13\x5d\x16\x3d\x11\xce\x0d"
"\x63\x05\x75\xff\x92\xf7\xf9\xf4\x97\xf2\x3e\xf5\x1a\xf8\x39\xfc"
"\xe5\xff\x3e\x03\x2f\x06\x52\x08\x67\x0b\x19\x0d\xfe\x0a\x4e\xf8"
"\xcf\xf3\x37\xe4\x02\xe4\x6e\xe0\x29\xef\x9e\xf6\x8c\x04\x66\x11"
"\xf7\x17\x3e\x1c\x79\x18\x3d\x17\x9b\x07\x7a\x01\xe8\xf3\xf2\xf0"
"\x72\xe7\x65\xec\xfc\xee\x16\xfa\xdd\x03\x72\x10\x6f\x17\xc1\x18"
"\x3f\x17\xf2\x0e\xa3\x07\xe9\xfd\x6b\xf9\xf1\xf0\x6c\xef\x5b\xeb"
"\xf8\xec\x86\xee\x76\xf7\x9c\x00\xf9\x0a\xea\x13\xc7\x18\xdd\x18"
"\x44\x12\x00\x0a\x56\xfd\x98\xf2\x5f\xe8\xd2\xe4\x9f\xe6\x56\xee"
"\x40\xf9\x10\x05\x8c\x0e\xfa\x13\x76\x16\x3c\x13\x41\x0e\x6a\x05"
"\x91\xfe\xc4\xf6\x12\xf4\xe7\xf2\xed\xf5\x3c\xf8\x35\xfb\x8b\xfe"
"\x4f\x00\xfb\x03\x8f\x06\x7f\x0c\x4c\x0a\x03\x11\x6b\x02\x1a\xf7"
"\x16\xeb\xea\xe5\x41\xe3\x2c\xe6\xd5\xf4\x58\xf9\x5e\x06\xde\x0c"
"\xad\x18\xfb\x17\x48\x1d\x0e\x16\xec\x0c\x61\xff\x3f\xf5\xef\xec"
"\x8b\xe7\x98\xeb\xd4\xef\x5a\xfb\xbe\x03\x1f\x10\xba\x13\x72\x17"
"\x22\x14\xd4\x10\xed\x08\x30\x02\xfa\xf9\x08\xf2\x16\xec\x4b\xe8"
"\xb7\xe9\x33\xee\x8b\xf8\x6b\x02\x34\x0e\x50\x15\x06\x1a\x03\x18"
"\x0a\x13\x28\x08\x8b\xfc\x8d\xf0\x3c\xe8\xbe\xe5\x79\xe8\x2f\xf2"
"\xc0\xfb\x43\x08\x97\x0e\x2f\x15\xce\x12\x39\x10\x7f\x08\x4e\x03"
"\xab\xfc\x68\xf9\x6d\xf7\x64\xf6\x1c\xf7\x39\xf6\xb4\xf9\x70\xfb"
"\x62\x01\xec\x03\x3e\x0a\xfd\x0a\x38\x0f\x79\xfd\x67\xf8\xad\xed"
"\x57\xea\x5b\xe8\xa7\xed\x27\xf8\xad\xf9\x14\x08\x6b\x0b\x8c\x16"
"\x3c\x14\x19\x1b\xde\x10\x4a\x0a\xb2\xfe\x0a\xf7\x36\xef\xaa\xea"
"\x37\xef\x81\xf1\x13\xfd\x02\x04\xed\x0f\x35\x11\x6a\x15\x8c\x10"
"\xfe\x0c\xb7\x05\x11\x00\xaa\xf9\x14\xf4\x1a\xf0\x1f\xec\x2b\xed"
"\x63\xef\xa3\xf8\x70\x00\x56\x0c\x4f\x13\xcb\x18\x78\x17\x8b\x12"
"\x73\x07\xba\xfc\xec\xf0\x29\xea\x04\xe8\x0b\xec\xa1\xf4\x02\xfe"
"\xd7\x08\x15\x0e\x0d\x13\x11\x10\x86\x0d\x16\x06\xd9\x01\x73\xfb"
"\x53\xfa\x21\xf8\x63\xf9\x05\xf8\xb5\xf9\x50\xf9\x7a\xfb\x22\xfe"
"\x80\x03\x36\x06\x58\x0b\x5b\x09\x91\xf9\xea\xf6\x4f\xeb\x62\xed"
"\x1f\xe9\x0a\xf7\x02\xfa\xc8\x01\x65\x09\x42\x0f\x5d\x14\x87\x13"
"\x8b\x17\x5e\x0c\x07\x08\x97\xfb\xc1\xf7\x33\xee\xf5\xee\x24\xf1"
"\xf1\xf6\xb3\xff\x58\x07\x8d\x0f\xb3\x0f\xf9\x11\xf2\x0c\x9b\x09"
"\x78\x02\xff\xfd\xe6\xf7\x68\xf3\x0b\xf0\x71\xed\x21\xef\x81\xf2"
"\x71\xfa\x95\x01\xef\x0b\xd2\x11\xf5\x16\xa0\x15\x0b\x10\x85\x06"
"\xf3\xfb\x63\xf2\xfc\xec\x4c\xec\xde\xf0\xe0\xf7\xb5\x00\x7d\x07"
"\x12\x0d\xe6\x0e\x65\x0d\xf8\x09\x81\x05\x29\x01\x03\xfd\x78\xfb"
"\x9f\xf9\xe0\xf9\xb2\xf8\x10\xf9\x53\xf8\xef\xfb\xc3\xfc\x5f\x02"
"\x92\x04\x6f\x0d\xd7\xfd\x92\xf9\x22\xf3\xb1\xed\x5d\xed\x12\xf0"
"\x2d\xfe\xd3\xfb\x57\x0a\x50\x0b\xa7\x13\x79\x0f\x11\x14\x5a\x0e"
"\xf5\x05\xdd\x00\x9f\xf8\xa6\xf5\x56\xed\x5a\xf3\x33\xf4\xac\xfd"
"\x86\x04\x32\x0e\x19\x11\xf3\x0f\x09\x0f\x6f\x08\xb6\x04\xe1\xfd"
"\x53\xfb\x63\xf5\xd7\xf2\xb7\xef\x2c\xef\xcb\xf1\x53\xf7\xee\xff"
"\x71\x07\xc0\x0f\x8e\x13\x04\x15\x6a\x0f\x09\x09\xd3\xff\x89\xf7"
"\x68\xf1\x2b\xef\x99\xf0\xc5\xf4\xec\xfb\xaf\x02\x7e\x08\x44\x0d"
"\x07\x0e\x43\x0c\x45\x08\xf1\x03\xec\xfe\xaa\xfb\xdd\xf9\x34\xfa"
"\x37\xf9\xc5\xf8\x0d\xf9\xe6\xf9\x69\xfb\x86\xff\x6b\x04\xa6\x09"
"\x0a\x0a\xf9\xfd\xe7\xf9\x3b\xf0\x96\xed\x67\xeb\xe7\xf2\x9c\xf9"
"\x8a\xfe\x63\x08\x42\x0c\x00\x12\xe8\x11\x28\x15\x5d\x0e\xce\x08"
"\x88\x01\x3c\xfa\x6d\xf3\xdd\xee\xb3\xf1\xe7\xf3\x1a\xfc\xd5\x03"
"\xf5\x0b\xbb\x0e\xb6\x0f\x1f\x0f\xc0\x0a\xa4\x07\xe2\x01\x03\xfe"
"\x74\xf7\x6e\xf3\xb7\xee\x5b\xed\x6d\xef\xbc\xf4\x49\xfc\xaf\x04"
"\x65\x0d\x96\x12\x86\x13\x35\x10\xe3\x0a\x75\x02\x42\xfb\x05\xf5"
"\xd0\xf2\xda\xf1\xb0\xf5\x11\xfa\x0b\x00\x8b\x04\x76\x09\xe6\x09"
"\x20\x0a\xb7\x07\xac\x05\xd8\x01\x3b\xff\x89\xfc\xe8\xfa\xc7\xf9"
"\xbe\xf8\xf7\xf8\x11\xf9\x2c\xfb\x7a\xfd\xa6\x02\x75\x05\x13\x0f"
"\xdf\xfc\xca\xfd\x6d\xf3\xfe\xef\x26\xec\x8b\xef\xf6\xfb\x8f\xf7"
"\xda\x07\xf4\x07\x76\x12\xac\x0e\x0c\x15\x6e\x0f\x21\x08\xaa\x04"
"\x65\xfc\xde\xf9\xbe\xf0\x84\xf4\xb2\xf2\x98\xf8\xda\xfe\x2f\x06"
"\x94\x0c\xa6\x0c\x86\x10\xdd\x0b\x50\x0a\x3e\x04\xcb\x00\x4f\xfc"
"\x01\xf6\xd4\xf3\xb8\xee\xd4\xf0\x9e\xf0\x57\xf8\x13\xff\x1a\x07"
"\x18\x0d\x07\x10\xc3\x10\x30\x0c\x48\x08\xd4\x00\xac\xfc\x5b\xf7"
"\x58\xf7\x03\xf7\x50\xf9\xbf\xfb\x6c\xfe\x5c\x02\x64\x03\x38\x06"
"\xb3\x06\x87\x06\x6a\x05\x2b\x03\x3f\x01\x71\xfe\xec\xfc\xe0\xf9"
"\x3d\xf9\xe2\xf8\xa6\xf9\x8c\xfb\x3e\xff\x8b\x07\x61\xf8\xfa\xfb"
"\x27\xf5\xce\xf3\x74\xf0\x16\xf5\x63\xff\xf1\xfb\x6e\x0b\x2b\x0b"
"\x79\x12\xfe\x0c\x79\x10\x79\x0a\xe8\x02\x98\x01\x03\xfc\x8f\xfa"
"\xfe\xf2\x4b\xf6\x0c\xf6\xb5\xf9\x88\x01\xf5\x07\x20\x0e\xce\x0c"
"\x22\x10\x82\x0a\x5e\x07\xa9\x02\x73\xfe\x22\xfb\x84\xf5\x9d\xf4"
"\x71\xef\x37\xf1\xe6\xf1\x06\xf9\x4a\xfe\x4f\x05\xcd\x0b\x08\x0f"
"\x24\x0f\x34\x0d\x50\x09\x7a\x03\xab\xfe\x4f\xfb\x1e\xf9\xd2\xf7"
"\x1a\xf8\x9e\xf9\x45\xfb\x4d\x00\xd8\x02\xc8\x06\x01\x08\x21\x08"
"\xb5\x06\x6a\x03\xfd\x01\x69\xfe\xbd\xfd\xf3\xf8\x84\xf9\xa5\xf6"
"\xfb\xf8\x02\xf8\xae\x03\x83\xf7\x95\xf6\x9c\xf7\x7d\xf2\xa5\xf5"
"\x86\xf3\x2e\x04\x76\xfd\x7c\x0a\xbd\x0d\xfd\x10\xeb\x0e\x1c\x0d"
"\x54\x0d\xba\x01\xb9\x01\xa7\xfc\x7b\xfb\x5f\xf5\x97\xf4\x25\xf7"
"\x85\xf6\xe7\xfe\x92\x04\x88\x0c\x91\x0c\x8c\x0e\x59\x0d\xe3\x06"
"\x59\x05\x6c\xff\x83\xfe\x24\xf7\x76\xf6\xee\xf1\x7a\xf0\x9d\xf1"
"\xc3\xf5\x33\xfc\x8f\x00\xd2\x08\xd8\x0c\xfa\x0e\x67\x0d\x6d\x0c"
"\xac\x07\xa3\x02\x4b\xff\xfa\xfb\x11\xfa\x43\xf7\x03\xf9\x1e\xf8"
"\x9a\xfc\xef\xfe\xee\x03\xb2\x06\x98\x07\x40\x08\xdc\x05\x0e\x04"
"\xf6\x00\x38\xff\x8f\xfc\x7e\xfa\x58\xf9\x92\xf8\x71\xfa\x4d\xfb"
"\x2a\xef\xa8\xf2\x50\xed\x53\xf0\x88\xf0\x13\xfa\x5c\x03\x6e\x05"
"\xe2\x12\xf3\x13\x14\x18\xcd\x11\x02\x11\xc2\x08\x6a\x01\xb7\xfe"
"\xfc\xf9\xb1\xf7\x60\xf2\x63\xf3\x9b\xf3\xfc\xf6\x82\xff\x7a\x06"
"\x03\x0e\xe2\x0e\x79\x11\xaf\x0c\x7a\x07\x62\x03\xc5\xfe\xb2\xfb"
"\xf7\xf5\x9d\xf4\xd3\xef\x87\xef\x1f\xf1\xcd\xf5\xde\xfb\xd3\x02"
"\x00\x0b\x30\x0f\xa1\x10\x9e\x0f\xe2\x0c\x83\x07\xc9\x03\x21\x00"
"\xdf\xfc\x17\xf9\xa5\xf7\x8c\xf6\x7e\xf7\x2f\xfb\x19\xff\x9b\x03"
"\x0f\x07\x8b\x08\x72\x08\x51\x06\x3a\x04\x7f\x01\x84\xfe\x66\xfc"
"\xb7\xfa\x76\xf9\x99\xf9\x36\xfa\x48\xed\x03\xef\x59\xea\x05\xeb"
"\x87\xed\xab\xf5\xb4\x01\x91\x04\x0a\x13\xb3\x16\x09\x1b\x15\x17"
"\xf5\x14\x79\x0d\x4c\x04\x4e\x00\xe4\xfa\x51\xf7\xa3\xf2\xc0\xf1"
"\x16\xf2\x48\xf3\x26\xfb\x30\x02\xbf\x09\x78\x0d\xe1\x10\xd7\x0f"
"\xd9\x0a\xff\x06\x21\x01\x66\xfd\x1d\xf7\x2d\xf5\x5b\xf1\x8c\xef"
"\x2f\xf0\xa3\xf3\x54\xf8\xac\xfe\x54\x07\x66\x0d\xeb\x10\x2e\x12"
"\xf1\x0f\x89\x0b\x53\x06\x7b\x02\xbf\xfe\xa6\xfa\xac\xf8\x44\xf6"
"\x4d\xf6\xc4\xf7\x03\xfc\x19\x00\xfc\x04\x01\x08\x63\x09\x32\x08"
"\xd5\x05\x4c\x03\xbd\xff\x0d\xfd\xc0\xfb\x4a\xf9\xeb\xf9\x02\xf8"
"\x02\xed\x97\xed\x3d\xe9\xd9\xea\x2b\xed\x5a\xf6\xb4\x00\x74\x05"
"\x16\x12\x0e\x16\x8d\x19\xee\x16\xd3\x14\x8d\x0e\x5e\x06\xd8\x02"
"\x44\xfd\x9b\xf8\x34\xf4\x64\xf2\xa1\xf2\x05\xf3\x2b\xfa\x87\xff"
"\x4c\x06\xc1\x09\x78\x0d\x81\x0d\x02\x0a\x6a\x08\xe8\x03\x3b\x00"
"\x27\xfa\x47\xf7\x5d\xf3\x9d\xf0\xaa\xf1\xc6\xf3\x1f\xf7\x8f\xfc"
"\xbc\x03\xb0\x09\x55\x0d\x27\x11\xb1\x10\x84\x0e\x81\x0a\xc3\x06"
"\xb6\x01\x78\xfc\x1e\xf9\x23\xf6\x1b\xf5\xcf\xf6\x86\xf9\x46\xfe"
"\xe2\x01\x6b\x06\x02\x08\x30\x08\xf2\x05\x6a\x04\x73\x01\x48\xfe"
"\x77\xfc\x26\xfc\xc2\xfa\x90\xec\x57\xee\x2c\xe7\x65\xe7\xd0\xe8"
"\x96\xf1\xfd\xfb\x40\x00\x14\x10\x38\x14\x61\x19\x90\x18\x10\x18"
"\xd9\x11\xb1\x09\xab\x06\x80\x01\xa0\xfb\x60\xf7\x6a\xf4\xec\xf2"
"\xe9\xf0\xf1\xf6\x76\xfb\x01\x01\x8f\x05\x2e\x0a\x35\x0b\x56\x09"
"\x68\x09\xa0\x05\x08\x03\x7d\xfe\xe6\xfb\xd6\xf6\x95\xf3\xf2\xf1"
"\x20\xf3\x8e\xf4\xf3\xf8\xc6\xff\x67\x05\xb6\x09\xe3\x0d\xa2\x0f"
"\xb3\x0e\x46\x0d\x51\x0b\xab\x07\xdd\x02\xa0\xfe\x03\xfa\x04\xf6"
"\x98\xf5\xe1\xf5\x95\xf9\x7b\xfd\xdc\x01\x4d\x05\x66\x06\x0f\x07"
"\xc7\x04\xd9\x02\xf8\xfe\x0e\xfe\xf7\xfb\x88\xfd\x40\xf2\x44\xef"
"\x60\xeb\x4a\xe6\x76\xe9\xb1\xec\x57\xf9\x8d\xfd\xce\x0a\xe7\x12"
"\x4a\x16\x71\x18\x2b\x16\x59\x13\xac\x0b\x47\x08\x3e\x05\x37\xff"
"\xc5\xfb\x0d\xf7\x43\xf5\x61\xf2\x89\xf5\x10\xfa\x73\xfd\x69\x02"
"\x0a\x05\xd0\x07\x3a\x06\x18\x07\x6f\x05\xd7\x03\x5f\x01\x70\xfe"
"\xee\xfa\x5f\xf7\x1e\xf5\x7c\xf5\xd2\xf4\x31\xf8\x0a\xfd\xdb\x01"
"\xc0\x06\xa1\x0a\xe8\x0d\x23\x0d\xc1\x0d\x36\x0c\xbc\x09\x2a\x06"
"\x08\x02\xd9\xfd\x17\xf9\x27\xf8\xad\xf6\x4d\xf8\xa2\xfa\xaa\xfd"
"\xbe\x00\x26\x02\xa6\x04\xd6\x03\x75\x03\xa7\x00\x92\xff\x56\xfe"
"\xbf\xfe\xe2\xf3\x9a\xf2\xf5\xed\xb2\xe8\x01\xea\xcd\xeb\xf3\xf5"
"\xdf\xf8\x38\x07\x48\x0f\xaa\x14\xd3\x17\x4f\x17\x9a\x13\xb4\x0c"
"\xab\x09\x6e\x06\x75\x01\x37\xfe\x7a\xfa\x22\xf7\x5e\xf3\x95\xf4"
"\x93\xf7\x8b\xfa\xb1\xff\x63\x03\x35\x06\x8b\x05\x90\x06\xf3\x04"
"\xc2\x03\xf1\x01\x37\x00\x14\xfd\xfb\xf9\xb1\xf7\x58\xf6\x85\xf4"
"\x8d\xf7\xca\xfb\x50\x00\xee\x05\x6a\x0a\x81\x0d\xf2\x0c\xc1\x0d"
"\xd4\x0b\x7a\x09\x9c\x06\x5d\x03\x5b\xff\xd2\xfa\x0f\xfa\x84\xf7"
"\x1c\xf8\xaf\xf9\x60\xfc\xee\xfe\x4c\x00\xe0\x02\x93\x02\xf6\x01"
"\x8c\x00\x4f\xff\x65\xff\xfb\xfd\xa4\xf4\x98\xf4\xcb\xee\xef\xea"
"\xd1\xeb\x71\xee\x47\xf5\x2e\xf9\x47\x06\x65\x0d\xd4\x12\xed\x16"
"\xf5\x16\x0c\x13\xd2\x0d\xb0\x0a\xd1\x06\xb7\x01\xd7\xfe\x6e\xfb"
"\xef\xf7\x25\xf5\x12\xf6\x46\xf7\x20\xf9\x3b\xfd\x97\x00\x3e\x03"
"\x0b\x04\xf8\x05\xdc\x04\x06\x04\x5c\x02\x87\x00\x77\xfd\x38\xfb"
"\x05\xf9\x9d\xf6\x72\xf6\x23\xf8\xc7\xfb\x8f\xff\xc6\x05\xab\x0a"
"\x71\x0d\x7d\x0e\xc1\x0e\x2e\x0c\x11\x09\xac\x05\x6a\x02\xc8\xfe"
"\xf3\xfb\x6f\xfb\x4f\xf9\x82\xf9\xf5\xf9\x2a\xfb\x6e\xfc\x2f\xfe"
"\xbc\x00\x45\x01\x3e\x01\xb0\x00\xc9\xff\xfc\xff\x1d\xf7\xa2\xf4"
"\x31\xf2\xe3\xec\xfc\xec\x58\xee\x6b\xf4\x7c\xf6\xff\xff\xcf\x08"
"\x2e\x0e\x4f\x13\x74\x16\xda\x14\x35\x10\xf1\x0c\xa0\x09\x93\x04"
"\xdc\x00\x3a\xfe\xd3\xfa\xc8\xf7\x3f\xf7\x62\xf8\x1d\xf8\xb6\xfa"
"\xc7\xfd\x1e\x00\xfa\x00\x3b\x03\xb5\x03\x37\x03\xaa\x02\xe2\x01"
"\xd2\xff\x82\xfd\x31\xfb\x6a\xf8\x45\xf7\x99\xf7\xb8\xfa\x64\xfe"
"\xde\x02\x33\x08\x8a\x0b\x1f\x0d\x59\x0d\x86\x0c\x6b\x0a\x37\x07"
"\x83\x04\xa9\x01\xcd\xfe\xea\xfc\xe2\xfb\xba\xfa\x92\xfa\x53\xfa"
"\x5e\xfb\xea\xfb\x9a\xfd\xc7\xfe\xed\xff\xf3\xff\x8e\x02\x8d\xfd"
"\x86\xf6\xe0\xf5\x8a\xef\x12\xee\x3a\xed\x17\xf2\x7d\xf5\x1e\xfa"
"\x96\x03\xbc\x08\x13\x0d\x89\x11\x43\x13\x73\x11\x1d\x0f\xac\x0d"
"\x26\x0a\xd8\x04\x5a\x01\xa5\xfd\x15\xfa\x95\xf7\xde\xf8\x3a\xf9"
"\xc9\xfa\x48\xfc\x80\xfe\xf3\xfe\x91\xff\xd5\x00\x3a\x01\x63\x01"
"\x3e\x01\x19\x01\x21\xff\x9c\xfd\x3a\xfb\x03\xfa\x17\xf9\x59\xfa"
"\x23\xfd\x77\x00\xb5\x03\x7a\x07\xe8\x09\x40\x0b\x25\x0b\x2d\x0b"
"\x8b\x09\x65\x07\x7d\x05\x76\x02\x9f\x00\x54\xfe\x1f\xfd\x8d\xfc"
"\xbd\xfb\x5d\xfb\x6a\xfb\x44\xfb\xae\xfb\xee\xfb\xd6\xfc\xc7\xfd"
"\x44\xff\x8f\xf8\xe3\xf7\x36\xf5\x1d\xf1\x74\xf1\xac\xf1\x48\xf6"
"\x42\xf7\x0b\xff\xfc\x04\xfd\x08\x4f\x0d\x43\x10\xb2\x0f\x73\x0d"
"\x2d\x0c\xa5\x0a\x25\x07\xc0\x04\x43\x02\x50\xff\x59\xfc\x06\xfb"
"\xf3\xfa\xf2\xf9\x8e\xfb\xab\xfc\xe4\xfd\xe2\xfd\x51\xff\x71\xff"
"\xef\xfe\x1f\xff\x48\xff\xc0\xfe\xbe\xfd\x6a\xfd\xcf\xfc\xa2\xfb"
"\x32\xfc\x86\xfd\x9c\xff\x09\x02\x63\x05\xee\x07\x07\x09\xed\x09"
"\x5d\x09\x3a\x08\xa8\x06\x9f\x05\x4d\x04\x97\x02\xc8\x01\xfe\xff"
"\xa3\xfe\xab\xfd\xb6\xfc\x5a\xfc\xba\xfb\x13\xfc\xee\xfb\xd2\xfb"
"\x2f\xfc\x03\xfd\xa1\xf6\x04\xf6\xeb\xf3\xf4\xf0\xbf\xf1\x29\xf3"
"\xc2\xf7\x83\xf9\x3f\x00\xb6\x05\x72\x09\xa6\x0c\x47\x0f\xb8\x0e"
"\xa7\x0c\xbd\x0a\x37\x09\xc5\x05\x66\x03\x1d\x01\xcd\xfe\x7e\xfc"
"\x9d\xfb\xe3\xfb\x82\xfb\xd6\xfc\xcc\xfd\x08\xff\xae\xfe\x71\xff"
"\x3d\xff\x19\xff\x8d\xfe\xcd\xfe\xe6\xfd\xdf\xfc\xa0\xfc\x00\xfc"
"\x32\xfc\xdf\xfc\x0a\xff\x46\x01\x88\x03\xd2\x05\x3d\x07\xb8\x07"
"\xdf\x07\x78\x07\x2a\x07\x4d\x06\x85\x05\xa1\x04\x2e\x03\x4a\x02"
"\x83\x00\x6e\xff\x65\xfe\x83\xfd\x36\xfd\xe7\xfc\x80\xfc\xad\xfc"
"\x10\xfc\x03\xfd\x10\xf9\x00\xf5\x7c\xf4\xc9\xef\x5d\xf0\xbe\xf0"
"\xdf\xf4\x34\xf8\x25\xfd\x57\x04\xda\x07\xf7\x0b\xc9\x0e\x88\x0f"
"\x30\x0e\xde\x0c\xdc\x0a\x2a\x08\x80\x04\x3a\x02\x8a\xfe\x22\xfc"
"\x81\xfa\x30\xfa\x09\xfa\x1c\xfb\x1c\xfd\x10\xfe\x54\xff\x35\x00"
"\x8a\x00\x0b\x00\xe4\xff\x46\xff\x62\xfe\x70\xfd\xdf\xfc\xc9\xfb"
"\xcc\xfb\x2d\xfc\xca\xfd\xde\xff\x66\x02\xb6\x04\x3b\x06\x28\x07"
"\x49\x07\x02\x07\x6d\x06\x1a\x06\xaf\x05\x4b\x05\x34\x04\x7b\x03"
"\xca\x01\x70\x00\x55\xff\x3a\xfe\xae\xfd\xa3\xfd\x53\xfd\x99\xfd"
"\x91\xfd\xe3\xfd\xd4\xf8\xc7\xf5\x76\xf3\x61\xee\xce\xee\x27\xef"
"\x7d\xf3\x27\xf7\xb6\xfd\x50\x04\x36\x08\x4f\x0c\x8c\x0e\xbf\x0e"
"\x1c\x0e\x62\x0d\xdc\x0b\x5b\x09\x6d\x06\x75\x03\x88\xff\x45\xfc"
"\xf0\xf9\xed\xf8\xfb\xf7\x72\xf9\xa8\xfa\x5c\xfc\xed\xfd\x81\xff"
"\x64\x00\xa6\x00\xba\x00\x1f\x00\xa0\xff\x1f\xff\xaa\xfe\x11\xfe"
"\xfe\xfd\xf0\xfd\x9e\xfe\xd3\xff\x58\x01\xb4\x02\x05\x04\xd8\x04"
"\x93\x05\x71\x05\xa0\x05\xac\x05\xa9\x05\x94\x05\x3b\x05\xb8\x04"
"\x3d\x03\x7c\x01\x2f\x00\x30\xfe\x70\xfd\xd4\xfc\x94\xfc\xcd\xfc"
"\x71\xfd\x5b\xfc\xba\xf7\xb4\xf6\x88\xf2\x0b\xf0\xe9\xef\x64\xf1"
"\x1b\xf5\x16\xf9\x29\x00\x1a\x05\x44\x09\x86\x0c\xad\x0d\x39\x0d"
"\xa0\x0c\xca\x0b\x80\x0a\x54\x08\x55\x06\x71\x03\x0e\x00\xdd\xfc"
"\xc3\xfa\x26\xf9\x67\xf8\x1c\xf9\x2e\xfa\x8d\xfb\xbb\xfc\x2f\xfe"
"\xb8\xfe\x28\xff\x4b\xff\x85\xff\x68\xff\x9f\xff\xb8\xff\xe3\xff"
"\x0d\x00\x45\x00\xaa\x00\x05\x01\xc0\x01\x7e\x02\xf4\x02\xad\x03"
"\x45\x04\x59\x04\x94\x04\x97\x04\x8c\x04\x95\x04\xbf\x04\x67\x04"
"\x71\x03\x8e\x02\x4d\x01\xab\xff\x50\xfe\x55\xfd\x6c\xfc\x27\xfc"
"\x79\xfb\x85\xf7\x5f\xf6\xaf\xf3\x48\xf1\x7b\xf1\x4b\xf2\x66\xf5"
"\xa1\xf8\xa7\xfe\xa8\x03\xba\x07\x70\x0b\x1f\x0d\xcd\x0c\x54\x0c"
"\x5a\x0b\xe1\x09\x01\x08\x19\x06\xe7\x03\x33\x01\x81\xfe\x5a\xfc"
"\x97\xfa\x50\xf9\x5c\xf9\xf3\xf9\x1d\xfb\x36\xfc\x9f\xfd\x28\xfe"
"\x35\xfe\x7a\xfe\x67\xfe\x64\xfe\xfb\xfe\xb2\xff\x49\x00\xd8\x00"
"\x4a\x01\x7f\x01\x98\x01\xa4\x01\x16\x02\x3c\x02\xa0\x02\x8f\x03"
"\xe3\x03\x70\x04\x85\x04\x88\x04\x0e\x04\xac\x03\xac\x03\xdd\x02"
"\xa7\x02\xe3\x01\x34\x01\x09\x00\xf1\xfe\xc3\xfd\x11\xfd\x1d\xfa"
"\x20\xf7\xc0\xf5\x2c\xf2\x69\xf1\x8e\xf1\x88\xf3\x51\xf6\x91\xfa"
"\x11\x00\x0e\x04\xc2\x07\xe5\x0a\x21\x0c\x07\x0c\xfa\x0b\x29\x0b"
"\xb8\x09\xd4\x07\x17\x06\x64\x03\xb6\x00\x3e\xfe\x33\xfc\x10\xfa"
"\x18\xf9\x40\xf9\xa5\xf9\xa4\xfa\x14\xfc\x39\xfd\xd2\xfd\x6a\xfe"
"\xc1\xfe\xfb\xfe\x22\xff\xf1\xff\x72\x00\x30\x01\xb0\x01\x2f\x02"
"\xea\x01\x95\x01\x32\x01\xc5\x00\xd2\x00\x1a\x01\x13\x02\xfb\x02"
"\xea\x03\x96\x04\x1a\x05\xc9\x04\x87\x04\xd6\x03\x26\x03\x6c\x02"
"\xd3\x01\x10\x01\x1d\x00\xef\xfe\xa4\xfd\x41\xfa\x94\xf7\x40\xf5"
"\x5c\xf2\xea\xf1\xfb\xf1\x61\xf4\x22\xf7\x4a\xfb\xef\xff\x9d\x03"
"\x1d\x07\x71\x09\x62\x0a\xfa\x0a\xc5\x0a\x75\x0a\x85\x09\x1d\x08"
"\xb6\x06\x40\x04\x00\x02\x6f\xff\x21\xfd\x2e\xfb\xdc\xf9\x6d\xf9"
"\x8d\xf9\x23\xfa\x19\xfb\xf0\xfb\xb6\xfc\x42\xfd\xd9\xfd\x45\xfe"
"\x08\xff\xed\xff\x0c\x01\xfc\x01\xd2\x02\x61\x03\x22\x03\x9c\x02"
"\xab\x01\xcf\x00\x19\x00\xd4\xff\x13\x00\xc6\x00\xb5\x01\xba\x02"
"\x65\x03\xf6\x03\x06\x04\xc4\x03\x4b\x03\x16\x03\x8e\x02\x3d\x02"
"\xb2\x01\x0b\x01\x0d\xff\x92\xfb\x4f\xf9\x9a\xf5\x13\xf3\x12\xf2"
"\x8b\xf2\x78\xf4\x6a\xf7\x04\xfc\x02\x00\x75\x03\x8a\x06\x58\x08"
"\xd2\x08\x5b\x09\x87\x09\x44\x09\xb7\x08\xfe\x07\x98\x06\x79\x04"
"\x36\x02\xf7\xff\x88\xfd\xc5\xfb\xe2\xfa\x3d\xfa\x81\xfa\x05\xfb"
"\xcb\xfb\x58\xfc\xda\xfc\x63\xfd\x8c\xfd\xfe\xfd\xa4\xfe\x82\xff"
"\x7c\x00\x7b\x01\x5e\x02\xe7\x02\xea\x02\x99\x02\xfb\x01\x31\x01"
"\x91\x00\x17\x00\x44\x00\xb2\x00\x64\x01\x39\x02\xad\x02\xf9\x02"
"\xd1\x02\x4d\x02\xef\x01\xae\x01\x80\x01\xad\x01\xc0\x01\x91\x01"
"\x65\xff\x5c\xfd\xa2\xfa\xf6\xf6\x2a\xf5\xcf\xf3\x53\xf4\xff\xf5"
"\x37\xf9\x08\xfd\x2f\x00\x71\x03\x99\x05\xa0\x06\x79\x07\x14\x08"
"\x8a\x08\xd6\x08\xd8\x08\x52\x08\xe9\x06\xee\x04\x74\x02\x9b\xff"
"\xff\xfc\x2e\xfb\xfa\xf9\xc6\xf9\x3f\xfa\x20\xfb\xef\xfb\xa0\xfc"
"\x12\xfd\x63\xfd\xb5\xfd\x41\xfe\x08\xff\x09\x00\x32\x01\x16\x02"
"\xaf\x02\xd1\x02\x75\x02\xb8\x01\xf9\x00\x60\x00\x24\x00\x52\x00"
"\xe0\x00\x98\x01\x3b\x02\xa1\x02\xdc\x02\xad\x02\x3f\x02\xfb\x01"
"\xba\x01\x88\x01\x8e\x01\x92\x01\xe5\x00\xb0\xfe\xae\xfc\xf2\xf9"
"\xae\xf6\xd0\xf4\xca\xf3\x57\xf4\x1b\xf6\xad\xf9\xcd\xfd\x67\x01"
"\xc5\x04\xe2\x06\x98\x07\xd0\x07\xcb\x07\xbe\x07\xc7\x07\xe2\x07"
"\xf3\x07\x44\x07\xfd\x05\x28\x04\x7d\x01\x9e\xfe\x2c\xfc\x47\xfa"
"\x71\xf9\x68\xf9\x33\xfa\x1e\xfb\xee\xfb\x91\xfc\xc0\xfc\xff\xfc"
"\x58\xfd\x39\xfe\x90\xff\x2b\x01\xb8\x02\xe0\x03\x28\x04\x93\x03"
"\x72\x02\xe5\x00\x91\xff\xd2\xfe\xbe\xfe\x51\xff\x33\x00\x50\x01"
"\x3e\x02\x8f\x02\x92\x02\x29\x02\x8e\x01\x1b\x01\xcd\x00\xe7\x00"
"\x15\x01\x28\x01\xf0\x00\x0f\xff\x50\xfd\x2b\xfb\x83\xf8\x24\xf7"
"\x66\xf6\x17\xf7\x8f\xf8\x2b\xfb\x47\xfe\xcd\x00\x2e\x03\xf6\x04"
"\xb5\x05\x2e\x06\x9a\x06\xd7\x06\xf2\x06\xe5\x06\xa0\x06\xa7\x05"
"\x38\x04\x8f\x02\x9e\x00\x9c\xfe\x28\xfd\x3b\xfc\xbf\xfb\xce\xfb"
"\x24\xfc\x71\xfc\xa9\xfc\xd9\xfc\x15\xfd\x5c\xfd\x09\xfe\x20\xff"
"\x54\x00\x8c\x01\x81\x02\xed\x02\xa2\x02\xfa\x01\x1d\x01\x1e\x00"
"\x69\xff\x3c\xff\x9c\xff\x1b\x00\xd6\x00\xa1\x01\xd4\x01\xdd\x01"
"\x02\x02\xa8\x01\x89\x01\x56\x01\x8f\x01\x71\x00\xc9\xfe\xc3\xfd"
"\xeb\xfa\xf4\xf8\x60\xf7\xbc\xf6\x0a\xf7\x7e\xf8\x9b\xfb\x6f\xfe"
"\x63\x01\x20\x04\x8f\x05\x16\x06\x54\x06\x46\x06\x2f\x06\x42\x06"
"\xa2\x06\xa7\x06\x3a\x06\x5f\x05\xc4\x03\x68\x01\x13\xff\xde\xfc"
"\x2f\xfb\x56\xfa\x6a\xfa\x28\xfb\x24\xfc\x39\xfd\x02\xfe\x55\xfe"
"\x63\xfe\x71\xfe\xa3\xfe\x3c\xff\x38\x00\x65\x01\x7e\x02\x11\x03"
"\x19\x03\x64\x02\x1b\x01\xdc\xff\xb4\xfe\x2b\xfe\x4d\xfe\xf2\xfe"
"\x15\x00\xf9\x00\xb4\x01\x07\x02\xda\x01\x8f\x01\x3b\x01\x1d\x01"
"\x1d\x01\x4e\x01\xa6\x01\x20\x01\x21\xff\xb6\xfd\x31\xfb\x84\xf8"
"\x37\xf7\xa3\xf6\x80\xf7\x2d\xf9\x5f\xfc\x8b\xff\x0e\x02\x75\x04"
"\xb8\x05\xcf\x05\xe0\x05\xdc\x05\xc0\x05\xb8\x05\xed\x05\xda\x05"
"\x1d\x05\x0a\x04\x77\x02\x4c\x00\x38\xfe\xa2\xfc\x71\xfb\x07\xfb"
"\x55\xfb\x10\xfc\xc6\xfc\x8e\xfd\x29\xfe\x74\xfe\xb6\xfe\x3f\xff"
"\xdb\xff\x9f\x00\xa3\x01\x78\x02\xdb\x02\xb2\x02\x1b\x02\x07\x01"
"\xcb\xff\xb2\xfe\x15\xfe\xfa\xfd\x77\xfe\x73\xff\x66\x00\x38\x01"
"\xc0\x01\xf3\x01\xc8\x01\xc5\x01\xc1\x01\xcb\x01\x04\x02\x4a\x02"
"\xbc\x01\x0d\x00\x6e\xfe\xdc\xfb\x38\xf9\x79\xf7\xa9\xf6\x15\xf7"
"\xa2\xf8\x6f\xfb\x58\xfe\xf1\x00\x23\x03\x52\x04\xa1\x04\xda\x04"
"\x0f\x05\x62\x05\xe5\x05\x71\x06\xa5\x06\x1b\x06\xfa\x04\x3a\x03"
"\xdf\x00\xa3\xfe\xf3\xfc\xbf\xfb\x73\xfb\xd9\xfb\x8d\xfc\x41\xfd"
"\xca\xfd\x1f\xfe\x21\xfe\x26\xfe\x7b\xfe\x1b\xff\x13\x00\x4e\x01"
"\x62\x02\x1e\x03\x48\x03\xc5\x02\xbd\x01\x5e\x00\x26\xff\x4f\xfe"
"\xf4\xfd\x49\xfe\xfb\xfe\xbc\xff\x75\x00\x03\x01\x23\x01\xed\x00"
"\xee\x00\xd8\x00\xf5\x00\x56\x01\xda\x01\xa2\x01\xa5\x00\x9e\xff"
"\x77\xfd\x53\xfb\xb2\xf9\xc6\xf8\xe7\xf8\x0e\xfa\x49\xfc\x8e\xfe"
"\x9c\x00\x4a\x02\x0d\x03\x1e\x03\x32\x03\x41\x03\x9f\x03\x23\x04"
"\xd2\x04\x39\x05\xf4\x04\x44\x04\xd8\x02\x0e\x01\x61\xff\x20\xfe"
"\x61\xfd\x35\xfd\xa0\xfd\x2b\xfe\x73\xfe\x9d\xfe\x77\xfe\x28\xfe"
"\x07\xfe\x36\xfe\xc6\xfe\xa4\xff\xa8\x00\x9a\x01\x23\x02\x28\x02"
"\xa6\x01\xcc\x00\xd6\xff\x14\xff\xac\xfe\xab\xfe\x11\xff\xa0\xff"
"\x3f\x00\xad\x00\x02\x01\x16\x01\x14\x01\x2b\x01\x50\x01\xa3\x01"
"\x15\x02\x44\x02\xe6\x01\xb3\x00\x26\xff\x0a\xfd\xde\xfa\x6d\xf9"
"\x9d\xf8\xeb\xf8\x3f\xfa\x5e\xfc\x9e\xfe\x92\x00\x15\x02\xc6\x02"
"\xe7\x02\xfc\x02\x0b\x03\x6c\x03\x00\x04\x9d\x04\xf1\x04\xbf\x04"
"\x10\x04\xbc\x02\x17\x01\x81\xff\x3e\xfe\x8d\xfd\x7e\xfd\xdc\xfd"
"\x59\xfe\xbd\xfe\xe8\xfe\xc2\xfe\x78\xfe\x3a\xfe\x40\xfe\xa7\xfe"
"\x66\xff\x54\x00\x40\x01\xf5\x01\x21\x02\xc5\x01\x20\x01\x44\x00"
"\x80\xff\xfc\xfe\xe1\xfe\x16\xff\x7c\xff\x04\x00\x64\x00\x87\x00"
"\x81\x00\x61\x00\x45\x00\x65\x00\xb4\x00\x43\x01\xb3\x01\xaf\x01"
"\x01\x01\xd9\xff\x4a\xfe\x7c\xfc\x25\xfb\x66\xfa\x7d\xfa\x78\xfb"
"\x0b\xfd\xd2\xfe\x58\x00\x75\x01\x02\x02\x23\x02\x34\x02\x67\x02"
"\xcb\x02\x41\x03\xbd\x03\xf0\x03\xbb\x03\x28\x03\x3e\x02\x24\x01"
"\x1b\x00\x50\xff\xc7\xfe\x85\xfe\x7c\xfe\x80\xfe\x72\xfe\x60\xfe"
"\x3d\xfe\x2c\xfe\x35\xfe\x74\xfe\xf2\xfe\x8f\xff\x3f\x00\xd8\x00"
"\x3f\x01\x49\x01\x1c\x01\xc7\x00\x51\x00\xf4\xff\xb6\xff\xae\xff"
"\xeb\xff\x3b\x00\x83\x00\xc0\x00\xc5\x00\xb5\x00\x77\x00\x22\x00"
"\x11\x00\x19\x00\x50\x00\x94\x00\x77\x00\xf6\xff\x1f\xff\x02\xfe"
"\xd3\xfc\xf6\xfb\xb7\xfb\x1c\xfc\x19\xfd\x7a\xfe\xdd\xff\xf1\x00"
"\x95\x01\xbc\x01\x9a\x01\x73\x01\x7f\x01\xc0\x01\x33\x02\xad\x02"
"\xf4\x02\xf2\x02\x9c\x02\xf2\x01\x20\x01\x61\x00\xc8\xff\x63\xff"
"\x36\xff\x2f\xff\x21\xff\x0c\xff\xe1\xfe\xa6\xfe\x78\xfe\x6c\xfe"
"\x8b\xfe\xe3\xfe\x6a\xff\xf6\xff\x72\x00\xca\x00\xeb\x00\xca\x00"
"\x7c\x00\x2d\x00\xd8\xff\xaf\xff\xba\xff\xf0\xff\x40\x00\x88\x00"
"\xcd\x00\xd5\x00\xc7\x00\xa8\x00\x79\x00\x63\x00\x65\x00\x3b\x00"
"\xf0\xff\x7b\xff\xb2\xfe\xd8\xfd\xfe\xfc\x77\xfc\x55\xfc\xc1\xfc"
"\xa5\xfd\xb9\xfe\xe6\xff\xe3\x00\x8b\x01\xdd\x01\xea\x01\xe2\x01"
"\xe2\x01\xf5\x01\x37\x02\x68\x02\x90\x02\x80\x02\x30\x02\xa7\x01"
"\x02\x01\x60\x00\xca\xff\x5f\xff\x15\xff\xe4\xfe\xcb\xfe\xcc\xfe"
"\xc5\xfe\xcf\xfe\xd0\xfe\xdb\xfe\xee\xfe\x1e\xff\x53\xff\xa6\xff"
"\x03\x00\x55\x00\x8f\x00\x9b\x00\x80\x00\x35\x00\xf1\xff\xa8\xff"
"\x81\xff\x89\xff\xb4\xff\xf2\xff\x3b\x00\x5c\x00\x60\x00\x44\x00"
"\x2a\x00\x19\x00\x28\x00\x56\x00\x53\x00\x37\x00\xed\xff\x70\xff"
"\xe3\xfe\x65\xfe\x18\xfe\x19\xfe\x66\xfe\xf0\xfe\x8b\xff\x20\x00"
"\x92\x00\xd2\x00\xf0\x00\xfe\x00\x12\x01\x37\x01\x69\x01\xa3\x01"
"\xc8\x01\xce\x01\xb6\x01\x78\x01\x1a\x01\xb7\x00\x50\x00\xe4\xff"
"\x93\xff\x51\xff\x25\xff\x0d\xff\x0d\xff\x00\xff\xfa\xfe\x07\xff"
"\x09\xff\x1d\xff\x3f\xff\x6c\xff\xbf\xff\x0a\x00\x3f\x00\x74\x00"
"\x9c\x00\x90\x00\x4c\x00\x09\x00\xd9\xff\xc7\xff\xc4\xff\xd7\xff"
"\xf7\xff\x1f\x00\x25\x00\x16\x00\xfd\xff\xeb\xff\xea\xff\xc9\xff"
"\xb6\xff\xa0\xff\x86\xff\x6c\xff\x44\xff\x28\xff\x1b\xff\x39\xff"
"\x81\xff\xc8\xff\x1f\x00\x6b\x00\x90\x00\xa8\x00\xb2\x00\xbc\x00"
"\xd5\x00\xf4\x00\x09\x01\x1b\x01\x22\x01\x1f\x01\x06\x01\xdd\x00"
"\xb0\x00\x74\x00\x3b\x00\xfc\xff\xb6\xff\x86\xff\x69\xff\x58\xff"
"\x56\xff\x52\xff\x5a\xff\x57\xff\x4e\xff\x52\xff\x4f\xff\x64\xff"
"\x82\xff\xb2\xff\xfa\xff\x2b\x00\x53\x00\x5f\x00\x4a\x00\x3d\x00"
"\x2a\x00\x10\x00\x08\x00\x00\x00\x06\x00\xff\xff\xea\xff\xdc\xff"
"\xce\xff\xc3\xff\xbd\xff\xaf\xff\x95\xff\x81\xff\x6c\xff\x64\xff"
"\x5b\xff\x6f\xff\x93\xff\xc5\xff\x10\x00\x5a\x00\x8a\x00\xb0\x00"
"\xbf\x00\xc1\x00\xc3\x00\xc2\x00\xc9\x00\xcf\x00\xd1\x00\xbb\x00"
"\xaa\x00\x9b\x00\x86\x00\x6e\x00\x5a\x00\x38\x00\x0d\x00\xdd\xff"
"\xaf\xff\x84\xff\x6b\xff\x62\xff\x61\xff\x6a\xff\x75\xff\x86\xff"
"\x8a\xff\x93\xff\xa2\xff\xa8\xff\xba\xff\xd4\xff\xee\xff\x06\x00"
"\x13\x00\x1a\x00\x18\x00\x0f\x00\x0a\x00\x01\x00\xfc\xff\xfa\xff"
"\xeb\xff\xe0\xff\xc2\xff\xb4\xff\xbd\xff\xbd\xff\xc6\xff\xde\xff"
"\xf8\xff\x05\x00\x09\x00\x11\x00\x15\x00\x14\x00\x1a\x00\x1f\x00"
"\x27\x00\x29\x00\x31\x00\x2e\x00\x27\x00\x1f\x00\x1c\x00\x25\x00"
"\x30\x00\x44\x00\x4b\x00\x43\x00\x35\x00\x25\x00\x28\x00\x2e\x00"
"\x39\x00\x47\x00\x4a\x00\x47\x00\x33\x00\x1c\x00\xf9\xff\xdd\xff"
"\xc8\xff\xc4\xff\xc3\xff\xc3\xff\xca\xff\xc5\xff\xc3\xff\xbd\xff"
"\xc2\xff\xce\xff\xd2\xff\xdf\xff\xf2\xff\x08\x00\x1d\x00\x29\x00"
"\x2c\x00\x26\x00\x19\x00\x07\x00\xf6\xff\xe3\xff\xd9\xff\xc7\xff"
"\xc8\xff\xcd\xff\xd3\xff\xe0\xff\xdc\xff\xd0\xff\xd3\xff\xd4\xff"
"\xd2\xff\xdb\xff\xe0\xff\xfa\xff\x11\x00\x27\x00\x2f\x00\x32\x00"
"\x35\x00\x2f\x00\x2e\x00\x37\x00\x37\x00\x3f\x00\x44\x00\x41\x00"
"\x42\x00\x40\x00\x36\x00\x31\x00\x34\x00\x2e\x00\x35\x00\x37\x00"
"\x2e\x00\x2b\x00\x18\x00\x08\x00\xf8\xff\xe2\xff\xd4\xff\xc0\xff"
"\xb5\xff\xa6\xff\xa9\xff\xb1\xff\xbe\xff\xcf\xff\xe2\xff\xee\xff"
"\xf4\xff\xec\xff\xdb\xff\xe9\xff\xe7\xff\xf1\xff\xfb\xff\xfd\xff"
"\x01\x00\x01\x00\xff\xff\xf3\xff\xe9\xff\xe6\xff\xed\xff\xf4\xff"
"\xf9\xff\x05\x00\x06\x00\x05\x00\xfa\xff\xea\xff\xe9\xff\xe6\xff"
"\xed\xff\xe9\xff\xec\xff\xf7\xff\xfe\xff\x05\x00\x0c\x00\x13\x00"
"\x19\x00\x1a\x00\x25\x00\x2d\x00\x2f\x00\x31\x00\x26\x00\x2a\x00"
"\x29\x00\x1f\x00\x1a\x00\x15\x00\x0f\x00\x06\x00\x06\x00\xfe\xff"
"\xef\xff\xe5\xff\xde\xff\xe1\xff\xe4\xff\xeb\xff\xf3\xff\x03\x00"
"\x16\x00\x23\x00\x35\x00\x3f\x00\x44\x00\x42\x00\x3f\x00\x34\x00"
"\x22\x00\x11\x00\x05\x00\xfc\xff\xea\xff\xda\xff\xd3\xff\xca\xff"
"\xc9\xff\xc8\xff\xc0\xff\xc8\xff\xd2\xff\xde\xff\xf2\xff\xf4\xff"
"\xff\xff\x0a\x00\x0e\x00\x17\x00\x12\x00\x1f\x00\x1b\x00\x14\x00"
"\x13\x00\x0b\x00\x05\x00\xfa\xff\xf0\xff\xe4\xff\xde\xff\xd8\xff"
"\xdb\xff\xea\xff\xf8\xff\xf8\xff\xff\xff\x01\x00\xfa\xff\xfd\xff"
"\x02\x00\x01\x00\xff\xff\x04\x00\x05\x00\x02\x00\xf1\xff\xe6\xff"
"\xdc\xff\xcc\xff\xd4\xff\xde\xff\xec\xff\x06\x00\x15\x00\x28\x00"
"\x38\x00\x40\x00\x43\x00\x44\x00\x46\x00\x41\x00\x3d\x00\x32\x00"
"\x30\x00\x21\x00\x0f\x00\x05\x00\xf3\xff\xe2\xff\xd4\xff\xcf\xff"
"\xca\xff\xcd\xff\xd7\xff\xdf\xff\xdf\xff\xe5\xff\xeb\xff\xec\xff"
"\xf3\xff\xfc\xff\x0d\x00\x18\x00\x13\x00\x1d\x00\x21\x00\x1f\x00"
"\x1f\x00\x17\x00\x0e\x00\x07\x00\xfe\xff\xf5\xff\xf1\xff\xf2\xff"
"\xf0\xff\xec\xff\xe9\xff\xe1\xff\xe3\xff\xe1\xff\xda\xff\xd9\xff"
@@ -0,0 +1,36 @@
/**
@file JCConchBridge.cpp
@brief
@author James
@version 1.0
@date 2016_5_27
*/
#include "JCConchBridge.h"
#include "../JCScriptRuntime.h"
#include "../JSWrapper/LayaWrap/JSCallbackFuncObj.h"
namespace laya
{
void JCConchBridge::getPixelsRenderToJS(unsigned char * pPixels, int nSize, int w, int h, int callbackObjID, int funcID)
{
if (JCScriptRuntime::s_JSRT) {
JCScriptRuntime::s_JSRT->m_pScriptThread->post([pPixels, nSize, w, h, callbackObjID, funcID]() {
JSCallbackFuncObj* pCallbackObj = JCScriptRuntime::s_JSRT->m_pCallbackFuncManager->getRes(callbackObjID);
if (pCallbackObj)
{
#ifdef JS_V8
v8::HandleScope scope(v8::Isolate::GetCurrent());
#endif
JsValue ab = createJSAB((char*)pPixels, nSize);
pCallbackObj->callJS(funcID, ab);
delete[] pPixels;
}
});
}
}
}
//------------------------------------------------------------------------------
//-----------------------------END FILE--------------------------------
+29
View File
@@ -0,0 +1,29 @@
/**
@file JCConchBridge.h
@brief
@author James
@version 1.0
@date 2016_5_27
*/
#ifndef __JCConchBridge_H__
#define __JCConchBridge_H__
namespace laya
{
/**
* @brief
*/
class JCConchBridge
{
public:
static void getPixelsRenderToJS(unsigned char * pPixels, int nSize, int w, int h, int callbackObjID, int funcID);
};
}
//------------------------------------------------------------------------------
#endif //__JCConchBridge_H__
//-----------------------------END FILE--------------------------------
File diff suppressed because it is too large Load Diff
+211
View File
@@ -0,0 +1,211 @@
/**
@file CToJavaBridge.h
@brief
@author James
@version 1.0
@date 2016_5_19
*/
#ifndef __CToJavaBridge_H__
#define __CToJavaBridge_H__
#include <jni.h>
#include <string>
#include <vector>
#include <map>
namespace laya
{
class BitmapData;
class JCFontInfo;
};
/*
根据名字来调用一个java函数。
不见得效率高,但是会方便一些。
TODO
根据注册的时候的函数的描述来自动把参数从C转换成java类型的
根据类型调用响应的函数
*/
enum JniParamType
{
PT_bool, //Z
PT_byte, //B
PT_char, //C
PT_short, //S
PT_int, //I
PT_long, //J
PT_float, //F
PT_double, //D
PT_String, //string
PT_array,
PT_object,
};
enum JniReturnType
{
JRT_Int,
JRT_string,
JRT_object,
JRT_void,
JRT_Float,
};
bool paserParamDesc( const char* p_sDesc,std::vector<int>& p_nParamNum,int& p_nReturnType );
class CToJavaBridge
{
public:
struct JavaMethod
{
jclass cls;
jmethodID method;
std::vector<int> paramInfo;
int retureValueType;
JavaMethod(){}
JavaMethod(jclass p_cls, jmethodID p_method)
{
cls = p_cls;
method = p_method;
}
};
struct ThreadJNIData
{
JavaVM* pJVM;
JNIEnv* pThreadJNI;
ThreadJNIData()
{
pThreadJNI = 0;
pJVM = 0;
}
};
struct JavaRet
{
enum RTType
{
RT_Object = 0,
RT_String,
RT_Int,
RT_Float,
RT_Unk = 0xffffffff
};
JNIEnv* pJNI;
RTType retType;
jobject objRet;
jstring strRet;
int intRet;
float floatRet;
JavaRet()
{
pJNI = NULL;
retType = RT_Unk;
objRet = NULL;
strRet = NULL;
intRet = 0;
floatRet = 0;
}
~JavaRet()
{
if (pJNI && objRet)
{
pJNI->DeleteLocalRef(objRet);
}
if (pJNI && strRet)
{
pJNI->DeleteLocalRef(strRet);
}
}
};
public:
static std::string JavaClass;
static CToJavaBridge* GetInstance();
static void DelInstance();
CToJavaBridge();
~CToJavaBridge();
/** @brief 内部不会保存这些字符串的指针
* @return
*/
jmethodID addStaticMethod( JNIEnv* p_Env, const char* p_sCls);
ThreadJNIData* checkThreadJNI();
/** @brief 返回的指针是重新分配内存的。
* @return
*/
int* getJavaIntArray(JNIEnv* p_pJNI, jobject p_obj);
//p_nLen 是byte的个数
int* getJavaIntArray(JNIEnv* p_pJNI, jobject p_obj, char* p_pBuff, int& p_nByteLen);
std::string getJavaString( JNIEnv* p_pJNI, jstring p_sJString );
//bool callStaticJavaMethod( int p_nJavaMethodName, std::vector<intptr_t>& p_Params, JavaRet& ret );
bool callMethodRefection(int objid,bool isSyn,const char* className, const char* methodName, const char* params, JavaRet& p_Ret);
bool callMethod(int objid, bool isSyn, const char* className, const char* methodName, const char* param, JavaRet& ret);
bool callMethod(const char* className, const char* methodName, int n, JavaRet& ret);
bool callMethod(const char* className, const char* methodName, float f, JavaRet& ret);
bool callMethod(const char* className, const char* methodName, int x, int y, int w, int h, JavaRet& ret);
bool callMethod(const char* className, const char* methodName, const char* s,int x, int y, int w, int h,int bKeyCloseView, JavaRet& ret);
bool callMethod(const char* className, const char* methodName, float x,float y,JavaRet& ret);
bool callMethod(const char* className, const char* methodName, bool b, JavaRet& ret);
bool callMethod(const char* className, const char* methodName, JavaRet& ret,JavaRet::RTType p_eReturnType=JavaRet::RT_String);
bool callMethod(const char* className, const char* methodName, int x, int y, JavaRet& ret);
bool callMethod(const char* className, const char* methodName, const char* s1,const char* s2,JavaRet& ret);
bool callMethod(const char* className, const char* methodName, const char* s1,const char* s2,const char* s3,JavaRet& ret);
bool callMethod(const char* className, const char* methodName, const char*s, int n, JavaRet& ret);
bool callMethod(const char* className, const char* methodName, const char*s, int n,int n1, JavaRet& ret);
bool callMethod(const char* className, const char* methodName, int n1, int n2,const char*s1, const char*s2, const char*s3, JavaRet& ret);
bool callMethod(const char* className, const char* methodName,int n1,int n2,int n3,const char*s1,const char*s2,const char*s3,JavaRet& ret);
bool callMethod(const char* className, const char* methodName, const char*s, JavaRet& ret,JavaRet::RTType p_eReturnType = JavaRet::RT_String);
void replace_all_distinct(std::string& str, const std::string& old_value, const std::string& new_value);
bool getTextBitmap(laya::BitmapData* bitmapData, const char*text, laya::JCFontInfo* pFontInfo, int fontColor, int borderSize, int nBorderColor);
void measureText(laya::JCFontInfo* pFontInfo, const char* p_sText, int& nResultWidth, int& nResultHeight);
// object
bool newObject(jobject* obj, const char* className);
bool newObject(jobject* obj, const char* className, intptr_t thisObj);
bool disposeObject(jobject& obj, const char* className, const char* methodName);
bool callObjVoidMethod(jobject& obj, const char* className, const char* methodName);
bool callObjVoidMethod(jobject& obj, const char* className, const char* methodName, const char* arg);
bool callObjVoidMethod(jobject& obj, const char* className, const char* methodName, int32_t arg);
bool callObjVoidMethod(jobject& obj, const char* className, const char* methodName, double arg);
bool callObjVoidMethod(jobject& obj, const char* className, const char* methodName, int64_t arg);
bool callObjVoidMethod(jobject& obj, const char* className, const char* methodName, bool arg);
bool callObjRetMethod(jobject& obj, const char* className, const char* methodName, int* ret);
bool callObjRetMethod(jobject& obj, const char* className, const char* methodName, double* ret);
bool callObjRetMethod(jobject& obj, const char* className, const char* methodName, bool* ret);
private:
bool getClassAndMethod(const char* className, const char* methodName, const char* methodSign, JNIEnv** ppEnv, jclass* pClazz, jmethodID* pMethodId);
public:
//typedef std::map<int, JavaMethod> JavaMethodMap;
// JavaMethodMap m_StaticMethods;
JavaVM* m_pJVM;
JNIEnv* m_pDefJNIEnv;
pthread_key_t m_kThreadkeyJNI; //TEST多个线程一起使用有没有问题
jmethodID m_jMethodID;//JS调用c++再调用java
jmethodID m_jMethodIDRefection;//JS调用c++再调用java
jmethodID m_jNativeMethodStrId;//C++直接调用java
jmethodID m_jNativeMethodStrId1;//C++直接调用java
jmethodID m_jNativeMethodStrId2;//C++直接调用java
jclass m_jClass;
jclass m_jIntegerClass;
std::map<std::string, jclass> m_classMap;
};
//------------------------------------------------------------------------------
#endif //__CToJavaBridge_H__
//-----------------------------END FILE--------------------------------
+197
View File
@@ -0,0 +1,197 @@
/**
@file CToObjectC.h
@brief
@author wyw
@version 1.0
@date 2014_8_26
*/
#ifndef _CToObjectC_H_
#define _CToObjectC_H_
#include <stdio.h>
#include <string>
#include <vector>
#include <JavaScriptCore/JSBase.h>
#include "resource/Audio/JCAudioInterface.h"
#include "resource/Audio/JCWaveInfo.h"
#include <functional>
#include "../render/Image/JCVideo.h"
void CToObjectCPostMainThread(int cmd,int param1,int param2);
char* CToObjectCGetFontBuffer(long& dataSize);
void CToObjectCPostEditBox(int cmd,int param1,int param2=0,bool bparam2=true,const char* sparam3=NULL);
void ObjectCOperateEditBox(int cmd,int param1,int param2=0,bool bparam2=true,std::string sparam3="");
void CToObjectCAlert(const char* message);
//以下是EditBox相关的
//------------------------------------------------------------------------------
enum IOSEditBoxOperator
{
IOS_EDITBOX_SETPOSX = 1,
IOS_EDITBOX_SETPOSY,
IOS_EDITBOX_SETWIDTH,
IOS_EDITBOX_SETHEIGHT,
IOS_EDITBOX_SETVALUE,
IOS_EDITBOX_SETSTYLE,
IOS_EDITBOX_SETVISIBLE,
IOS_EDITBOX_SETFOCUS,
IOS_EDITBOX_SETBLUR,
IOS_EDITBOX_SETCOLOR,
IOS_EDITBOX_SETFONTSIZE,
IOS_EDITBOX_SETFONTPOS,
IOS_EDITBOX_SETFONTSIZE2,
IOS_EDITBOX_SETCURSORPOSITION,
IOS_EDITBOX_SETMAXLENGTH,
IOS_EDITBOX_SETPASSWORD,
IOS_EDITBOX_SETREGULAR,
IOS_EDITBOX_SETNUMBERONLY,
IOS_EDITBOX_SETMULTIABLE,
IOS_EDITBOX_SETFORBIDEDIT,
};
static const int IOS_EDITBOX_POSX = 1;
void IOS_SetEditBoxStyle(const char* p_sType);
void CToObjectCSetEditBoxX( int p_nX );
void CToObjectCSetEditBoxY( int p_nY );
void CToObjectCSetEditBoxWidth( int p_nWidth );
void CToObjectCSetEditBoxHeight( int p_nHeight );
void CToObjectCSetEditBoxValue( const char* p_sValue );
void CToObjectCSetEditBoxStyle( const char* p_sType );
void CToObjectCSetEditBoxVisible( bool p_bVisible );
void CToObjectCSetEditBoxFocus();
void CToObjectCSetEditBoxBlur();
void CToObjectCSetEditBoxColor( int p_nColor );
void CToObjectCSetEditBoxFontSize( int p_nFontSize );
void CToObjectCSetEditBoxFontPos( int p_nX,int p_nY );
void CToObjectCSetEditBoxFontSize( int p_nWidth,int p_nHeight );
void CToObjectCSetEditBoxCursorPosition( int p_nPos );
void CToObjectCSetEditBoxMaxLength( int p_nMaxLength );
void CToObjectCSetEditBoxPassword( bool p_bPassword );
void CToObjectCSetEditBoxRegular( const char* p_sRegular );
void CToObjectCSetEditBoxNumberOnly( bool p_bNumberOnly );
void CToObjectCSetEditBoxForbidEdit( bool p_bForbidEdit );
const char* CToObjectCGetEditBoxValue();
void CToObjectCSetEditBoxMultiAble(bool p_bMultiAble);
void CToObjectCSetCurrentTime(double nCurrentTime);
double CToObjectCGetCurrentTime();
double CToObjectCGetDuration();
//------------------------------------------------------------------------------
//以下是声音相关的
//------------------------------------------------------------------------------
void CToObjectCPlayMp3Audio( const char* p_sUrl,int p_nTimes,float nCurrentTime );
void CToObjectCSetMp3Volume( float p_nVolume );
void CToObjectCStopMp3();
void CToObjectCResumeMp3();
void CToObjectCPauseMp3();
//------------------------------------------------------------------------------
//以下是视频相关的
//------------------------------------------------------------------------------
void CToObjectNewVideoPlayer(void** obj, std::function<void(const char*)> emitFunc);
void CToObjectDisposeVideoPlayer(void* obj);
void CToObjectReleaseVideoPlayer(void* obj);
void CToObjectVideoPlayerLoad(void* obj, const char* path);
void CToObjectVideoPlayerPlay(void* obj);
void CToObjectVideoPlayerPause(void* obj);
void CToObjectVideoPlayerGetPaused(void* obj, bool* ret);
void CToObjectVideoPlayerGetVideoWidth(void* obj, double* ret);
void CToObjectVideoPlayerGetVideoHeight(void* obj, double* ret);
void CToObjectVideoPlayerSetX(void* obj, double val);
void CToObjectVideoPlayerSetY(void* obj, double val);
void CToObjectVideoPlayerSetWidth(void* obj, double val);
void CToObjectVideoPlayerGetWidth(void* obj, double* val);
void CToObjectVideoPlayerSetHeight(void* obj, double val);
void CToObjectVideoPlayerGetHeight(void* obj, double* val);
void CToObjectVideoPlayerGetCurrentTime(void* obj, double* val);
void CToObjectVideoPlayerSetCurrentTime(void* obj, double val);
void CToObjectVideoPlayerGetDuration(void* obj, double* val);
void CToObjectVideoPlayerSetVolume(void* obj, double val);
void CToObjectVideoPlayerGetVolume(void* obj, double* val);
void CToObjectVideoPlayerSetLoop(void* obj, bool val);
void CToObjectVideoPlayerGetLoop(void* obj, bool* val);
void CToObjectVideoPlayerGetReadyState(void* obj, int* val);
void CToObjectVideoPlayerGetMuted(void* obj, bool* val);
void CToObjectVideoPlayerSetMuted(void* obj, bool val);
void CToObjectVideoPlayerGetAutoplay(void* obj, bool* val);
void CToObjectVideoPlayerSetAutoplay(void* obj, bool val);
void CToObjectVideoPlayerGetBitmap(void* obj, laya::BitmapData* bitmap);
void CToObjectVideoPlayerIsFrameUpdate(void* obj, bool* val);
//------------------------------------------------------------------------------
//JSC比较恶心,必须在ObjectC层开启和关闭js线程的循环
void CToObjectCRunJSLoop();
void CToObjectCRunStopJSLoop();
void CToObjectCPostFunc(std::function<void(void)> func);
//------------------------------------------------------------------------------
//本地推送
void CToObjectCSetRepeatNotify( int p_nID,long p_nStartTime,int p_nRepeatType,const char* p_sTickerText,const char* p_sTitleText,const char* p_sDesc );
void CToObjectCSetOnceNotify( int p_nID,long p_nStartTime,const char* p_sTickerText,const char* p_sTitleText,const char* p_sDesc );
void CToObjectCDeleteOnceNotify( int p_nID );
void CToObjectCDeleteAllNotify();
//------------------------------------------------------------------------------
//以下是一些杂项
//------------------------------------------------------------------------------
//获得总的内存数
long CToObjectCGetTotalMem();
long CToObjectCGetUsedMem();
long CToObjectCGetAvalidMem();
float CToObjectCGetScreenInch();
void CToObjectCSetScreenOrientation( int p_nType );
long CToObjectCGetScreenOrientation();
int CToObjectCGetNetworkType();
std::string CToObjectCGetGUID();
std::string CToObjectCGetDeviceModel();
std::string CToObjectCGetDeviceInfo();
float CToObjectCGetDeviceSystemVersion();
std::string CToObjectCGetAppVersion();
std::string CToObjectCGetAppLocalVersion();
void CToObjectCSetExternalLink( const char* p_sUrl,int x,int y,int w,int h,bool bShowCloseButton );
void CToObjectCCloseExternalLink();
void CToObjectCSetScreenWakeLock( bool p_bWakeLock );
void CToObjectCShowToast( const char* p_sInfo );
void CToObjectCOpenAppStoreUrl( const char* p_sAppID );
std::string CToObjectCCallMethod(int objid,bool isSync, const char*clsName, const char* methodName, const char* paramStr);//
void CToObjectCCallWebviewJS(const char* functionName, const char* jsonParam, const char* callback);
void CToObjectCShowWebView();
void CToObjectCHideWebView();
void CToObjectCSetSensorAble(bool p_bAble);
void CToObjectCRunJS(const std::string& script);
void CToObjectCCaptureScreen();
float CToObjectCGetDevicePixelRatio();
void CToObjectCOnBlur();
void CToObjectCOnFocus();
#endif //_CToObjectC_H_
//-----------------------------END FILE--------------------------------
@@ -0,0 +1,66 @@
/**
@file JCIOSFreeType.cpp
@brief
@author James
@version 1.0
@date 2016_6_11
*/
#include "JCIOSFreeType.h"
#ifdef __APPLE__
#include "../CToObjectC.h"
#endif
#include <util/Log.h>
extern std::string gRedistPath;
extern std::string gResourcePath;
namespace laya
{
JCIOSFreeType::JCIOSFreeType()
{
}
char* JCIOSFreeType::getFontBuffer(long& buffSize)
{
return CToObjectCGetFontBuffer(buffSize);
}
std::string JCIOSFreeType::writeIOSFontTTF()
{
long nBufferSize = 0;
char* sBuffer = getFontBuffer( nBufferSize );
LOGE("wirteIOSFontTTF size=%d",(int)nBufferSize);
std::string sPath = gRedistPath + "ios.ttf";
long nWriteSize = 0;
if( sBuffer != NULL && nBufferSize > 0 )
{
FILE* fp = fopen(sPath.c_str(),"wb");
if( fp )
{
nWriteSize = (long)( fwrite(sBuffer, 1, nBufferSize, fp ) );
fclose(fp);
}
delete sBuffer;
if( nBufferSize == nWriteSize )
{
return sPath;
}
else
{
return "";
}
}
return "";
}
std::string JCIOSFreeType::getIOSFontTTFPath()
{
std::string sPath = gRedistPath + "ios.ttf";
return sPath;
}
}
//------------------------------------------------------------------------------
//-----------------------------END FILE--------------------------------
@@ -0,0 +1,37 @@
/**
@file JCIOSFreeType.h
@brief
@author James
@version 1.0
@date 2016_6_11
*/
#ifndef __JCIOSFreeType_H__
#define __JCIOSFreeType_H__
#include <JCIOSFTInterface.h>
#include <string>
namespace laya
{
class JCIOSFreeType : public JCIOSFTInterface
{
public:
JCIOSFreeType();
char* getFontBuffer(long& buffSize);
std::string getIOSFontTTFPath();
std::string writeIOSFontTTF();
};
}
//------------------------------------------------------------------------------
#endif //__JCIOSFreeType_H__
//-----------------------------END FILE--------------------------------
+339
View File
@@ -0,0 +1,339 @@
/**
@file JCConch.cpp
@brief
@author James
@version 1.0
@date 2017_11_28
*/
#include "JCConch.h"
#include <algorithm>
#include <util/Log.h>
#include <util/JCCommonMethod.h>
#include <fileSystem/JCFileSystem.h>
#include <downloadCache/JCFileSource.h>
#include <resource/JCFileResManager.h>
#include "JCConch.h"
#include "JSWrapper/JSInterface/JSInterface.h"
#include "JSWrapper/LayaWrap/JSFileReader.h"
#include "JSWrapper/LayaWrap/JSGlobalExportCFun.h"
#include "JCScriptRuntime.h"
#include <downloadMgr/JCDownloadMgr.h>
#include "JCThreadCmdMgr.h"
#include "JCSystemConfig.h"
#include <LayaGL/JCLayaGL.h>
#ifdef JS_V8
#include "JSWrapper/v8debug/debug-agent.h"
#endif
#ifdef ANDROID
#include "WebSocket/WebSocket.h"
#include "CToJavaBridge.h"
#include <dlfcn.h>
#include <pthread.h>
#include <sys/types.h>
#include <unistd.h>
#elif __APPLE__
#include "CToObjectC.h"
#include "pthread.h"
#elif _WIN32
#include <windows.h>
#endif
std::string gRedistPath = "";
std::string gResourcePath = "";
#ifdef __APPLE__
std::string gAssetRootPath = "";
#endif
int g_nInnerWidth = 1024;
int g_nInnerHeight = 768;
bool g_bGLCanvasSizeChanged = false;
namespace laya
{
extern JCWorkerThread* g_DecThread;
JCConch* JCConch::s_pConch = NULL;
int64_t JCConch::s_nUpdateTime = 0;
JCFileSource* JCConch::s_pAssetsFiles = NULL;
std::shared_ptr<JCConchRender> JCConch::s_pConchRender;
void _vibrate()
{
#ifdef ANDROID
CToJavaBridge::JavaRet kRet;
CToJavaBridge::GetInstance()->callMethod(CToJavaBridge::JavaClass.c_str(), "vibrate", kRet);
#endif
}
JCConch::JCConch(int nDownloadThreadNum, JS_DEBUG_MODE nJSDebugMode, int nJSDebugPort)
{
s_pConch = this;
#ifdef __APPLE__
pthread_key_create(&JCWorkerThread::s_tls_curThread, NULL);
pthread_key_create(&s_tls_curDataThread, NULL);
pthread_key_create(&JSClassMgr::s_tls_curThread, NULL);
pthread_key_create(&__TlsData::s_tls_curThread, NULL);
#elif _WIN32
HMODULE libHandle = LoadLibrary("libGLESv2.dll");
#elif ANDROID
//void *libhandle = dlopen("libGLESv2.so", RTLD_LAZY);
#endif
m_nUrlHistoryPos = -1;
m_sCachePath = gRedistPath + "/appCache";
g_DecThread = new JCWorkerThread(true);
g_DecThread->setThreadName("image decode");
JCDownloadMgr* pdmgr = JCDownloadMgr::getInstance();
LOGI("download thread num = %d", nDownloadThreadNum);
pdmgr->init(nDownloadThreadNum);
m_pFileResMgr = new JCFileResManager(pdmgr);
JCWebGLPlus::getInstance()->init(g_kSystemConfig.m_nThreadMODE);
m_pScrpitRuntime = new JCScriptRuntime();
s_pConchRender.reset(new JCConchRender(m_pFileResMgr,JCWebGLPlus::getInstance()->m_pRArrayBufferManager,m_pScrpitRuntime->m_pRegister,JCWebGLPlus::getInstance()));
//------------------------------------------------------------------------------
//绑定函数
JCWebGLPlus* pWebGLPlus = JCWebGLPlus::getInstance();
JCLayaGL* pLayaGL = s_pConchRender->m_pLayaGL;
pWebGLPlus->uniform1f = std::bind(&JCLayaGL::uniform1f,pLayaGL, std::placeholders::_1, std::placeholders::_2);
pWebGLPlus->uniform1fv = std::bind(&JCLayaGL::uniform1fv, pLayaGL, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
pWebGLPlus->uniform1i = std::bind(&JCLayaGL::uniform1i, pLayaGL, std::placeholders::_1, std::placeholders::_2);
pWebGLPlus->uniform1iv = std::bind(&JCLayaGL::uniform1iv, pLayaGL, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
pWebGLPlus->uniform2f = std::bind(&JCLayaGL::uniform2f, pLayaGL, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
pWebGLPlus->uniform2fv = std::bind(&JCLayaGL::uniform2fv, pLayaGL, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
pWebGLPlus->uniform2i = std::bind(&JCLayaGL::uniform2i, pLayaGL, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
pWebGLPlus->uniform2iv = std::bind(&JCLayaGL::uniform2iv, pLayaGL, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
pWebGLPlus->uniform3f = std::bind(&JCLayaGL::uniform3f, pLayaGL, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3,std::placeholders::_4);
pWebGLPlus->uniform3fv = std::bind(&JCLayaGL::uniform3fv, pLayaGL, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
pWebGLPlus->uniform3i = std::bind(&JCLayaGL::uniform3i, pLayaGL,std::placeholders::_1, std::placeholders::_2, std::placeholders::_3,std::placeholders::_4);
pWebGLPlus->uniform3iv = std::bind(&JCLayaGL::uniform3iv, pLayaGL, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
pWebGLPlus->uniform4f = std::bind(&JCLayaGL::uniform4f, pLayaGL, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5);
pWebGLPlus->uniform4fv = std::bind(&JCLayaGL::uniform4fv, pLayaGL, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
pWebGLPlus->uniform4i = std::bind(&JCLayaGL::uniform4i, pLayaGL,std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5);
pWebGLPlus->uniform4iv = std::bind(&JCLayaGL::uniform4iv, pLayaGL, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
pWebGLPlus->uniformMatrix2fv = std::bind(&JCLayaGL::uniformMatrix2fv, pLayaGL,std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4);
pWebGLPlus->uniformMatrix3fv = std::bind(&JCLayaGL::uniformMatrix3fv, pLayaGL,std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4);
pWebGLPlus->uniformMatrix4fv = std::bind(&JCLayaGL::uniformMatrix4fv, pLayaGL,std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4);
pWebGLPlus->activeTexture = std::bind(&JCLayaGL::activeTexture, pLayaGL,std::placeholders::_1);
pWebGLPlus->bindTexture = std::bind(&JCLayaGL::bindTexture, pLayaGL,std::placeholders::_1, std::placeholders::_2);
//------------------------------------------------------------------------------
m_pAssetsRes = JCConch::s_pAssetsFiles;
s_pConchRender->setAssetRes(m_pAssetsRes);
m_strStartJS = "scripts/apploader.js";
if (g_kSystemConfig.m_nThreadMODE == THREAD_MODE_DOUBLE)
{
m_pScrpitRuntime->init(m_pFileResMgr, m_pAssetsRes, &m_ThreadCmdMgr);
m_pFileResMgr->m_pCmdPoster = &m_ThreadCmdMgr;
}
else
{
m_pScrpitRuntime->init(m_pFileResMgr, m_pAssetsRes, m_pScrpitRuntime);
m_pFileResMgr->m_pCmdPoster = m_pScrpitRuntime;
}
m_nJSDebugMode = nJSDebugMode;
m_nJSDebugPort = nJSDebugPort;
#ifdef JS_V8
m_pDbgAgent = NULL;
if (m_nJSDebugMode != JS_DEBUG_MODE_OFF)
{
LOGI("open js debug port at %d", m_nJSDebugPort);
m_pDbgAgent = new DebuggerAgent("layabox", m_nJSDebugPort);
m_pScrpitRuntime->m_pDbgAgent = m_pDbgAgent;
}
else
{
m_pDbgAgent = NULL;
m_pScrpitRuntime->m_pDbgAgent = NULL;
}
#endif
}
JCConch::~JCConch()
{
s_pConchRender.reset();
s_pConch = NULL;
if (m_pScrpitRuntime)
{
delete m_pScrpitRuntime;
m_pScrpitRuntime = NULL;
}
#ifdef JS_V8
if (m_pDbgAgent)
{
m_pDbgAgent->Shutdown();
delete m_pDbgAgent;
m_pDbgAgent = NULL;
}
#endif
}
void JCConch::onAppStart()
{
m_strLocalStoragePath = gRedistPath + "/localstorage/";
try
{
fs::create_directories(m_strLocalStoragePath);
}
catch (...)
{
if (global_onCreateFileError)
{
global_onCreateFileError();
}
return;
}
#ifdef __APPLE__
if (g_kSystemConfig.m_nThreadMODE == THREAD_MODE_DOUBLE)
{
m_ThreadCmdMgr.regThread(JCThreadCmdMgr::JS, m_pScrpitRuntime->m_pScriptThread->getWorker());
}
//因为iOS界面和渲染是一个线程,所以即使单线程也可以在这启动
m_pScrpitRuntime->start(m_strStartJS.c_str());
#else
if (g_kSystemConfig.m_nThreadMODE == THREAD_MODE_DOUBLE)
{
m_ThreadCmdMgr.regThread(JCThreadCmdMgr::JS, m_pScrpitRuntime->m_pScriptThread->getWorker());
m_pScrpitRuntime->start(m_strStartJS.c_str());
}
#endif
}
void JCConch::reload()
{
LOGI("JCConch::reload start...");
//先通知消息管理器,关闭各个线程之间的post
m_ThreadCmdMgr.stop();
#ifdef __APPLE__
m_pScrpitRuntime->reload();
m_ThreadCmdMgr.start();
if (g_kSystemConfig.m_nThreadMODE == THREAD_MODE_DOUBLE)
{
m_ThreadCmdMgr.regThread(JCThreadCmdMgr::JS, m_pScrpitRuntime->m_pScriptThread->getWorker());
}
#else
if (g_kSystemConfig.m_nThreadMODE == THREAD_MODE_DOUBLE)
{
m_pScrpitRuntime->reload();
m_ThreadCmdMgr.start();
m_ThreadCmdMgr.regThread(JCThreadCmdMgr::JS, m_pScrpitRuntime->m_pScriptThread->getWorker());
}
else
{
m_pScrpitRuntime->m_bReload = true;
}
#endif
LOGI("JCConch::reload end.");
}
void JCConch::delAppRes()
{
}
void JCConch::onClearMemory()
{
}
void JCConch::onAppDestory()
{
//先通知消息管理器,关闭各个线程之间的post
m_ThreadCmdMgr.stop();
//渲染要继续
JCConch::s_pConchRender->willExit();
//关闭解码线程
delete g_DecThread;
//如果是单线程 在渲染线程析构了
if (g_kSystemConfig.m_nThreadMODE == THREAD_MODE_DOUBLE)
{
if (m_pScrpitRuntime)
{
delete m_pScrpitRuntime;
m_pScrpitRuntime = NULL;
}
}
//关闭下载线程
//删除所有的下载任务
JCDownloadMgr* pNetLoader = JCDownloadMgr::getInstance();
pNetLoader->stopCurTask();
pNetLoader->clearAllAsyncTask();
JCDownloadMgr::delInstance();
}
void JCConch::postCmdToMainThread(int nCmd, int nParam1, int nParam2)
{
#ifdef __APPLE__
CToObjectCPostMainThread(nCmd, nParam1, nParam2);
#else
m_funcPostMsgToMainThread(nCmd, nParam1, nParam2);
#endif
}
int JCConch::urlHistoryLength()
{
return m_vUrlHistory.size();
}
void JCConch::urlBack()
{
urlGo(-1);
}
void JCConch::urlGo(int s)
{
#ifdef __APPLE__
CToObjectCRunStopJSLoop();
#endif
int sz = m_vUrlHistory.size();
m_nUrlHistoryPos += s;
if (m_nUrlHistoryPos >= sz) m_nUrlHistoryPos = sz - 1;
if (m_nUrlHistoryPos < 0) m_nUrlHistoryPos = 0;
if ((size_t)m_nUrlHistoryPos < m_vUrlHistory.size())
{
g_kSystemConfig.m_strStartURL = m_vUrlHistory[m_nUrlHistoryPos];
}
postCmdToMainThread(CMD_ReloadProcess, 0, 0);
}
void JCConch::urlForward()
{
urlGo(1);
}
void JCConch::urlHistoryPush(const char* sUrl)
{
m_nUrlHistoryPos++; //位置
int nsz = m_nUrlHistoryPos+1; //希望的大小
m_vUrlHistory.resize(nsz);
m_vUrlHistory[m_nUrlHistoryPos] = sUrl;
int sz = m_vUrlHistory.size();
if (sz>1)
{
if (m_vUrlHistory[sz - 1] == m_vUrlHistory[sz - 2])
{
m_vUrlHistory.resize(sz - 1);
m_nUrlHistoryPos--;
}
}
}
void JCConch::onRunCmdInMainThread(int nCmd, int nParam1, int nParam2)
{
switch (nCmd)
{
case JCConch::CMD_ActiveProcess:
break;
case JCConch::CMD_DeactiveProcess:
break;
case JCConch::CMD_CloseProcess:
break;
case JCConch::CMD_ReloadProcess:
reload();
break;
case JCConch::CMD_UrlBack:
urlBack();
break;
case JCConch::CMD_UrlForward:
break;
case JCConch::CMD_onOrientationChanged:
break;
case CMD_ClearRender:
if(JCConch::s_pConchRender)
{
JCConch::s_pConchRender->clearAllData();
}
break;
case CMD_MgrStartThread:
m_ThreadCmdMgr.start();
break;
}
}
};
//------------------------------------------------------------------------------
//-----------------------------END FILE--------------------------------
+121
View File
@@ -0,0 +1,121 @@
/**
@file JCConch.h
@brief
@author James
@version 1.0
@date 2017_11_28
*/
#ifndef __JCConch_H__
#define __JCConch_H__
#include <vector>
#include <util/JCCommonMethod.h>
#include "JCConchRender.h"
#ifndef WEBASM
#include "JSWrapper/JSInterface/JSInterface.h"
#include "JCThreadCmdMgr.h"
#endif
namespace laya
{
enum JS_DEBUG_MODE
{
JS_DEBUG_MODE_OFF = 0, //关闭
JS_DEBUG_MODE_NORMAL, //正常
JS_DEBUG_MODE_WAIT, //等待
};
#ifndef WEBASM
class JCFileResManager;
class JCFileSource;
class DebuggerAgent;
#endif
class JCScriptRuntime;
class JCConch
{
public:
enum CMDMSG
{
CMD_ActiveProcess = 0x400 + 3333 + 100, //0x400=WM_USER
CMD_DeactiveProcess,
CMD_ReloadProcess,
CMD_CloseProcess,
CMD_UrlBack,
CMD_UrlForward,
CMD_ClearRender,
CMD_MgrStartThread,
CMD_onOrientationChanged = 0x400 + 3333 + 110, //屏幕切换已经完成。
};
public:
JCConch( int nDownloadThreadNum,JS_DEBUG_MODE nJSDebugMode,int nJSDebugPort );
~JCConch();
void delAppRes();
void onRunCmdInMainThread(int nCmd, int nParam1, int nParam2);
void onAppStart();
void reload();
int urlHistoryLength();
void urlBack();
void urlGo(int s);
void urlForward();
void urlHistoryPush(const char* sUrl);
void exit();
void onClearMemory();
void onAppDestory();
void postCmdToMainThread(int nCmd, int nParam1, int nParam2);
const char* getLocalStoragePath()
{
return m_strLocalStoragePath.c_str();
}
public:
static JCConch* s_pConch;
static int64_t s_nUpdateTime;
static std::shared_ptr<JCConchRender> s_pConchRender;
std::function<void(int, int, int)> m_funcPostMsgToMainThread;
std::string m_strLocalStoragePath;
JCScriptRuntime* m_pScrpitRuntime;
#ifndef WEBASM
static JCFileSource* s_pAssetsFiles;
JCFileSource* m_pAssetsRes;
std::string m_strStartJS;
std::string m_sCachePath;
JCThreadCmdMgr m_ThreadCmdMgr;
int m_nJSDebugPort;
JS_DEBUG_MODE m_nJSDebugMode;
#ifdef JS_V8
DebuggerAgent* m_pDbgAgent;
#endif
JCFileResManager* m_pFileResMgr;
protected:
bool m_bDestroying;
std::vector<std::string> m_vUrlHistory;
int m_nUrlHistoryPos;
#endif
};
};
//------------------------------------------------------------------------------
#endif //__JCConch_H__
//-----------------------------END FILE--------------------------------
+588
View File
@@ -0,0 +1,588 @@
/**
@file JCConchRender.cpp
@brief
@author James
@version 1.0
@date 2016_5_12
*/
#include "JCConchRender.h"
#include <util/Log.h>
#include <util/JCCommonMethod.h>
#include "JCSystemConfig.h"
#include <downloadCache/JCFileSource.h>
#include <downloadCache/JCServerFileCache.h>
#include "JCScriptRuntime.h"
#include "JSWrapper/LayaWrap/JSConchConfig.h"
#include "JCConch.h"
#include "JSWrapper/LayaWrap/JSLayaGL.h"
#include <LayaGL/JCLayaGLDispatch.h>
extern int g_nInnerHeight;
extern int g_nInnerWidth;
int s_nGLCaps = laya::GLC_NONE;
namespace laya
{
JCConchRender::JCConchRender(void* pFileResManager, JCArrayBufferManager* pArrayBufferManager, JCRegister* pRegister, JCWebGLPlus* pWebGLPlus)
{
m_pRenderThread = NULL;
m_fMouseMoveTime = 0.0f;
m_pAssetsRes = NULL;
m_bExit = false;
m_nFrameCount = 0;
m_fShowPerfScale = 0;
m_bStopRender = false;
m_pImageManager = new JCImageManager();
m_pArrayBufferManager = pArrayBufferManager;
if (g_kSystemConfig.m_nThreadMODE == THREAD_MODE_DOUBLE)
{
m_pRegister = new JCRegister();
}
else
{
m_pRegister = pRegister;
}
m_pIDGenerator = new JCIDGenerator();
m_pProgramLocationTable = new JCIDGenerator();
m_pIDGenerator->reset();
m_pProgramLocationTable->reset();
m_pLayaGL = new JCLayaGL(g_nInnerWidth, g_nInnerHeight,m_pArrayBufferManager,m_pImageManager, m_pIDGenerator, m_pProgramLocationTable,m_pRegister,pWebGLPlus);
JCLayaGLDispatch::ms_pLayaGL = m_pLayaGL;
m_pFileResManager = (JCFileResManager*)pFileResManager;
m_nFPS = 0;
m_nDelayTime = 0;
m_nCountDelayTime = 0;
#ifndef __APPLE__
m_bClearAllData = false;
#endif
if (g_kSystemConfig.m_nThreadMODE == THREAD_MODE_DOUBLE)
{
m_pCurrentRenderCmds = new JCCommandEncoderBuffer(102400, 1280);
}
else
{
m_pCurrentRenderCmds = NULL;
}
}
JCConchRender::~JCConchRender()
{
//这个是在JCConch中传过来的,但是为了确保最后一帧,在这释放了,因为JCConchRender全局只有一个
if (m_pFileResManager)
{
//这个fileCache也是同理,需要在这删除,
if (m_pFileResManager->m_pFileCache)
{
delete m_pFileResManager->m_pFileCache;
m_pFileResManager->m_pFileCache = NULL;
}
delete m_pFileResManager;
m_pFileResManager = NULL;
}
if (m_pImageManager)
{
delete m_pImageManager;
m_pImageManager = NULL;
}
if (m_pLayaGL)
{
delete m_pLayaGL;
m_pLayaGL = NULL;
}
m_pArrayBufferManager = NULL;
if (g_kSystemConfig.m_nThreadMODE == THREAD_MODE_DOUBLE)
{
if (m_pRegister)
{
delete m_pRegister;
m_pRegister = NULL;
}
}
if (m_pIDGenerator)
{
delete m_pIDGenerator;
m_pIDGenerator = NULL;
}
if (m_pProgramLocationTable)
{
delete m_pProgramLocationTable;
m_pProgramLocationTable = NULL;
}
if (m_pCurrentRenderCmds)
{
delete m_pCurrentRenderCmds;
m_pCurrentRenderCmds = NULL;
}
}
void JCConchRender::setAssetRes(JCFileSource* pAssetRes)
{
m_pAssetsRes = pAssetRes;
}
void JCConchRender::initOpenGLES()
{
const char* pstrVersion = (const char*)glGetString(GL_VERSION);
LOGI("OpenGL ES version [%s]", pstrVersion);
s_nGLCaps |= GLC_TEXTURE_TPG;
char* pStrExt = (char *)glGetString(GL_EXTENSIONS);
if (pStrExt != nullptr)
{
if (strstr(pStrExt, "GL_IMG_texture_compression_pvrtc"))
{
s_nGLCaps |= GLC_TEXTURE_COMPRESSION_PVR;
}
if (strstr(pstrVersion, "OpenGL ES 3."))
{
s_nGLCaps |= GLC_NOPT;
#ifdef ANDROID
s_nGLCaps |= GLC_TEXTURE_COMPRESSION_ETC1;
s_nGLCaps |= GLC_TEXTURE_COMPRESSION_ETC2;
s_nGLCaps |= GLC_INSTANCEING;
#endif
}
#ifndef ANDROID
s_nGLCaps |= GLC_INSTANCEING;
#endif
#ifdef GL_ETC1_RGB8_OES
if (strstr(pStrExt, "GL_OES_compressed_ETC1_RGB8_texture"))
{
s_nGLCaps |= GLC_TEXTURE_COMPRESSION_ETC1;
}
#endif
}
}
void JCConchRender::onGLReady()
{
initOpenGLES();
}
void JCConchRender::clearAllData()
{
#ifdef __APPLE__
_clearAllData();
#else
m_bClearAllData = true;
#endif
}
void JCConchRender::_clearAllData()
{
LOGI(">>>JCConchRender::clearAllData =%d", std::this_thread::get_id());
m_kPerfRender.invalidGLRes();
m_pLayaGL->deleteAllGLRes();
//图片全部清空
if (m_pImageManager)
{
m_pImageManager->resetRenderThread();
}
m_pArrayBufferManager->clearAll();
m_pIDGenerator->reset();
m_pProgramLocationTable->reset();
m_bStopRender = false;
#ifndef __APPLE__
m_bClearAllData = false;
#endif
}
void JCConchRender::syncArrayBuffer(JCArrayBufferManager* pJSManager, JCArrayBufferManager::ArrayBufferContent* pSyncBufferList,int nSyncCount)
{
if (nSyncCount <= 0)return;
int nSize = pJSManager->m_vBuffers.size();
if ((size_t)nSize > m_pArrayBufferManager->m_vBuffers.size())
{
m_pArrayBufferManager->m_vBuffers.resize(nSize);
}
int* pBuffer = (int*)pSyncBufferList->m_pBuffer;
for (int i = 0; i < nSyncCount;i++)
{
int nIndex = pBuffer[i];
JCArrayBufferManager::ArrayBufferContent* pBuffer1 = pJSManager->m_vBuffers[nIndex];
if (pBuffer1)
{
if (m_pArrayBufferManager->m_vBuffers[nIndex] == NULL)
{
m_pArrayBufferManager->m_vBuffers[nIndex] = new JCArrayBufferManager::ArrayBufferContent(pBuffer1->m_nType,true);
}
m_pArrayBufferManager->m_vBuffers[nIndex]->syncContent(pBuffer1);
}
else
{
JCArrayBufferManager::ArrayBufferContent* pBuffer2 = m_pArrayBufferManager->m_vBuffers[nIndex];
if (pBuffer2)
{
delete pBuffer2;
m_pArrayBufferManager->m_vBuffers[nIndex] = NULL;
}
}
}
/*
for (int i = 0; i < nSize;i++)
{
int nIndex = i;
JCArrayBufferManager::ArrayBufferContent* pBuffer1 = pJSManager->m_vBuffers[nIndex];
if (pBuffer1)
{
if (m_pArrayBufferManager->m_vBuffers[nIndex] == NULL)
{
m_pArrayBufferManager->m_vBuffers[nIndex] = new JCArrayBufferManager::ArrayBufferContent(pBuffer1->m_nType,true);
}
m_pArrayBufferManager->m_vBuffers[nIndex]->syncContent(pBuffer1);
}
else
{
JCArrayBufferManager::ArrayBufferContent* pBuffer2 = m_pArrayBufferManager->m_vBuffers[nIndex];
if (pBuffer2)
{
delete pBuffer2;
m_pArrayBufferManager->m_vBuffers[nIndex] = NULL;
}
}
}
*/
}
void JCConchRender::syncDeleteArrayBuffer(JCArrayBufferManager* pJSManager)
{
if (pJSManager->m_vPrepareDelIDs.size() <= 0)return;
std::vector<int>& vDeleteLists = pJSManager->m_vPrepareDelIDs;
int nSize = vDeleteLists.size();
for (int i = 0; i < nSize; i++)
{
int nIndex = vDeleteLists[i];
pJSManager->removeArrayBuffer(nIndex);
JCArrayBufferManager::ArrayBufferContent* pBuffer2 = m_pArrayBufferManager->m_vBuffers[nIndex];
if (pBuffer2)
{
delete pBuffer2;
m_pArrayBufferManager->m_vBuffers[nIndex] = NULL;
}
}
vDeleteLists.clear();
}
void JCConchRender::setRenderData(JCArrayBufferManager* pJSArrayBufferManger, JCArrayBufferManager::ArrayBufferContent* pSyncBufferList, int nSyncCount, JCCommandEncoderBuffer*& pRenderCmd,double& fDelay, double& fFPS)
{
if (pJSArrayBufferManger == NULL)
{
m_kRenderSem.waitUntilNoData();
if (pRenderCmd)
{
std::swap(pRenderCmd, m_pCurrentRenderCmds);
}
fDelay = m_nDelayTime;
fFPS = m_nFPS;
m_kRenderSem.setDataNum(1);
}
else
{
//开启线程锁
m_kRenderSem.waitUntilNoData();
//double nTime = tmGetCurms();
syncArrayBuffer(pJSArrayBufferManger, pSyncBufferList, nSyncCount);
syncDeleteArrayBuffer(pJSArrayBufferManger);
//double nSpace = tmGetCurms() - nTime;
//LOGI("syncArrayBuffer time space=%f",nSpace);
if (pRenderCmd)
{
std::swap(pRenderCmd, m_pCurrentRenderCmds);
}
fDelay = m_nDelayTime;
fFPS = m_nFPS;
m_kRenderSem.setDataNum(1);
}
}
void JCConchRender::setInterruptFunc(std::function<void(void)> pFunc)
{
if (g_kSystemConfig.m_nThreadMODE == THREAD_MODE_SINGLE)
{
pFunc();
}
else
{
m_kRenderSem.waitUntilNoData();
m_pInterruptFunc = pFunc;
m_kRenderSem.setDataNum(2);
m_kRenderSem.waitUntilNoData();
}
}
void onJSUpdate(void* pThis)
{
if (!JCConch::s_pConchRender->m_bStopRender)
{
JCScriptRuntime* pScriptRuntime = (JCScriptRuntime*)pThis;
pScriptRuntime->onUpdate();
}
}
#ifdef __APPLE__
int JCConchRender::renderFrame( long nCurrentFrame, bool bStopRender)
{
if(g_kSystemConfig.m_nThreadMODE == THREAD_MODE_DOUBLE)
{
if (m_bExit)return 0;
PERF_INITVAR(nTime123);
/*
if (!m_bStopRender)
{
if (JCScriptRuntime::s_JSRT)
{
JCScriptRuntime::s_JSRT->m_ScriptThread.post(std::bind(&JCScriptRuntime::onUpdate,JCScriptRuntime::s_JSRT));
}
}
*/
if (!m_bStopRender)
{
//线程等待
while (true)
{
m_kRenderSem.waitUntilHasData();
if (m_kRenderSem.getDataNum() == 2)
{
m_pInterruptFunc();
m_kRenderSem.setDataNum(0);
}
else
{
break;
}
}
}
//计算FPS
//------------------------------------------------------------------------------
m_nFrameCount++;
PERF_UPDATE_DTIME(JCPerfHUD::PHUD_FRAME_DELAY, JCPerfHUD::m_tmCurRender, JCPerfHUD::m_tmDelayTime);
m_nCountDelayTime += JCPerfHUD::m_tmDelayTime;
if (m_nFrameCount % 10 == 0)
{
m_nFPS = (10000 / m_nCountDelayTime);
m_nDelayTime = m_nCountDelayTime / 10;
//LOGI(">>>FPS=%.2f,DELAY=%.2f", m_nFPS, m_nDelayTime);
m_nCountDelayTime = 0;
}
//开始渲染
//------------------------------------------------------------------------------
PERF_INITVAR(nTime);
//开始解析
JCLayaGLDispatch::dispatchAllCmds(m_pCurrentRenderCmds);
m_pCurrentRenderCmds->clearData();
//imageManager的update 不需要每帧都调用
if (m_nFrameCount % 60 == 0)
{
m_pImageManager->update(m_nFrameCount);
}
//性能测试
PERF_UPDATE_DATA(JCPerfHUD::PHUD_RENDER_DELAY, (float)(tmGetCurms() - nTime));
//------------------------------------------------------------------------------
m_kRenderSem.setDataNum(0);
if (m_fShowPerfScale != 0)
{
m_kPerfRender.drawData();
}
FRAME_TYPE nFrameType = (g_kSystemConfig.m_nFrameType == FT_MOUSE) ? (nTime123 - m_fMouseMoveTime < g_kSystemConfig.m_nFrameThreshold ? FT_FAST : FT_SLOW) : g_kSystemConfig.m_nFrameType;
if (nFrameType == FT_SLOW)
{
int64_t nSleepTime = g_kSystemConfig.m_nSleepTime - (tmGetCurms() - nTime123);
if (nSleepTime > 0)
{
std::this_thread::sleep_for(std::chrono::milliseconds(nSleepTime));
}
}
return 0;
}
else
{
if (m_bExit)return 0;
PERF_INITVAR(nTime123);
if (JCScriptRuntime::s_JSRT && !m_bStopRender)
{
JSThreadInterface* pScriptThread = JCScriptRuntime::s_JSRT->m_pScriptThread;
pScriptThread->run(NULL, NULL);
}
//计算FPS
//------------------------------------------------------------------------------
m_nFrameCount++;
PERF_UPDATE_DTIME(JCPerfHUD::PHUD_FRAME_DELAY, JCPerfHUD::m_tmCurRender, JCPerfHUD::m_tmDelayTime);
m_nCountDelayTime += JCPerfHUD::m_tmDelayTime;
if (m_nFrameCount % 10 == 0)
{
m_nFPS = (10000 / m_nCountDelayTime);
m_nDelayTime = m_nCountDelayTime / 10;
//LOGI(">>>FPS=%.2f,DELAY=%.2f", m_nFPS, m_nDelayTime);
m_nCountDelayTime = 0;
}
//开始渲染
//------------------------------------------------------------------------------
PERF_INITVAR(nTime);
//imageManager的update 不需要每帧都调用
if (m_nFrameCount % 60 == 0)
{
m_pImageManager->update(m_nFrameCount);
}
//性能测试
PERF_UPDATE_DATA(JCPerfHUD::PHUD_RENDER_DELAY, (float)(tmGetCurms() - nTime));
//------------------------------------------------------------------------------
if (m_fShowPerfScale != 0)
{
m_kPerfRender.drawData();
}
FRAME_TYPE nFrameType = (g_kSystemConfig.m_nFrameType == FT_MOUSE) ? (nTime123 - m_fMouseMoveTime < g_kSystemConfig.m_nFrameThreshold ? FT_FAST : FT_SLOW) : g_kSystemConfig.m_nFrameType;
if (nFrameType == FT_SLOW)
{
int64_t nSleepTime = g_kSystemConfig.m_nSleepTime - (tmGetCurms() - nTime123);
if (nSleepTime > 0)
{
std::this_thread::sleep_for(std::chrono::milliseconds(nSleepTime));
}
}
return 0;
}
}
#else
int JCConchRender::renderFrame( long nCurrentFrame, bool bStopRender)
{
if (g_kSystemConfig.m_nThreadMODE == THREAD_MODE_DOUBLE)
{
PERF_INITVAR(nTime123);
if (m_bClearAllData)
{
_clearAllData();
m_bClearAllData = false;
}
if (JCScriptRuntime::s_JSRT)
{
JCScriptRuntime::s_JSRT->m_pScriptThread->post(std::bind(&JCScriptRuntime::onUpdate, JCScriptRuntime::s_JSRT));
}
if (m_bExit)return 0;
//线程等待
while (true)
{
m_kRenderSem.waitUntilHasData();
if (m_kRenderSem.getDataNum() == 2)
{
m_pInterruptFunc();
m_kRenderSem.setDataNum(0);
}
else
{
break;
}
}
//计算FPS相关的
//------------------------------------------------------------------------------
m_nFrameCount++;
PERF_UPDATE_DTIME(JCPerfHUD::PHUD_FRAME_DELAY, JCPerfHUD::m_tmCurRender, JCPerfHUD::m_tmDelayTime);
m_nCountDelayTime += JCPerfHUD::m_tmDelayTime;
if (m_nFrameCount % 10 == 0)
{
m_nFPS = (10000 / m_nCountDelayTime);
m_nDelayTime = m_nCountDelayTime / 10;
//LOGI(">>>FPS=%.2f,DELAY=%.2f", m_nFPS, m_nDelayTime);
m_nCountDelayTime = 0;
}
//开始渲染
//------------------------------------------------------------------------------
PERF_INITVAR(nTime);
//开始解析
JCLayaGLDispatch::dispatchAllCmds(m_pCurrentRenderCmds);
m_pCurrentRenderCmds->clearData();
//imageManager的update 不需要每帧都调用
m_pImageManager->update(m_nFrameCount);
//性能测试
PERF_UPDATE_DATA(JCPerfHUD::PHUD_RENDER_DELAY, (float)(tmGetCurms() - nTime));
//------------------------------------------------------------------------------
m_kRenderSem.setDataNum(0);
if (m_fShowPerfScale != 0)
{
m_kPerfRender.drawData();
}
FRAME_TYPE nFrameType = (g_kSystemConfig.m_nFrameType == FT_MOUSE) ? (nTime123 - m_fMouseMoveTime < g_kSystemConfig.m_nFrameThreshold ? FT_FAST : FT_SLOW) : g_kSystemConfig.m_nFrameType;
if (nFrameType == FT_SLOW)
{
int64_t nSleepTime = g_kSystemConfig.m_nSleepTime - (int)((tmGetCurms() - nTime123));
if (nSleepTime > 0)
{
std::this_thread::sleep_for(std::chrono::milliseconds(nSleepTime));
}
}
return 0;
}
else
{
PERF_INITVAR(nTime123);
if (m_bClearAllData)
{
_clearAllData();
m_bClearAllData = false;
}
if (JCScriptRuntime::s_JSRT->m_bReload == true)
{
JCScriptRuntime::s_JSRT->reload();
}
if (JCScriptRuntime::s_JSRT && !m_bStopRender)
{
JSThreadInterface* pScriptThread = JCScriptRuntime::s_JSRT->m_pScriptThread;
pScriptThread->run(onJSUpdate, JCScriptRuntime::s_JSRT);
//pScriptThread->post(std::bind(&JCScriptRuntime::onUpdate, JCScriptRuntime::s_JSRT));
//pScriptThread->run(NULL, NULL);
}
if (m_bExit)return 0;
//计算FPS相关的
//------------------------------------------------------------------------------
m_nFrameCount++;
PERF_UPDATE_DTIME(JCPerfHUD::PHUD_FRAME_DELAY, JCPerfHUD::m_tmCurRender, JCPerfHUD::m_tmDelayTime);
m_nCountDelayTime += JCPerfHUD::m_tmDelayTime;
if (m_nFrameCount % 10 == 0)
{
m_nFPS = (10000 / m_nCountDelayTime);
m_nDelayTime = m_nCountDelayTime / 10;
//LOGI(">>>FPS=%.2f,DELAY=%.2f", m_nFPS, m_nDelayTime);
m_nCountDelayTime = 0;
}
//开始渲染
//------------------------------------------------------------------------------
PERF_INITVAR(nTime);
//imageManager的update 不需要每帧都调用
m_pImageManager->update(m_nFrameCount);
//性能测试
PERF_UPDATE_DATA(JCPerfHUD::PHUD_RENDER_DELAY, (float)(tmGetCurms() - nTime));
//------------------------------------------------------------------------------
if (m_fShowPerfScale != 0)
{
m_kPerfRender.drawData();
}
FRAME_TYPE nFrameType = (g_kSystemConfig.m_nFrameType == FT_MOUSE) ? (nTime123 - m_fMouseMoveTime < g_kSystemConfig.m_nFrameThreshold ? FT_FAST : FT_SLOW) : g_kSystemConfig.m_nFrameType;
if (nFrameType == FT_SLOW)
{
int64_t nSleepTime = g_kSystemConfig.m_nSleepTime - (int)((tmGetCurms() - nTime123));
if (nSleepTime > 0)
{
std::this_thread::sleep_for(std::chrono::milliseconds(nSleepTime));
}
}
return 0;
}
}
#endif
void JCConchRender::willExit()
{
LOGI("render will exit");
m_bExit = true;
m_kRenderSem.notifyAllWait();
}
void JCConchRender::onTouchStart(double fTime)
{
m_fMouseMoveTime = fTime;
}
}
//------------------------------------------------------------------------------
//-----------------------------END FILE--------------------------------
+89
View File
@@ -0,0 +1,89 @@
/**
@file JCConchRender.h
@brief
@author James
@version 1.0
@date 2016_5_12
*/
#ifndef __JCConchRender_H__
#define __JCConchRender_H__
#include <JCIGLRender.h>
#include <fontMgr/JCFreeTypeRender.h>
#include <resource/JCFileResManager.h>
#include <misc/JCWorkSemaphore.h>
#include <Performance/JCPerfHUD.h>
#include <Manager/JCOrderResManager.h>
#include <LayaGL/JCLayaGL.h>
#include "RenderEx/JCRegister.h"
#include <misc/JCWorkerThread.h>
#ifdef __APPLE__
#include "IOSFreetype/JCIOSFreeType.h"
#endif
#include <atomic>
namespace laya
{
enum GL_CAPS
{
GLC_NONE = 0,
GLC_TEXTURE_COMPRESSION_PVR = 1 << 1,
GLC_TEXTURE_COMPRESSION_ETC1 = 1 << 2,
GLC_TEXTURE_COMPRESSION_ETC2 = 1 << 3,
GLC_NOPT = 1 << 4,
GLC_TEXTURE_TPG = 1 << 5,
GLC_INSTANCEING = 1 << 6,
};
class JCFileSource;
class JCConchRender : public JCIGLRender
{
public:
JCConchRender(void* pFileResManager,JCArrayBufferManager* pArrayBufferManager, JCRegister* pRegister,JCWebGLPlus* pWebGLPlus);
~JCConchRender();
void initOpenGLES();
void onGLReady();
void setRenderData(JCArrayBufferManager* pJSArrayBufferManger, JCArrayBufferManager::ArrayBufferContent* pSyncBufferList,int nSyncCount, JCCommandEncoderBuffer*& pRenderCmd,double& fDelay,double& fFPS);
void setInterruptFunc(std::function<void(void)> pFunc);
void syncArrayBuffer(JCArrayBufferManager* pManager, JCArrayBufferManager::ArrayBufferContent* pSyncBufferList,int nSyncCount);
void syncDeleteArrayBuffer(JCArrayBufferManager* pJSManager);
int renderFrame(long nCurrentFrame, bool bStopRender);
void clearAllData();
void willExit();
void setAssetRes(JCFileSource* pAssetRes);
void onTouchStart(double fTime);
private:
void _clearAllData();
public:
JCWorkerThread* m_pRenderThread;
float m_fShowPerfScale; ///<是否显示性能测试
long m_nFrameCount; ///<frameCount
bool m_bStopRender; ///<这个变量仅仅为了IOS使用的,因为IOS主线程(UI线程)和渲染线程是一个,所以增加了这个标记
bool m_bExit; ///<是否退出
JCImageManager* m_pImageManager; ///<Image管理器
JCIDGenerator* m_pIDGenerator;
JCIDGenerator* m_pProgramLocationTable;
JCLayaGL* m_pLayaGL; ///<layaGL
JCFileResManager* m_pFileResManager; ///<FileResManager 外部设置的
JCWorkSemaphore m_kRenderSem; ///<与js线程同步的对象。
JCPerfDataRender m_kPerfRender; ///<性能测试
JCArrayBufferManager* m_pArrayBufferManager; ///<ArrayBufferManager
JCRegister* m_pRegister;
JCCommandEncoderBuffer* m_pCurrentRenderCmds; ///<渲染指令流
private:
JCFileSource* m_pAssetsRes; ///<读取文件用的fileSource
double m_nFPS;
double m_nCountDelayTime;
double m_nDelayTime;
std::function<void(void)> m_pInterruptFunc;
float m_fMouseMoveTime;
#ifndef __APPLE__
std::atomic<bool> m_bClearAllData{ false };
#endif
};
}
//------------------------------------------------------------------------------
#endif //__JCConchRender_H__
//-----------------------------END FILE--------------------------------
+105
View File
@@ -0,0 +1,105 @@
/**
@file JCConch.cpp
@brief
@author guo
@version 1.0
@date 2016_5_13
*/
#include "JCConch.h"
#include <algorithm>
#include <util/Log.h>
#include <util/JCCommonMethod.h>
#include "JCConch.h"
#include "JCScrpitRuntimeWASM.h"
int g_nInnerWidth = 1024;
int g_nInnerHeight = 768;
bool g_bGLCanvasSizeChanged = false;
namespace laya
{
JCConch* JCConch::s_pConch = NULL;
int64_t JCConch::s_nUpdateTime = 0;
std::shared_ptr<JCConchRender> JCConch::s_pConchRender;
JCConch::JCConch(int nDownloadThreadNum)
{
s_pConchRender.reset(new JCConchRender(NULL));
s_pConchRender->setSize(g_nInnerWidth, g_nInnerHeight);
m_pScrpitRuntime = new JCScriptRuntime();
m_pScrpitRuntime->init(s_pConchRender->m_pFreeTypeRender);
s_pConch = this;
}
JCConch::~JCConch()
{
if (m_pScrpitRuntime)
{
delete m_pScrpitRuntime;
m_pScrpitRuntime = NULL;
}
s_pConchRender.reset();
s_pConch = NULL;
}
void JCConch::onAppStart()
{
}
void JCConch::reload()
{
}
void JCConch::DelAppRes()
{
}
void JCConch::onClearMemory()
{
}
void JCConch::onAppDestory()
{
}
void JCConch::postCmdToMainThread(int p_nCmd, int p_nParam1, int p_nParam2)
{
m_funcPostMsgToMainThread(p_nCmd, p_nParam1, p_nParam2);
}
int JCConch::urlHistoryLength()
{
return 0;
}
void JCConch::urlBack()
{
urlGo(-1);
}
void JCConch::urlGo(int s)
{
}
void JCConch::urlForward()
{
urlGo(1);
}
void JCConch::urlHistoryPush(const char* pUrl)
{
}
void JCConch::onRunCmdInMainThread(int p_nCmd, int p_nParam1, int p_nParam2)
{
switch (p_nCmd)
{
case JCConch::CMD_ActiveProcess:
break;
case JCConch::CMD_DeactiveProcess:
break;
case JCConch::CMD_CloseProcess:
break;
case JCConch::CMD_ReloadProcess:
reload();
break;
case JCConch::CMD_UrlBack:
urlBack();
break;
case JCConch::CMD_UrlForward:
break;
case JCConch::CMD_onOrientationChanged:
break;
}
}
};
//------------------------------------------------------------------------------
//-----------------------------END FILE--------------------------------
+700
View File
@@ -0,0 +1,700 @@
/**
@file JCScriptRuntime.cpp
@brief
@author James
@version 1.0
@date 2016_5_13
*/
#include "JCScriptRuntime.h"
#include <algorithm>
#include <util/Log.h>
#include "JSWrapper/JSInterface/JSInterface.h"
#include "JSWrapper/LayaWrap/JSFileReader.h"
#include "JSWrapper/LayaWrap/JSGlobalExportCFun.h"
#include "JSWrapper/LayaWrap/JSInput.h"
#include <downloadCache/JCFileSource.h>
#include <resource/JCFileResManager.h>
#include "Audio/JCAudioManager.h"
#include "JCSystemConfig.h"
#include "JCConch.h"
#include <Performance/JCPerfHUD.h>
#include <downloadMgr/JCDownloadMgr.h>
#include <inttypes.h>
#include "JSWrapper/LayaWrap/JSCallbackFuncObj.h"
#include "JSWrapper/LayaWrap/JSLayaGL.h"
#include <LayaGL/JCLayaGLDispatch.h>
#ifdef JS_V8
#include "JSWrapper/v8debug/debug-agent.h"
#endif
//#include "btBulletDynamicsCommon.h"
extern int g_nInnerWidth;
extern int g_nInnerHeight;
extern bool g_bGLCanvasSizeChanged;
#ifdef ANDROID
#include <android/configuration.h>
#include <dlfcn.h>
// Declaration for native chreographer API.
struct AChoreographer;
typedef void(*AChoreographer_frameCallback)(long frameTimeNanos, void* data);
typedef AChoreographer* (*func_AChoreographer_getInstance)();
typedef void(*func_AChoreographer_postFrameCallback)(
AChoreographer* choreographer, AChoreographer_frameCallback callback,
void* data);
// Function pointers for native Choreographer API.
func_AChoreographer_getInstance AChoreographer_getInstance_;
func_AChoreographer_postFrameCallback AChoreographer_postFrameCallback_;
void choreographer_callback(long frameTimeNanos, void* data);
double lastVSYNC = 0.0;
void StartChoreographer()
{
auto choreographer = AChoreographer_getInstance_();
AChoreographer_postFrameCallback_(choreographer, choreographer_callback, nullptr);
}
void choreographer_callback(long frameTimeNanos, void* data)
{
//LOGE("---TM:"PRIu64",d=%f", frameTimeNanos,(frameTimeNanos- lastVSYNC)/(1e6f));
double vsynctm = ((unsigned long)frameTimeNanos) / 1e6;
auto ctm = laya::tmGetCurms();
//LOGE("---TM:%f,d=%f,cur=%f,d=%f", (float)vsynctm, (float)(vsynctm - lastVSYNC) , ctm,(ctm-vsynctm));
laya::JCPerfHUD::m_tmVSYNC = vsynctm;
if (laya::JCScriptRuntime::s_JSRT) {
laya::JCScriptRuntime::s_JSRT->onVSyncEvent(vsynctm);
}
lastVSYNC = vsynctm;
StartChoreographer();
}
void initChoreographer()
{
return;//不用了,全部用java更方便一些。
//>=24
void* lib = dlopen("libandroid.so", RTLD_NOW | RTLD_LOCAL);
if (lib != nullptr)
{
LOGE("Run with Choreographer Native API.");
//api_mode_ = kAPINativeChoreographer;
// Retrieve function pointers from shared object.
AChoreographer_getInstance_ = reinterpret_cast<func_AChoreographer_getInstance>(dlsym(lib, "AChoreographer_getInstance"));
AChoreographer_postFrameCallback_ = reinterpret_cast<func_AChoreographer_postFrameCallback>(dlsym(lib, "AChoreographer_postFrameCallback"));
//assert(AChoreographer_getInstance_);
//assert(AChoreographer_postFrameCallback_);
//开始
if (AChoreographer_getInstance_)
StartChoreographer();
}
}
#endif
namespace laya
{
JCScriptRuntime* JCScriptRuntime::s_JSRT = NULL;
JCScriptRuntime::JCScriptRuntime()
{
#ifdef ANDROID
initChoreographer();
#endif
s_JSRT = this;
m_pPoster = NULL;
m_bHasJSThread = false;
m_pFileResMgr = NULL;
m_pAssetsRes = NULL;
m_bIsExit = false;
m_pUrl = new JCUrl();
m_nThreadState = 0;
m_bJSOnBackPressedFunctionSet = false;
m_bHasPostVsync = false;
m_pArrayBufferManager = JCWebGLPlus::getInstance()->m_pJSArrayBufferManager;
m_pABManagerSyncToRender = JCWebGLPlus::getInstance()->m_pJSABManagerSyncToRender;
m_pCallbackFuncManager = new JCOrderResManager<JSCallbackFuncObj>(false);
m_pRegister = new JCRegister();
JCAudioManager::GetInstance();
if (g_kSystemConfig.m_nThreadMODE == THREAD_MODE_SINGLE)
{
m_pScriptThread = new JSSingleThread();
}
else
{
m_pScriptThread = new JSMulThread();
}
if (g_kSystemConfig.m_nThreadMODE == THREAD_MODE_DOUBLE)
{
m_pRenderCmd = new JCCommandEncoderBuffer(102400, 1280);
}
else
{
m_pRenderCmd = new JCCommandEncoderBuffer(0,0);
}
m_pGCCmd = new JCCommandEncoderBuffer(2048, 2048);
//事件现在有问题,只能添加不能删除。所以不要调用多次。
m_pScriptThread->on(JCWorkerThread::Event_threadStart, std::bind(&JCScriptRuntime::onThreadInit, this, std::placeholders::_1));
m_pScriptThread->on(JCWorkerThread::Event_threadStop, std::bind(&JCScriptRuntime::onThreadExit, this, std::placeholders::_1));
m_nFPS = 60;
m_nDelayTime = 16;
m_nUpdateCount = 0;
m_bRunDraw = true;
m_dbLastUsedVsync = 0;
m_dbCurVsync = 0;
#ifdef ANDROID
m_pDbgAgent = nullptr;
m_pCurEditBox = NULL;
#elif __APPLE__
m_pCurEditBox = NULL;
#endif
m_bReload = false;
}
JCScriptRuntime::~JCScriptRuntime()
{
//在这时候js可能还在执行。需要先停止才能释放其运行环境。
#ifdef __APPLE__
m_pScriptThread->stop();
#else
if (g_kSystemConfig.m_nThreadMODE == THREAD_MODE_DOUBLE)
{
m_pScriptThread->stop();
}
#endif
if (m_pScriptThread)
{
delete m_pScriptThread;
m_pScriptThread = NULL;
}
s_JSRT = NULL;
m_pFileResMgr = NULL;
m_pAssetsRes = NULL;
if (m_pUrl)
{
delete m_pUrl;
m_pUrl = NULL;
}
if (m_pCallbackFuncManager)
{
delete m_pCallbackFuncManager;
m_pCallbackFuncManager = NULL;
}
if (m_pRegister)
{
delete m_pRegister;
m_pRegister = NULL;
}
if (m_pRenderCmd)
{
delete m_pRenderCmd;
m_pRenderCmd = NULL;
}
if (m_pGCCmd)
{
delete m_pGCCmd;
m_pGCCmd = NULL;
}
JCWebGLPlus::releaseInstance();
}
void JCScriptRuntime::init(JCFileResManager* pFileMgr, JCFileSource* pAssetRes, IConchThreadCmdMgr* pThreadCmdSender)
{
m_pFileResMgr = pFileMgr;
m_pAssetsRes = pAssetRes;
m_pPoster = pThreadCmdSender;
}
void JCScriptRuntime::start(const char* pStartJS)
{
LOGI("Start js %s", pStartJS);
if (pStartJS)m_strStartJS = pStartJS;
m_pScriptThread->initialize(JCConch::s_pConch->m_nJSDebugPort);
#ifdef __APPLE__
m_pScriptThread->setLoopFunc(std::bind(&JCScriptRuntime::onUpdate, this));
#endif
m_nThreadState = 1;
m_pScriptThread->start();
}
void JCScriptRuntime::stop()
{
LOGI("Stop js start...");
while (m_nThreadState==1)
{
LOGI("stop: wait for thread to start...");
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
#ifdef __APPLE__
if (JCConch::s_pConchRender)
{
while (JCConch::s_pConchRender->m_kRenderSem.getDataNum() == 1)
{
JCConch::s_pConchRender->renderFrame(0, false);
}
}
#endif
m_pScriptThread->stop();
m_pScriptThread->uninitialize();
LOGI("Stop js end.");
}
void JCScriptRuntime::reload()
{
m_bReload = false;
#ifdef __APPLE__
if(JCConch::s_pConchRender)
{
JCConch::s_pConchRender->m_bStopRender = true;
}
#else
if (g_kSystemConfig.m_nThreadMODE == THREAD_MODE_SINGLE)
{
JCConch::s_pConchRender->m_bStopRender = true;
}
#endif
stop();
//为了避免上个js的下载的影响,去掉下载任务
//这个必须在stop之后做,且保证stop确实会停止线程,包括还没有启动的线程。
//如果线程还没有启动,stop会等待线程先启动。这样就可能会执行脚本,所以,清理必须放在stop之后。
JCDownloadMgr* pNetLoader = JCDownloadMgr::getInstance();
pNetLoader->stopCurTask();
pNetLoader->clearAllAsyncTask();
pNetLoader->resetDownloadTail(); //防止第二次进入的时候,下载错误的dcc等
pNetLoader->resetFinalReplacePath();
pNetLoader->resetDownloadReplaceExt();
//文件资源不能跨js环境使用,所以必须clear
// 例如一个资源正在下载,则可能的问题:1.可能会上个线程取消了,不会再回调, 2. 自己希望回调的是上个js环境,也无法传给新的js环境。
// 所以需要clear。
m_pFileResMgr->clear();
start(m_strStartJS.c_str());
#ifndef __APPLE_
if (g_kSystemConfig.m_nThreadMODE == THREAD_MODE_SINGLE)
{
if (JCConch::s_pConch)
{
JCConch::s_pConch->postCmdToMainThread(JCConch::CMD_MgrStartThread, 0, 0);
}
}
#endif
}
void JCScriptRuntime::onThreadInit(JCEventEmitter::evtPtr evt)
{
LOGI("js thread started.");
m_nThreadState = 2;
JCPerfHUD::resetFrame();
#ifdef JS_V8
JSObjNode::s_pListJSObj = new JCSimpList();
if (m_pDbgAgent)
{
m_pDbgAgent->onJSStart(m_pScriptThread,(JCConch::s_pConch->m_nJSDebugMode == JS_DEBUG_MODE_WAIT) ? true : false);
LOGI("js debug open mode: %d port %d", JCConch::s_pConch->m_nJSDebugMode, JCConch::s_pConch->m_nJSDebugPort);
}
else
{
LOGI("js debug closed");
}
#endif
JCConch::s_pConchRender->m_pImageManager->resetJSThread();
//JS线程的数据清空一下
m_pCallbackFuncManager->clearAllRes();
m_pCallbackFuncManager->resetGlobalID();
m_pArrayBufferManager->clearAll();
m_pABManagerSyncToRender->clearAll();
//给渲染线程发开始指令
startScriptOnRenderThread();
JsFile::RegisterToJS();
JsFileReader::RegisterToJS();
JSGlobalExportC();
//设置js的一些环境。必须在所有导出之后,执行其他脚本之前。
#ifndef WIN32
JSP_RUN_SCRIPT((const char*)"function getExePath(){return null;}");
#endif
{
char* sJSRuntime = NULL;
int nSize = 0;
if (m_pAssetsRes->loadFileContent("scripts/runtimeInit.js", sJSRuntime, nSize))
{
JSP_RUN_SCRIPT(sJSRuntime);
delete[] sJSRuntime;
}
}
char* sJCBuffer = NULL;
int nJSSize = 0;
if (m_pAssetsRes->loadFileContent(m_strStartJS.c_str(), sJCBuffer, nJSSize))
{
std::string kBuf = "(function(window){\n'use strict'\n";
kBuf += sJCBuffer;
kBuf += "\n})(window);\n//@ sourceURL=apploader.js";
#ifdef JS_V8
v8::Isolate* isolate = v8::Isolate::GetCurrent();
v8::HandleScope handle_scope(isolate);
v8::TryCatch try_catch(isolate);
JSP_RUN_SCRIPT(kBuf.c_str());
if (try_catch.HasCaught())
{
__JSRun::ReportException(isolate, &try_catch);
}
#else
JSP_RUN_SCRIPT(kBuf.c_str());
#endif
delete[] sJCBuffer;
sJCBuffer = NULL;
}
#ifndef __APPLE__
if (g_kSystemConfig.m_nThreadMODE == THREAD_MODE_DOUBLE)
{
m_pScriptThread->post(std::bind(&JCScriptRuntime::onUpdate, this));
}
#endif
JSP_RUN_SCRIPT("gc();gc();gc();");
}
void JCScriptRuntime::onThreadExit(JCEventEmitter::evtPtr evt)
{
if (m_nThreadState == 0)
{
return;
}
LOGI("js thread exiting...");
m_nThreadState = 0;
m_pJSOnFrameFunction.Reset();
m_pJSOnResizeFunction.Reset();
m_pJSOnFocusFunction.Reset();
m_pJSOnBlurFunction.Reset();
m_pJSMouseEvtFunction.Reset();
m_pJSKeyEvtFunction.Reset();
m_pJSTouchEvtFunction.Reset();
m_pJSDeviceMotionEvtFunction.Reset();
m_pJSNetworkEvtFunction.Reset();
m_pJSOnBackPressedFunction.Reset();
m_pJSOnceOtherEvtFuction.Reset();
m_pJSOnDrawFunction.Reset();
m_bJSBulletGetWorldTransformHandle.Reset();
m_bJSBulletSetWorldTransformHandle.Reset();
#ifdef ANDROID
m_pCurEditBox = NULL;
#endif
JSClassMgr::GetThreadInstance()->resetAllRegClass();
#ifdef JS_V8
JCSimpList* pNodeLists = JSObjNode::s_pListJSObj;
if (pNodeLists != NULL)
{
JCListNode* pCur = pNodeLists->begin();
JCListNode* pEnd = pNodeLists->end();
while (pCur != pEnd)
{
JSObjNode* pJsCur = (JSObjNode*)pCur;
pCur = pNodeLists->delNode(pCur);
delete pJsCur;
}
delete JSObjNode::s_pListJSObj;
JSObjNode::s_pListJSObj = nullptr;
}
if (m_pDbgAgent)
{
m_pDbgAgent->onJSExit();
}
#elif JS_JSC
JSP_RESET_GLOBAL_FUNCTION;
#endif
JCAudioManager::ClearAllWork();
JCAudioManager::GetInstance()->stopMp3();
JCAudioManager::GetInstance()->pauseMp3();
m_pCallbackFuncManager->clearAllRes();
m_pCallbackFuncManager->resetGlobalID();
JCWebGLPlus::getInstance()->clearAll();
}
bool JCScriptRuntime::onUpdate()
{
PERF_INITVAR(nBenginTime);
#ifdef JS_V8
m_pScriptThread->runDbgFuncs();
#endif
m_nUpdateCount++;
bool bRunOnDraw = false;
double nTime = tmGetCurms();
#ifdef ANDROID1
if (m_bRunDraw)
{
m_bRunDraw = false;
bRunOnDraw = true;
m_dbLastUsedVsync = m_dbCurVsync;
onUpdateDraw(m_dbCurVsync);
}
#else
if (!g_kSystemConfig.m_bUseChoreographer)
{
JCPerfHUD::m_tmVSYNC = nTime;
}
#endif
onUpdateDraw(JCPerfHUD::m_tmVSYNC);
JSInput* pInput = JSInput::getInstance();
if ( pInput->m_bTouchMode )
{
pInput->swapCurrentTouchEvent();
if( pInput->m_vInputEventsJS.size() > 0 )
{
pInput->m_nTouchFrame = 120;
for (int i = 0, nSize = (int)pInput->m_vInputEventsJS.size(); i < nSize; i++ )
{
TouchEventInfo* touchEvent = &pInput->m_vInputEventsJS[i];
m_pJSTouchEvtFunction.Call(touchEvent->nType, touchEvent->nID,"type",touchEvent->x, touchEvent->y);
}
}
if( pInput->m_nTouchFrame > 0 )
{
pInput->m_nTouchFrame--;
}
}
if (g_bGLCanvasSizeChanged)
{
m_pJSOnResizeFunction.Call(g_nInnerWidth, g_nInnerHeight);
//m_pRootCanvas->size( g_nInnerWidth,g_nInnerHeight );
g_bGLCanvasSizeChanged = false;
}
int nUpdateNum = m_nUpdateCount % 3;
switch (nUpdateNum)
{
case 0:
JCAudioManager::GetInstance()->update();
break;
case 1:
//如果有需要清理的或者update可以放到这
JCAudioManager::GetInstance()->m_pWavPlayer->autoGarbageCollection();
break;
case 2:
//如果有需要清理的或者update可以放到这
break;
}
JS_TRY;
m_pJSOnFrameFunction.Call();
JS_CATCH;
float dt = tmGetCurms() - nBenginTime;
PERF_UPDATE_DATA(JCPerfHUD::PHUD_JS_DELAY, (float)dt);
return true;
}
void JCScriptRuntime::onUpdateDraw(double vsyncTime)
{
m_bHasPostVsync = false;
if (!m_pJSOnDrawFunction.Empty())
{
JS_TRY;
m_pJSOnDrawFunction.Call(vsyncTime);
JS_CATCH;
runLayaGL();
}
}
void JCScriptRuntime::runLayaGL()
{
JSLayaGL* pLayaGL = JSLayaGL::getInstance();
if (pLayaGL->m_nFrameAndSyncCountABListID != -1)
{
//恢复frameCount和syncCount
JCArrayBufferManager::ArrayBufferContent* pBuffer = m_pArrayBufferManager->getArrayBuffer(pLayaGL->m_nFrameAndSyncCountABListID);
if (pBuffer)
{
int* pData = (int*)pBuffer->m_pBuffer;
pLayaGL->m_nSyncArrayBufferCount=pData[1];
pData[0]++;
pData[1]=0;
pLayaGL->m_nFrameCount = pData[0];
}
}
if (g_kSystemConfig.m_nThreadMODE == THREAD_MODE_DOUBLE)
{
flushSharedCmdBuffer();
if (m_pGCCmd->getDataSize() > 0)
{
m_pRenderCmd->append(m_pGCCmd->getBuffer(), m_pGCCmd->getDataSize());
m_pGCCmd->clearData();
}
if (pLayaGL->m_nSyncToRenderABListID != -1)
{
JCArrayBufferManager::ArrayBufferContent* pSyncBufferList = m_pArrayBufferManager->getArrayBuffer(pLayaGL->m_nSyncToRenderABListID);
JCConch::s_pConchRender->setRenderData(m_pABManagerSyncToRender, pSyncBufferList, pLayaGL->m_nSyncArrayBufferCount, m_pRenderCmd, m_nDelayTime, m_nFPS);
}
else
{
JCConch::s_pConchRender->setRenderData(NULL, NULL, 0, m_pRenderCmd, m_nDelayTime, m_nFPS);
}
}
else
{
dispatchLayaGLBuffer(true);
}
}
void JCScriptRuntime::dispatchLayaGLBuffer(bool bDispatchGC)
{
JCArrayBufferManager::ArrayBufferContent* pRootCommandEncoder = JSLayaGL::getInstance()->m_pRootCommandEncoder;
if (!pRootCommandEncoder)return;
char* pBuffer = pRootCommandEncoder->m_pBuffer;
int nLen = (*(int*)pBuffer - 1) * 4;
m_pRenderCmd->setShareBuffer(pBuffer + 4, nLen);
((int*)pBuffer)[0] = 1;
JCLayaGLDispatch::dispatchAllCmds(m_pRenderCmd);
m_pRenderCmd->clearData();
if (bDispatchGC && m_pGCCmd->getDataSize() > 0)
{
JCLayaGLDispatch::dispatchAllCmds(m_pGCCmd);
m_pGCCmd->clearData();
}
}
void JCScriptRuntime::flushSharedCmdBuffer()
{
JCArrayBufferManager::ArrayBufferContent* pRootCommandEncoder = JSLayaGL::getInstance()->m_pRootCommandEncoder;
if (!pRootCommandEncoder)return;
char* pBuffer = pRootCommandEncoder->m_pBuffer;
int nLen = (*(int*)pBuffer - 1)*4;
if (nLen > 0)
{
//TODO想办法不拷贝,改成share
m_pRenderCmd->append(pBuffer + 4, nLen);
((int*)pBuffer)[0] = 1;
}
}
void JCScriptRuntime::onVSyncEvent(double vsyncTime)
{
JCPerfHUD::m_tmVSYNC = vsyncTime;
m_dbCurVsync = vsyncTime;
//m_bRunDraw = true;
//这个事件的速度始终固定,但是js可能会非常卡,导致大量积累,所以要保护 一下。
if (!m_bHasPostVsync)
{
m_bHasPostVsync = true;
m_pScriptThread->post(std::bind(&JCScriptRuntime::onUpdate, this));
}
}
void JCScriptRuntime::dispatchInputEvent(inputEvent e)
{
JSInput::getInstance()->activeCall(e);
}
void JCScriptRuntime::dispatchInputEvent(DeviceOrientationEvent e)
{
JSInput::getInstance()->activeCall(e);
}
void JCScriptRuntime::dispatchInputEvent(DeviceMotionEvent e)
{
JSInput::getInstance()->activeCall(e);
}
void JCScriptRuntime::onNetworkChanged(int nType)
{
std::function<void(void)> pFunction = std::bind(&JCScriptRuntime::onNetworkChangedCallJSFunction, this, nType);
m_pScriptThread->post(pFunction);
}
void JCScriptRuntime::onNetworkChangedCallJSFunction(int nType)
{
m_pJSNetworkEvtFunction.Call(nType);
}
void JCScriptRuntime::jsGC()
{
std::function<void(void)> pFunction = std::bind(&JCScriptRuntime::jsGCCallJSFunction, this);
m_pScriptThread->post(pFunction);
}
void JCScriptRuntime::jsGCCallJSFunction()
{
JSP_RUN_SCRIPT("gc()");
}
void JCScriptRuntime::callJC(std::string sFunctionName, std::string sJsonParam, std::string sCallbackFunction)
{
std::function<void(void)> pFunction = std::bind(&JCScriptRuntime::callJSFuncton, this, sFunctionName, sJsonParam, sCallbackFunction );
m_pScriptThread->post(pFunction);
}
void JCScriptRuntime::callJSString( std::string sBuffer )
{
std::function<void(void)> pFunction = std::bind(&JCScriptRuntime::callJSStringFunction, this,sBuffer);
m_pScriptThread->post(pFunction);
}
void JCScriptRuntime::callJSStringFunction( std::string sBuffer )
{
JSP_RUN_SCRIPT(sBuffer.c_str());
}
void JCScriptRuntime::callJSFuncton(std::string sFunctionName, std::string sJsonParam, std::string sCallbackFunction)
{
std::string sBuffer = sFunctionName;
sBuffer += "(\"";
sBuffer += sJsonParam;
sBuffer += "\",\"";
sBuffer += sCallbackFunction;
sBuffer += "\");";
LOGI("JCScriptRuntime::callJSFuncton buffer=%s",sBuffer.c_str() );
JSP_RUN_SCRIPT( sBuffer.c_str() );
}
void JCScriptRuntime::restoreAudio()
{
std::function<void(void)> pFunction = std::bind(&JCScriptRuntime::jsRestoreAudioFunction, this);
m_pScriptThread->post(pFunction);
}
void JCScriptRuntime::jsRestoreAudioFunction()
{
if(JCAudioManager::GetInstance()->getMp3Mute() == false && JCAudioManager::GetInstance()->getMp3Stopped() == false)
{
JCAudioManager::GetInstance()->resumeMp3();
}
}
void JCScriptRuntime::jsReloadUrl()
{
std::function<void(void)> pFunction = std::bind(&JCScriptRuntime::jsReloadUrlJSFunction, this);
m_pScriptThread->post(pFunction);
}
void JCScriptRuntime::jsReloadUrlJSFunction()
{
JSP_RUN_SCRIPT("reloadJS(true)");
}
void JCScriptRuntime::jsUrlback()
{
std::function<void(void)> pFunction = std::bind(&JCScriptRuntime::jsUrlbackJSFunction, this);
m_pScriptThread->post(pFunction);
}
void JCScriptRuntime::jsUrlbackJSFunction()
{
JSP_RUN_SCRIPT("history.back()");
}
void JCScriptRuntime::startScriptOnRenderThread()
{
m_pRenderCmd->clearData();
m_pGCCmd->clearData();
if (JCConch::s_pConch)
{
#ifdef __APPLE__
JCConch::s_pConch->postCmdToMainThread(JCConch::CMD_ClearRender, 0, 0);
#else
if (JCConch::s_pConchRender){
JCConch::s_pConchRender->clearAllData();
}
#endif
}
}
bool JCScriptRuntime::onBackPressed()
{
std::lock_guard<std::mutex> lock(m_OnBackPressedMutex);
if (!m_bJSOnBackPressedFunctionSet)
{
return false;
}
if (JCScriptRuntime::s_JSRT->m_pPoster)
{
JCScriptRuntime::s_JSRT->m_pPoster->postToJS([this]() {
this->m_pJSOnBackPressedFunction.Call();
});
}
return true;
}
void JCScriptRuntime::postToJS(const std::function<void(void)>& func)
{
m_pScriptThread->post(func);
}
void JCScriptRuntime::postToDownload(const std::function<void(void)>& funcf)
{
}
void JCScriptRuntime::postToDecoder(const std::function<void(void)>& func)
{
}
}
//------------------------------------------------------------------------------
//-----------------------------END FILE--------------------------------
+285
View File
@@ -0,0 +1,285 @@
/**
@file JCScriptRuntime.h
@brief
@author James
@version 1.0
@date 2016_5_13
*/
#ifndef __JCScriptRuntime_H__
#define __JCScriptRuntime_H__
#include <vector>
#include <util/JCCommonMethod.h>
#include "JSWrapper/JSInterface/JSInterface.h"
#include <fontMgr/JCFreeTypeRender.h>
#include "util/JCLayaUrl.h"
#include <mutex>
#include <Manager/JCArrayBufferManager.h>
#include <Manager/JCOrderResManager.h>
#include <RenderEx/JCRegister.h>
#ifdef ANDROID
#include "JSWrapper/LayaWrap/JSAndroidEditBox.h"
#elif __APPLE__
#include "JSWrapper/LayaWrap/JSIOSEditBox.h"
#endif
#include <util/JCIThreadCmdMgr.h>
namespace laya
{
enum NetworkType
{
NET_NO = 0,
NET_WIFI = 1,
NET_2G = 2,
NET_3G = 3,
NET_4G = 4,
NET_YES = 5,
};
struct inputEvent
{
char type[256];
int nType;
int key;
int posX;
int posY;
int keyChar;
int keyCode;
int nWheel;
float fTHUMBL_xOffset;
float fTHUMBL_yOffset;
float fTHUMBR_xOffset;
float fTHUMBR_yOffset;
float fLT_Offset;
float fRT_Offset;
bool bCtrl;
bool bAlt;
bool bShift;
int id;
int nTouchType; //是用来传给js的
inputEvent()
{
memset(type, 0, 256);
nType = 0;
key = 0;
posX = 0;
posY = 0;
keyChar = 0;
keyCode = 0;
nWheel = 0;
fTHUMBL_xOffset = fTHUMBL_yOffset = fTHUMBR_xOffset = fTHUMBR_yOffset = fLT_Offset = fRT_Offset = .0f;
bCtrl = bAlt = bShift = false;
id = 0;
nTouchType = 0;
}
};
struct DeviceOrientationEvent
{
char type[256];
int nType;
float ra;
float rb;
float rg;
};
struct DeviceMotionEvent:public DeviceOrientationEvent
{
float ax;
float ay;
float az;
float agx;
float agy;
float agz;
float interval;
};
enum EINPUTTYPE
{
E_ONTOUCHSTART = 0X01,
E_ONTOUCHMOVE,
E_ONTOUCHEND,
E_ONACTION_POINTER_DOWN,
E_ONACTION_POINTER_UP,
E_ONMOUSEDOWN,
E_ONMOUSEMOVE,
E_ONMOUSEWHEEL,
E_ONMOUSEUP,
E_ONRIGHTMOUSEDOWN,
E_ONRIGHTMOUSEUP,
E_ONKEYDOWN,
E_ONKEYUP,
E_JOYSTICK,
E_DEVICEMOTION,
E_DEVICEORIENTATION,
E_TYPE_COUNT,
};
#ifdef JS_V8
class DebuggerAgent;
#endif
class JSLayaGL;
class JCFileResManager;
class JCFileSource;
class JSCallbackFuncObj;
class JCScriptRuntime : public IConchThreadCmdMgr
{
public:
JCScriptRuntime();
~JCScriptRuntime();
/** @brief
初始化js环境。
* @param[in] pFileMgr
* @param[in] pAssetRes
* @param[in] pThreadCmdSender 跨线程发送消息的统一管理。避免各个线程直接发送消息导,以简化退出流程。
* @return void
*/
void init(JCFileResManager* pFileMgr, JCFileSource* pAssetRes, IConchThreadCmdMgr* pThreadCmdSender);
void start(const char* pStartJS);
void stop();
void reload();
void onThreadInit(JCEventEmitter::evtPtr evt);
bool onUpdate();
void onUpdateTimer();
//每次需要渲染的时候触发js
void onUpdateDraw(double vsyncTime);
void flushSharedCmdBuffer();
void dispatchLayaGLBuffer(bool bDispatchGC);
void runLayaGL();
//输入事件触发js
void onUpdateInput();
/*
可以调用渲染流程了。
参数是当前的垂直回扫的时间。
本来打算在垂直回扫的时候post一个函数到js线程执行。但是这样有个问题就是如果js卡了,会积累大量的函数。
所以采用这个简单的方法。
*/
void onVSyncEvent(double vsyncTime);
void onThreadExit(JCEventEmitter::evtPtr evt);
void dispatchInputEvent(inputEvent e);
void dispatchInputEvent(DeviceOrientationEvent e);
void dispatchInputEvent(DeviceMotionEvent e);
public:
void jsGC();
void jsGCCallJSFunction();
void callJSString( std::string sBuffer );
void callJSStringFunction( std::string sBuffer );
void jsReloadUrl();
void jsReloadUrlJSFunction();
void jsUrlback();
void jsUrlbackJSFunction();
void restoreAudio();
void jsRestoreAudioFunction();
void onNetworkChanged(int nType);
void onNetworkChangedCallJSFunction(int nType);
void callJC( std::string sFunctionName,std::string sJsonParam,std::string sCallbackFunction );
void callJSFuncton(std::string sFunctionName, std::string sJsonParam, std::string sCallbackFunction);
bool onBackPressed();
public:
void postToJS(const std::function<void(void)>& func);
void postToDownload(const std::function<void(void)>& funcf);
void postToDecoder(const std::function<void(void)>& func);\
private:
void startScriptOnRenderThread();
public:
static JCScriptRuntime* s_JSRT;
JCCommandEncoderBuffer* m_pRenderCmd; //渲染指令流
JCCommandEncoderBuffer* m_pGCCmd; //垃圾回收的指令流
bool m_bReload;
JSThreadInterface* m_pScriptThread;
bool m_bHasJSThread; //js线程是否在工作
JsObjHandle m_pJSOnFrameFunction;
JsObjHandle m_pJSOnDrawFunction; //垂直回扫同步
JsObjHandle m_pJSOnResizeFunction;
JsObjHandle m_pJSOnBlurFunction;
JsObjHandle m_pJSOnFocusFunction;
JsObjHandle m_pJSMouseEvtFunction; //鼠标事件回调
JsObjHandle m_pJSKeyEvtFunction;
JsObjHandle m_pJSTouchEvtFunction;
JsObjHandle m_pJSDeviceMotionEvtFunction; //重力感应
JsObjHandle m_pJSOnceOtherEvtFuction; //注册一次的事件 如截屏
JsObjHandle m_pJSNetworkEvtFunction; //网络事件的监听
JsObjHandle m_pJSOnBackPressedFunction;
bool m_bJSOnBackPressedFunctionSet;
JsObjHandle m_bJSBulletGetWorldTransformHandle;
JsObjHandle m_bJSBulletSetWorldTransformHandle;
std::mutex m_OnBackPressedMutex;
std::string m_strStartJS;
JCFileResManager* m_pFileResMgr; //外部设置的。本地不允许删除
JCFileSource* m_pAssetsRes; //外部设置的。本地不允许删除
IConchThreadCmdMgr* m_pPoster;
bool m_bIsExit;
char* m_pOtherBufferSharedWidthJS;
int m_nUpdateCount; //update次数
JCUrl* m_pUrl;
/*
* 确保线程已经开始了。有时候想结束线程,但是实际线程还没起来(结束请求太快)
* 确保线程已经开始了。有时候想结束线程,但是实际线程还没起来(结束请求太快)
* 需要靠这个状态来判断是否已经起来了。防止stop之后,线程才起来,导致混乱。
*/
int m_nThreadState;
JCOrderResManager<JSCallbackFuncObj>* m_pCallbackFuncManager; ///<回调函数的管理器
JCRegister* m_pRegister; ///<寄存器
JCArrayBufferManager* m_pArrayBufferManager; ///<ArrayBufferManager
JCArrayBufferManager* m_pABManagerSyncToRender; ///<ArrayBufferManager,这个是需要同步给渲染线程的
bool m_bHasPostVsync; ///避免发送太多的同步事件
#ifdef ANDROID
JSAndroidEditBox* m_pCurEditBox;
#elif __APPLE__
JSIOSEditBox * m_pCurEditBox;
#endif
#ifdef JS_V8
DebuggerAgent* m_pDbgAgent;
#endif
private:
bool m_bRunDraw;
/*
希望每次垂直回扫的时候都能执行js。但实际做不到。
记录 m_dbLastUsedVsync 可以知道实际两次调用之间到底跨越了多少,即丢了多少帧
记录 m_dbCurVsync 可以用来判断距离最近的垂直回扫的时间,从而可以判断是否需要主动减少当前帧的工作量(例如不重要的事情可以分帧做)
上次实际调用draw的时候对应的时间。在卡的情况下
*/
double m_dbLastUsedVsync;
double m_dbCurVsync;
double m_nFPS;
double m_nDelayTime;
};
}
//------------------------------------------------------------------------------
#endif //__JCScriptRuntime_H__
//-----------------------------END FILE--------------------------------
+167
View File
@@ -0,0 +1,167 @@
/**
@file JCScrpitRuntimeWASM.cpp
@brief
@author James
@version 1.0
@date 2017_9_25
*/
#include "JCScrpitRuntimeWASM.h"
#include <algorithm>
#include <util/Log.h>
#include "JCSystemConfig.h"
#include "JCConch.h"
//#include <Performance/JCPerfHUD.h>
#include "JCCmdDispatchManager.h"
#include <downloadMgr/JCDownloadMgr.h>
#include <inttypes.h>
#include <RenderCmd/CmdBase.h>
#include <RenderCmd/CmdFunction.h>
namespace laya
{
#define RENDERCMD_RESERVE_NUM 2048
JCScriptRuntime* JCScriptRuntime::s_JSRT = NULL;
JCScriptRuntime::JCScriptRuntime()
{
s_JSRT = this;
JCICmdDispatch::resetDispathGlobalID();
m_pJSCmdBuffer = new JCMemClass(MEM_RENDER_COMMAND_SIZE, MEM_RENDER_COMMAND_SIZE);
m_pJSCmdBuffer->setAlign(true);
m_pTextManager = new JCTextManager(JCConch::s_pConchRender->m_pAtlasManager);
m_pFontManager = new JCFontManager();
m_pMeasureTextManager = new JCMeasureTextManager();
m_pCmdDispathManager = new JCCmdDispathManager();
m_nCountGroup = 0;
m_nCountVertex = 0;
m_nCountNode = 0;
m_pRootHtml5Context = NULL;
m_pRootNode = NULL;
m_pFreeTypeRender = NULL;
onThInit();
}
JCScriptRuntime::~JCScriptRuntime()
{
onThExit();
s_JSRT = NULL;
m_pFreeTypeRender = NULL;
if (m_pJSCmdBuffer)
{
delete m_pJSCmdBuffer;
m_pJSCmdBuffer = NULL;
}
if (m_pFontManager)
{
delete m_pFontManager;
m_pFontManager = NULL;
}
if( m_pMeasureTextManager )
{
delete m_pMeasureTextManager;
m_pMeasureTextManager = nullptr;
}
if (m_pTextManager)
{
delete m_pTextManager;
m_pTextManager = NULL;
}
if (m_pCmdDispathManager)
{
delete m_pCmdDispathManager;
m_pCmdDispathManager = NULL;
}
m_pRootNode = NULL;
JCNode2DRenderer::clearAll();
}
void JCScriptRuntime::init(JCFreeTypeFontRender* pFreeTypeRender )
{
m_pFreeTypeRender = pFreeTypeRender;
m_pMeasureTextManager->setFreeTypeFontRender(m_pFreeTypeRender);
m_pTextManager->setFreeTypeRender(m_pFreeTypeRender);
}
void JCScriptRuntime::onThInit()
{
m_pRootHtml5Context = NULL;
//JCPerfHUD::resetFrame();
m_vRenderCmds.reserve(RENDERCMD_RESERVE_NUM);
JCConch::s_pConchRender->m_pImageManager->resetJSThread();
JCICmdDispatch::resetDispathGlobalID();
m_pJSCmdBuffer->clearData();
startScriptOnRenderThread();
JCNode2DRenderer::initAll();
}
bool JCScriptRuntime::onUpdate()
{
m_nUpdateCount++;
onUpdateDraw(0);
//释放已经丢弃的cmd指令
//CmdBase::releaseDiscardedCmds();
return true;
}
void JCScriptRuntime::onUpdateDraw(double vsyncTime)
{
dispatchScriptCmd();
if (JCConch::s_pConchRender != NULL)
{
if (m_pRootHtml5Context)
{
if (m_pRootNode)
{
m_pRootNode->render(m_pRootHtml5Context, 0, 0);
}
}
//setRenderData
int nRenderCmdSize = m_vRenderCmds.size();
JCConch::s_pConchRender->setRenderData(m_vRenderCmds, m_nCountGroup, m_nCountVertex, m_nCountNode);
JCConch::s_pConchRender->renderFrame(0,false);
if (nRenderCmdSize > RENDERCMD_RESERVE_NUM)
{
m_vRenderCmds.reserve(nRenderCmdSize);
}
}
}
void JCScriptRuntime::onThExit()
{
m_pRootHtml5Context = NULL;
//清空文字相关的
m_pMeasureTextManager->clearAll();
m_pFontManager->clearAllData();
//清空会非法,这个地方先重用这
//m_pTextManager->clearAll();
m_pCmdDispathManager->clearAll();
}
void JCScriptRuntime::flushSharedCmdBuffer()
{
char* pBuff = m_pCmdBufferSharedWithJS;
if (!pBuff)return;
int len = *(int*)pBuff;
m_pJSCmdBuffer->append(pBuff + 4, len-4);
((int*)pBuff)[0] = 4;
}
void JCScriptRuntime::setJSCmdBuffer(char* pBuffer)
{
int nLen = *(int*)pBuffer;
m_pJSCmdBuffer->setExternalBuffer(pBuffer + 4, nLen - 4);
}
void JCScriptRuntime::dispatchScriptCmd()
{
m_pCmdDispathManager->dispatchScriptCmd(*m_pJSCmdBuffer, m_nUpdateCount);
m_pJSCmdBuffer->clearData();
}
void JCScriptRuntime::setRootNode(JCNode2D* pNode)
{
m_pRootNode = pNode;
}
void JCScriptRuntime::startScriptOnRenderThread()
{
CmdFunction* pObject = CmdFunction::create(-1);
pObject->m_pFunction = std::bind([]() {
JCConch::s_pConchRender->clearAllData();
});
m_vRenderCmds.push_back(pObject);
}
}
//------------------------------------------------------------------------------
//-----------------------------END FILE--------------------------------
+83
View File
@@ -0,0 +1,83 @@
/**
@file JCScrpitRuntimeWASM.h
@brief
@author James
@version 1.0
@date 2017_9_25
*/
#ifndef __JCScrpitRuntimeWASM_H__
#define __JCScrpitRuntimeWASM_H__
#include <vector>
#include <util/JCCommonMethod.h>
#include <buffer/JCBuffer.h>
#include <FontRender/JCFreeTypeRender.h>
#include <FontRender/JCMeasureTextManager.h>
#include <resource/text/JCFontManager.h>
#include "JCCmdDispatchManager.h"
#include <RenderCmd/CmdBase.h>
#include <Node/JCNode2D.h>
#include <Node/JCNode2DRenderer.h>
namespace laya
{
class JCScriptRuntime
{
public:
JCScriptRuntime();
~JCScriptRuntime();
void init(JCFreeTypeFontRender* pFreeTypeRender);
void onThInit();
bool onUpdate();
//每次需要渲染的时候触发js
void onUpdateDraw(double vsyncTime);
void onThExit();
void flushSharedCmdBuffer();
void dispatchScriptCmd();
void setJSCmdBuffer(char* pBuffer);
void setRootNode(JCNode2D* pNode);
private:
void startScriptOnRenderThread();
public:
static JCScriptRuntime* s_JSRT;
JCHtml5Context* m_pRootHtml5Context;
JCNode2D* m_pRootNode;
std::vector<CmdBase*> m_vRenderCmds;
JCCmdDispathManager* m_pCmdDispathManager; //
JCMeasureTextManager* m_pMeasureTextManager; //MeasureTextManager
JCMemClass* m_pJSCmdBuffer; //JS的buffer
char* m_pCmdBufferSharedWithJS; //第一个int是当前指针。
int m_nCmdBufferSharedWithJSLen;
int m_nUpdateCount; //update次数
JCTextManager* m_pTextManager; ///<TextManager
JCFreeTypeFontRender* m_pFreeTypeRender; ///<FreeTypeRender 用于绘制文字
JCFontManager* m_pFontManager; ///<FontManager
int m_nCountGroup; ///<组的个数
int m_nCountVertex; ///<顶点的个数
int m_nCountNode; ///<node的个数
};
}
//------------------------------------------------------------------------------
#endif //__JCScrpitRuntimeWASM_H__
//-----------------------------END FILE--------------------------------
+27
View File
@@ -0,0 +1,27 @@
#include "JCSystemConfig.h"
namespace laya
{
JCSystemConfig g_kSystemConfig;
JCSystemConfig::JCSystemConfig()
{
reset();
}
bool JCSystemConfig::s_bIsPlug = true; //插件是主流。同一进程也不会改变。
bool JCSystemConfig::s_bLocalizable = false;
void JCSystemConfig::reset()
{
m_bPerfStat=false;
m_nFrameType = FT_FAST;
m_nFrameThreshold = 2000;
m_nSleepTime = 0;
m_strStartURL = "";
m_nPerf_UpdateNum=500;
m_jsonparamExt="";
s_bLocalizable = false;
m_bShowInternalPerBar = false;
m_bUseChoreographer = false;
m_bUseAndroidSystemFont = false;
m_nThreadMODE = THREAD_MODE_DOUBLE;
}
}
+40
View File
@@ -0,0 +1,40 @@
#ifndef _LAYA_CONFIG_H__
#define _LAYA_CONFIG_H__
#include <string>
#include <JCWebGLPlus.h>
namespace laya
{
enum FRAME_TYPE
{
FT_SLOW = 0,
FT_FAST,
FT_MOUSE,
};
class JCSystemConfig
{
public:
JCSystemConfig();
void reset();
public:
std::string m_strStartURL;
bool m_bPerfStat; //进行效率统计
FRAME_TYPE m_nFrameType;
double m_nFrameThreshold;
int m_nSleepTime;
int m_nPerf_UpdateNum;
std::string m_strPerfOut;
std::string m_jsonparamExt; //额外参数
bool m_bShowInternalPerBar; //是否显示js ondraw部分和gl的柱状性能图。
bool m_bUseChoreographer; //在android下启用choreographer
static bool s_bIsPlug; //因为初始化太早了,做成static
static bool s_bLocalizable; //设置是否是本地包
bool m_bUseAndroidSystemFont; //是否使用android本身的字体
THREAD_MODE m_nThreadMODE; //线程模式
};
extern JCSystemConfig g_kSystemConfig;
}
#endif
+82
View File
@@ -0,0 +1,82 @@
/**
@file JCThreadCmdMgr.cpp
@brief
@author James
@version 1.0
@date 2017_11_28
*/
#include "JCThreadCmdMgr.h"
#include <misc/JCWorkerThread.h>
namespace laya
{
JCThreadCmdMgr::JCThreadCmdMgr()
{
for (int i = 0; i < NUM; i++)
{
m_Threads[i] = nullptr;
}
m_bStop = false;
}
JCThreadCmdMgr::~JCThreadCmdMgr()
{
stop();
}
void JCThreadCmdMgr::postTo(int tid, const function<void(void)>& f)
{
m_Lock.lock(); //保护下面的post,一旦m_bStop设置了,下面的pTarget就随时可能无效。所以对pTarget的使用都要保护起来。
if (!m_bStop)
{
JCWorkerThread* pTarget = m_Threads[tid];
if (pTarget)
{
pTarget->post(f);
}
}
m_Lock.unlock();
}
void JCThreadCmdMgr::postToJS(const function<void(void)>& f)
{
postTo(JS, f);
}
void JCThreadCmdMgr::postToDownload(const function<void(void)>& f)
{
postTo(DOWNLOADER, f);
}
void JCThreadCmdMgr::postToDecoder(const function<void(void)>& f)
{
postTo(DECODER, f);
}
void JCThreadCmdMgr::regThread(int id, JCWorkerThread* pTh)
{
m_Lock.lock();
m_Threads[id] = pTh;
m_Lock.unlock();
}
void JCThreadCmdMgr::start()
{
m_Lock.lock();
m_bStop = false;
for (int i = 0; i < NUM; i++)
{
m_Threads[i] = nullptr;
}
m_Lock.unlock();
}
void JCThreadCmdMgr::stop()
{
m_Lock.lock();
m_bStop = true;
for (int i = 0; i < NUM; i++)
{
m_Threads[i] = nullptr;
}
m_Lock.unlock();
}
}
//------------------------------------------------------------------------------
//-----------------------------END FILE--------------------------------
+53
View File
@@ -0,0 +1,53 @@
/**
@file JCThreadCmdMgr.h
@brief
@author James
@version 1.0
@date 2017_11_28
*/
#ifndef __JCThreadCmdMgr_H__
#define __JCThreadCmdMgr_H__
#include <functional>
#include <vector>
#include <mutex>
#include <util/JCIThreadCmdMgr.h>
using namespace std;
namespace laya
{
class JCWorkerThread;
class JCThreadCmdMgr:public IConchThreadCmdMgr
{
public:
enum ThreadID
{
JS,
DOWNLOADER,
DECODER,
NUM
};
public:
JCThreadCmdMgr();
~JCThreadCmdMgr();
void postTo(int tid, const function<void(void)>& f);
virtual void postToJS(const function<void(void)>& f);
virtual void postToDownload(const function<void(void)>& f);
virtual void postToDecoder(const function<void(void)>& f);
void regThread(int id, JCWorkerThread* pTh);
void stop();
void start();
public:
JCWorkerThread* m_Threads[NUM];
bool m_bStop;
recursive_mutex m_Lock;
};
}
//------------------------------------------------------------------------------
#endif //__JCThreadCmdMgr_H__
//-----------------------------END FILE--------------------------------
+624
View File
@@ -0,0 +1,624 @@
/**
@file JNIFun.cpp
@brief
@author James
@version 1.0
@date 2016_5_19
*/
#include <jni.h>
#include <android/log.h>
#include <stdio.h>
#include <stdlib.h>
#ifdef ANDROID
#include <sys/syscall.h>
#define gettidv1() syscall(__NR_gettid)
#define gettidv2() syscall(SYS_gettid)
#endif
#include <downloadCache/JCAndroidFileSource.h>
#include <android/asset_manager.h>
#include <android/asset_manager_jni.h>
#include <android/bitmap.h>
#include <downloadMgr/JCDownloadMgr.h>
#include <util/Log.h>
#include "JCConch.h"
//#include "JSWrapper/LayaWrap/JSMarket.h"
#include "CToJavaBridge.h"
#include "Audio/JCAudioManager.h"
#include "JSWrapper/LayaWrap/JSInput.h"
#include "util/JCZipFile.h"
#include "JCSystemConfig.h"
#include "JSWrapper/LayaWrap/JSGlobalExportCFun.h"
#include "JCConchRender.h"
#include "JCScriptRuntime.h"
#include "JSWrapper/LayaWrap/Video/JSVideo.h"
#include <imageLib/JCImageRW.h>
using namespace laya;
extern int g_nInnerWidth;
extern int g_nInnerHeight;
extern bool g_bGLCanvasSizeChanged;
extern std::string gRedistPath;
//------------------------------------------------------------------------------
bool g_bEngineInited = false;
std::mutex g_kReadyLock;
laya::JCConch* g_pConch = NULL;
extern AAssetManager* g_pAssetManager;
extern std::string gAssetRootPath;
extern std::string gAPKExpansionMainPath;
extern std::string gAPKExpansionPatchPath;
bool g_bInBKGround=false;
int64_t g_nInitTime = 0;
//------------------------------------------------------------------------------
extern "C"
{
JNIEXPORT void JNICALL Java_layaair_game_browser_ConchJNI_configSetParamExt(JNIEnv * env, jobject obj,jstring p_strParamExt);//extparam
JNIEXPORT void JNICALL Java_layaair_game_browser_ConchJNI_configSetURL(JNIEnv * env, jobject obj,jstring p_strUrl);
JNIEXPORT void JNICALL Java_layaair_game_browser_ConchJNI_configSetIsPlug(JNIEnv * env, jobject obj, jboolean p_bIsPlug);
JNIEXPORT void JNICALL Java_layaair_game_browser_ConchJNI_InitDLib(JNIEnv * env, jobject obj,jobject assetManager,jint nDownloadThreadNum,jstring p_strAssetRootPath,jstring p_strCachePath, jstring p_strAPKExpansionMainPath, jstring p_strAPKExpansionPatchPath,int threadMode,int debugMode,int debugPort);
JNIEXPORT void JNICALL Java_layaair_game_browser_ConchJNI_SetLocalStoragePath(JNIEnv * env, jobject obj,jstring p_strLocalStorage );
JNIEXPORT void JNICALL Java_layaair_game_browser_ConchJNI_handleTouch(JNIEnv * env, jobject obj,jint type,jint id,jint x,jint y );
JNIEXPORT void JNICALL Java_layaair_game_browser_ConchJNI_handleKeyEvent(JNIEnv * env, jobject obj,jint keyCode,jint actionType);
JNIEXPORT void JNICALL Java_layaair_game_browser_ConchJNI_handleJoystickEvent(JNIEnv * env, jobject obj,float THUMBL_xOffset,float THUMBL_yOffset,float THUMBR_xOffset,float THUMBR_yOffset,float LT_Offset,float RT_Offset);
JNIEXPORT void JNICALL Java_layaair_game_browser_ConchJNI_handleDeviceMotionEvent(JNIEnv * env, jobject obj, float ax, float ay, float az, float agx, float agy, float agz, float ra, float rb, float rg, float interval);
JNIEXPORT void JNICALL Java_layaair_game_browser_ConchJNI_handleDeviceOrientationEvent(JNIEnv * env, jobject obj, float ra, float rb, float rg);
JNIEXPORT void JNICALL Java_layaair_game_browser_ConchJNI_ReleaseDLib(JNIEnv * env, jobject obj );
JNIEXPORT void JNICALL Java_layaair_game_browser_ConchJNI_OnAppDestroy(JNIEnv * env, jobject obj );
JNIEXPORT void JNICALL Java_layaair_game_browser_ConchJNI_OnAppPause(JNIEnv * env, jobject obj );
JNIEXPORT void JNICALL Java_layaair_game_browser_ConchJNI_OnGLReady(JNIEnv * env, jobject obj, int width,int height );
JNIEXPORT void JNICALL Java_layaair_game_browser_ConchJNI_OnAppResume(JNIEnv * env, jobject obj );
JNIEXPORT void JNICALL Java_layaair_game_browser_ConchJNI_onDrawFrame(JNIEnv * env, jobject obj );
JNIEXPORT void JNICALL Java_layaair_game_browser_ConchJNI_onVSyncCallback(JNIEnv * env, jobject obj, jlong vsynctm);
JNIEXPORT void JNICALL Java_layaair_game_browser_ConchJNI_exportStaticMethodToC(JNIEnv * env, jobject obj, jstring packcls);
JNIEXPORT void JNICALL Java_layaair_game_browser_ConchJNI_closeExternalWebView(JNIEnv * env, jobject obj );
JNIEXPORT void JNICALL Java_layaair_game_browser_ConchJNI_alertCallback(JNIEnv * env, jobject obj );
JNIEXPORT void JNICALL Java_layaair_game_browser_ConchJNI_onSensorChanged(JNIEnv * env, jobject obj,float arc );
JNIEXPORT void JNICALL Java_layaair_game_browser_ConchJNI_reloadJS(JNIEnv * env, jobject obj );
JNIEXPORT void JNICALL Java_layaair_game_browser_ConchJNI_onRunCmd(JNIEnv* env, jobject obj, jint cmd, jint nParam1, jint nParam2 );
JNIEXPORT void JNICALL Java_layaair_game_browser_ConchJNI_RunJS(JNIEnv* env, jobject obj, jstring jsstr );
JNIEXPORT void JNICALL Java_layaair_game_browser_ConchJNI_postMsgToRuntime(JNIEnv* env, jobject obj, jstring msg, jstring params);
JNIEXPORT void JNICALL Java_layaair_game_browser_ConchJNI_onBuyPropsCallback( JNIEnv * env, jobject obj,jstring p_sDesc );
JNIEXPORT void JNICALL Java_layaair_game_browser_ConchJNI_onInviteCallback( JNIEnv * env, jobject obj,jstring p_sJsonParam );
JNIEXPORT void JNICALL Java_layaair_game_browser_ConchJNI_exitToPlatform( JNIEnv * env, jobject obj );
JNIEXPORT void JNICALL Java_layaair_game_browser_ConchJNI_audioMusicPlayEnd( JNIEnv * env, jobject obj );
JNIEXPORT void JNICALL Java_layaair_game_browser_ConchJNI_networkChanged(JNIEnv* env, jobject obj, jint nNetworkType );
JNIEXPORT void JNICALL Java_layaair_game_browser_ConchJNI_loginCallback(JNIEnv* env, jobject obj, jstring p_sJsonParam);
JNIEXPORT void JNICALL Java_layaair_game_browser_ConchJNI_authorizeCallback(JNIEnv* env, jobject obj, jstring p_sJsonParam);
JNIEXPORT void JNICALL Java_layaair_game_browser_ConchJNI_refreshTokenCallback(JNIEnv* env, jobject obj, jstring p_sJsonParam);
JNIEXPORT void JNICALL Java_layaair_game_browser_ConchJNI_rechargeEvent(JNIEnv* env, jobject obj, jstring p_sJsonParam );
JNIEXPORT void JNICALL Java_layaair_game_browser_ConchJNI_inputChange(JNIEnv* env, jobject obj, jint keycode );
JNIEXPORT void JNICALL Java_layaair_game_browser_ConchJNI_onShareAndFeed( JNIEnv * env, jobject obj,jstring p_sJsonParam );
JNIEXPORT void JNICALL Java_layaair_game_browser_ConchJNI_onGetGameFriends( JNIEnv * env, jobject obj,jstring p_sJsonParam);
JNIEXPORT void JNICALL Java_layaair_game_browser_ConchJNI_onSendToDesktop( JNIEnv * env, jobject obj,jstring p_sJsonParam);
JNIEXPORT void JNICALL Java_layaair_game_browser_ConchJNI_onLogout( JNIEnv * env, jobject obj,jstring p_sJsonParam);
JNIEXPORT void JNICALL Java_layaair_game_browser_ConchJNI_onMarketInit( JNIEnv * env, jobject obj,jstring p_sJsonParam );
JNIEXPORT void JNICALL Java_layaair_game_browser_ConchJNI_onTopicCircle( JNIEnv * env, jobject obj,jstring p_sJsonParam );
JNIEXPORT void JNICALL Java_layaair_game_browser_ConchJNI_onSwitchUserCallback( JNIEnv * env, jobject obj,jstring p_sJsonParam );
JNIEXPORT void JNICALL Java_layaair_game_browser_ConchJNI_onEnterPlatformCallback( JNIEnv * env, jobject obj,jstring p_sJsonParam );
JNIEXPORT void JNICALL Java_layaair_game_browser_ConchJNI_onEnterBBSCallback( JNIEnv * env, jobject obj,jstring p_sJsonParam );
JNIEXPORT void JNICALL Java_layaair_game_browser_ConchJNI_onEnterFeedbackCallback( JNIEnv * env, jobject obj,jstring p_sJsonParam );
JNIEXPORT void JNICALL Java_layaair_game_browser_ConchJNI_onEnterAccountMgrCallback( JNIEnv * env, jobject obj,jstring p_sJsonParam );
JNIEXPORT void JNICALL Java_layaair_game_browser_ConchJNI_onSetRechargeInfoCallback( JNIEnv * env, jobject obj,jstring p_sJsonParam );
JNIEXPORT void JNICALL Java_layaair_game_browser_ConchJNI_onSendMessageToPlatformCallback( JNIEnv * env, jobject obj,jstring p_sJsonParam );
JNIEXPORT void JNICALL Java_layaair_game_browser_ConchJNI_onGetUserInfoCallback(JNIEnv * env, jobject obj, jstring p_sJsonParam);
JNIEXPORT void JNICALL Java_layaair_game_browser_ConchJNI_onGetAvailableLoginTypeCallback(JNIEnv * env, jobject obj, jstring p_sJsonParam);
JNIEXPORT void JNICALL Java_layaair_game_browser_ConchJNI_setLocalizable(JNIEnv * env, jobject obj, jboolean p_bIsLocalPackage);
JNIEXPORT void JNICALL Java_layaair_game_browser_ConchJNI_callConchJSFunction(JNIEnv* env, jobject obj, jstring sFunctionName,jstring sJsonParam,jstring sCallbackFunction);
JNIEXPORT void JNICALL Java_layaair_game_browser_ConchJNI_captureScreenCallBack(JNIEnv* env, jobject obj, jint w, jint h, jbyteArray byteArray);
JNIEXPORT jboolean JNICALL Java_layaair_game_browser_ConchJNI_onBackPressed(JNIEnv* env, jobject obj);
JNIEXPORT void JNICALL Java_layaair_game_browser_LayaVideoPlayer_emit(JNIEnv* env, jobject obj, jlong ptr, jstring str);
JNIEXPORT void JNICALL Java_layaair_game_browser_LayaVideoPlayer_transferBitmap(JNIEnv* env, jobject obj, jobject bitmap, jlong dataPtr);
};
void postCmdToMainThread(int p_nCmd, int p_nParam1, int p_nParam2)
{
CToJavaBridge::JavaRet ret;
char buffer[60];
sprintf(buffer, "[%d,%d,%d]",p_nCmd,p_nParam1,p_nParam2);
std::string params(buffer);
CToJavaBridge::GetInstance()->callMethod(-1, true, CToJavaBridge::JavaClass.c_str(), "postCmdToMain", params.c_str(), ret);
}
JNIEXPORT void JNICALL Java_layaair_game_browser_ConchJNI_configSetURL(JNIEnv * env, jobject obj,jstring p_strUrl)
{
char* pstrUrl =(char*) env->GetStringUTFChars( p_strUrl, NULL );
g_kSystemConfig.m_strStartURL = pstrUrl;
LOGI("JNI seturl%s", pstrUrl);
env->ReleaseStringUTFChars(p_strUrl, pstrUrl);
}
JNIEXPORT void JNICALL Java_layaair_game_browser_ConchJNI_configSetIsPlug(JNIEnv * env, jobject obj, jboolean p_bIsPlug)
{
JCSystemConfig::s_bIsPlug = p_bIsPlug;
LOGI("JNI setIsPlug%d", p_bIsPlug);
}
JNIEXPORT void JNICALL Java_layaair_game_browser_ConchJNI_configSetParamExt(JNIEnv * env, jobject obj,jstring p_strParamExt)
{
char* pstrParamExt =(char*) env->GetStringUTFChars( p_strParamExt, NULL );
g_kSystemConfig.m_jsonparamExt = pstrParamExt;
LOGI("JNI setParamExt%s", pstrParamExt);
env->ReleaseStringUTFChars(p_strParamExt, pstrParamExt);
}
JNIEXPORT void JNICALL Java_layaair_game_browser_ConchJNI_InitDLib(JNIEnv * env, jobject obj,jobject assetManager,int nThreadNum,jstring p_strAssetRootPath, jstring p_strCachePath , jstring p_strAPKExpansionMainPath, jstring p_strAPKExpansionPatchPath,int threadMode,int debugMode,int debugPort)
{
LOGI("JNI InitDLib");
if(g_pConch)
{
LOGI("JNI has an old conch object! delete it");
//如果上次不正常退出,如果时间太短,可能有的线程还在创建过程中。所以等待一会儿。
//例如g_pConch突然为null,可能有人还在用。
std::this_thread::sleep_for(std::chrono::milliseconds(500));
//必须走完整流程,例如有的线程还在创建,完了后就正常跑,然后这里g_pConch又被删了
Java_layaair_game_browser_ConchJNI_ReleaseDLib(env,obj);
LOGI("JNI del old end");
}
//这个不要放到开始,以影响面上面的异常处理
g_nInitTime=tmGetCurms();
char* pAssetRootPath =(char*) env->GetStringUTFChars( p_strAssetRootPath, NULL );
char* pCachePath = (char*)env->GetStringUTFChars( p_strCachePath, NULL);
char* pAPKExpansionMain =(char*) env->GetStringUTFChars( p_strAPKExpansionMainPath, NULL );
char* pAPKExpansionPatch = (char*)env->GetStringUTFChars( p_strAPKExpansionPatchPath, NULL);
LOGI( "JNI InitDownLoadManager CachePath=%s, assetroot=%s, APKExpansionMain=%s, APKExpansionPatch=%s ", pCachePath, pAssetRootPath, pAPKExpansionMain, pAPKExpansionPatch);
gRedistPath = pCachePath;
gRedistPath +="/";
gAssetRootPath = pAssetRootPath;
gAPKExpansionMainPath= pAPKExpansionMain;
gAPKExpansionPatchPath = pAPKExpansionPatch;
if( assetManager==0 || !(g_pAssetManager = AAssetManager_fromJava(env,assetManager)))
{
LOGI("JNI Warning! AssetManager =NULL!! 下面要采用jar流程了。");
JCZipFile* pZip = new laya::JCZipFile();
if( strstr(pAssetRootPath,".jar" ) ||strstr(pAssetRootPath,".JAR" )||strstr(pAssetRootPath,".zip" )||strstr(pAssetRootPath,".apk")||strstr(pAssetRootPath,".APK") ){
if(pZip->open(pAssetRootPath))
{
LOGI("JNI 打开jar成功。");
pZip->InitDir("assets");
}
JCConch::s_pAssetsFiles = pZip;
}
else
{
LOGI("JNI 没有设置assetMgr,也没有传入jar包。");
}
}
else
{
laya::JCAndroidFileSource* pAssets = new laya::JCAndroidFileSource();
pAssets->Init(g_pAssetManager, "","", "", "");
JCConch::s_pAssetsFiles = pAssets;
}
env->ReleaseStringUTFChars(p_strAssetRootPath, pAssetRootPath);
env->ReleaseStringUTFChars(p_strCachePath, pCachePath);
env->ReleaseStringUTFChars(p_strAPKExpansionMainPath, pAPKExpansionMain);
env->ReleaseStringUTFChars(p_strAPKExpansionPatchPath, pAPKExpansionPatch);
THREAD_MODE nMode = (THREAD_MODE)(threadMode);
if (nMode == THREAD_MODE_SINGLE)
{
g_kSystemConfig.m_nThreadMODE = nMode;
LOGI(">>>>>>Thread Mode = single");
}
else if (nMode == THREAD_MODE_DOUBLE)
{
g_kSystemConfig.m_nThreadMODE = nMode;
LOGI(">>>>>>Thread Mode = double");
}
else
{
LOGI(">>>>>>Thread Mode = %d", g_kSystemConfig.m_nThreadMODE);
}
g_pConch = new laya::JCConch(nThreadNum,(laya::JS_DEBUG_MODE)debugMode,debugPort);
g_pConch->m_funcPostMsgToMainThread = std::bind(postCmdToMainThread, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
}
JNIEXPORT void JNICALL Java_layaair_game_browser_ConchJNI_SetLocalStoragePath(JNIEnv * env, jobject obj,jstring p_strLocalStorage )
{
char* pLocalStoragePath =(char*) env->GetStringUTFChars( p_strLocalStorage, NULL );
LOGI( "JNI localStoragePath=%s", pLocalStoragePath);
env->ReleaseStringUTFChars(p_strLocalStorage, pLocalStoragePath);
}
JNIEXPORT void JNICALL Java_layaair_game_browser_ConchJNI_handleTouch( JNIEnv * env, jobject obj,jint type,jint id,jint x,jint y )
{
enum java_motion_Action
{
ACTION_DOWN=0,
ACTION_UP=1,
ACTION_MOVE=2,
ACTION_POINTER_DOWN=5,
ACTION_POINTER_UP=6,
};
switch(type)
{
case java_motion_Action::ACTION_DOWN:
{
inputEvent e;
e.nType =E_ONTOUCHSTART;
e.nTouchType = type;
e.posX = x;
e.posY = y;
e.id = id;
strncpy(e.type, "touchstart", 256 );
JCScriptRuntime::s_JSRT->dispatchInputEvent(e);
break;
}
case java_motion_Action::ACTION_UP:
{
inputEvent e;
e.nType = E_ONTOUCHEND;
e.nTouchType = type;
e.posX = x;
e.posY = y;
e.id = id;
strncpy(e.type, "touchend", 256 );
JCScriptRuntime::s_JSRT->dispatchInputEvent(e);
break;
}
case java_motion_Action::ACTION_MOVE:
{
inputEvent e;
e.nType = E_ONTOUCHMOVE;
e.nTouchType = type;
e.posX = x;
e.posY = y;
e.id = id;
strncpy(e.type, "touchmove", 256);
JCScriptRuntime::s_JSRT->dispatchInputEvent(e);
break;
}
case java_motion_Action::ACTION_POINTER_DOWN:
{
inputEvent e;
e.nType = E_ONACTION_POINTER_DOWN;
e.nTouchType = type;
e.posX = x;
e.posY = y;
e.id = id;
strncpy(e.type, "touchstart", 256 );
JCScriptRuntime::s_JSRT->dispatchInputEvent(e);
break;
}
case java_motion_Action::ACTION_POINTER_UP:
{
inputEvent e;
e.nType = E_ONACTION_POINTER_UP;
e.nTouchType = type;
e.posX = x;
e.posY = y;
e.id = id;
strncpy(e.type, "touchend", 256 );
JCScriptRuntime::s_JSRT->dispatchInputEvent(e);
break;
}
}
}
JNIEXPORT void JNICALL Java_layaair_game_browser_ConchJNI_handleKeyEvent(JNIEnv * env, jobject obj,jint keyCode,jint actionType)
{
enum android_key_Code
{
KEYCODE_BACK = 4,
KEYCODE_DPAD_UP = 19,
KEYCODE_DPAD_DOWN = 20,
KEYCODE_DPAD_LEFT = 21,
KEYCODE_DPAD_RIGHT = 22,
KEYCODE_DPAD_CENTER = 23,
KEYCODE_VOLUME_UP = 24,
KEYCODE_VOLUME_DOWN = 25,
KEYCODE_ENTER = 66,
KEYCODE_MENU = 82,
KEYCODE_BUTTON_A = 96,
KEYCODE_BUTTON_B = 97,
KEYCODE_BUTTON_X = 99,
KEYCODE_BUTTON_Y = 100,
KEYCODE_BUTTON_L1 = 102,
KEYCODE_BUTTON_R1 = 103,
KEYCODE_BUTTON_L2 = 104,
KEYCODE_BUTTON_R2 = 105,
KEYCODE_BUTTON_THUMBL = 106,
KEYCODE_BUTTON_THUMBR = 107,
KEYCODE_BUTTON_START = 108,
KEYCODE_BUTTON_SELECT = 109,
};
enum android_key_Action
{
ACTION_DOWN = 0,
ACTION_UP = 1,
};
if(actionType == android_key_Action::ACTION_DOWN)
{
inputEvent e;
e.nType = E_ONKEYDOWN;
e.keyCode = keyCode;
strncpy(e.type, "keydown", 256 );
JCScriptRuntime::s_JSRT->dispatchInputEvent(e);
}
else if(actionType == android_key_Action::ACTION_UP)
{
inputEvent e;
e.nType =E_ONKEYUP;
e.keyCode = keyCode;
strncpy(e.type, "keyup", 256 );
JCScriptRuntime::s_JSRT->dispatchInputEvent(e);
}
}
JNIEXPORT void JNICALL Java_layaair_game_browser_ConchJNI_handleJoystickEvent( JNIEnv * env, jobject obj,float THUMBL_xOffset,float THUMBL_yOffset,float THUMBR_xOffset,float THUMBR_yOffset,float LT_Offset,float RT_Offset )
{
inputEvent e;
e.nType = E_JOYSTICK;
e.fTHUMBL_xOffset = THUMBL_xOffset;
e.fTHUMBL_yOffset = THUMBL_yOffset;
e.fTHUMBR_xOffset = THUMBR_xOffset;
e.fTHUMBR_yOffset = THUMBR_yOffset;
e.fLT_Offset = LT_Offset;
e.fRT_Offset = RT_Offset;
strncpy(e.type, "onjoystick", 256 );
JCScriptRuntime::s_JSRT->dispatchInputEvent(e);
}
JNIEXPORT void JNICALL Java_layaair_game_browser_ConchJNI_handleDeviceMotionEvent(JNIEnv * env, jobject obj, float ax, float ay, float az, float agx, float agy, float agz, float ra, float rb, float rg, float interval)
{
DeviceMotionEvent e;
e.nType = E_DEVICEMOTION;
e.ax = ax;
e.ay = ay;
e.az = az;
e.agx = agx;
e.agy = agy;
e.agz = agz;
e.ra = ra;
e.rb = rb;
e.rg = rg;
e.interval = interval;
strncpy(e.type, "devicemotion", 256);
JCScriptRuntime::s_JSRT->dispatchInputEvent(e);
}
JNIEXPORT void JNICALL Java_layaair_game_browser_ConchJNI_handleDeviceOrientationEvent(JNIEnv * env, jobject obj, float ra, float rb, float rg)
{
DeviceOrientationEvent e;
e.nType = E_DEVICEORIENTATION;
e.ra = ra;
e.rb = rb;
e.rg = rg;
strncpy(e.type, "deviceorientation", 256);
JCScriptRuntime::s_JSRT->dispatchInputEvent(e);
}
JNIEXPORT void JNICALL Java_layaair_game_browser_ConchJNI_ReleaseDLib(JNIEnv * env, jobject obj )
{
LOGI("JNI del engine");
JCAudioManager::GetInstance()->stopMp3();
if(g_pConch)
{
if(tmGetCurms()- g_nInitTime<2000)
{
LOGI("JNI exit need a little wait");
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
}
if (g_bInBKGround)
{
LOGI("JNI App in background!");
JCConch::s_pConchRender->willExit();
}
g_pConch->onAppDestory();
if (g_kSystemConfig.m_nThreadMODE==THREAD_MODE_SINGLE)
{
JCScriptRuntime::s_JSRT->stop();
}
delete g_pConch;
g_pConch=NULL;
}
g_bEngineInited = false;
}
JNIEXPORT void JNICALL Java_layaair_game_browser_ConchJNI_OnAppDestroy(JNIEnv * env, jobject obj )
{
}
JNIEXPORT void JNICALL Java_layaair_game_browser_ConchJNI_OnAppPause(JNIEnv * env, jobject obj )
{
LOGI("JNI OnAppPause");
g_bInBKGround = true;
if( laya::JCAudioManager::GetInstance()->getMp3Mute() == false && laya::JCAudioManager::GetInstance()->getMp3Stopped() == false)
{
JCAudioManager::GetInstance()->pauseMp3();
}
laya::JCAudioManager::GetInstance()->m_pWavPlayer->pause();
}
JNIEXPORT void JNICALL Java_layaair_game_browser_ConchJNI_OnAppResume(JNIEnv * env, jobject obj )
{
LOGI("JNI OnAppResume");
if (!g_pConch)
return;
g_bInBKGround=false;
//继续声音
if( laya::JCAudioManager::GetInstance()->getMp3Mute() == false && laya::JCAudioManager::GetInstance()->getMp3Stopped() == false)
{
laya::JCAudioManager::GetInstance()->resumeMp3();
}
laya::JCAudioManager::GetInstance()->m_pWavPlayer->resume();
}
JNIEXPORT void JNICALL Java_layaair_game_browser_ConchJNI_OnGLReady(JNIEnv * env, jobject obj, int width,int height )
{
LOGI("JNI onGLReady tid=%ld", gettidv1());
auto pRender = JCConch::s_pConchRender;
if( g_nInnerWidth!=width || g_nInnerHeight != height )
{
LOGI("JNI surface innersize changed : g_nInnerWidth=%d,g_nInnerHeight=%d",width,height);
g_nInnerWidth = width;
g_nInnerHeight = height;
g_bGLCanvasSizeChanged=true;
}
LOGI("JNI init dev w=%d,h=%d",width,height);
//pRender->onGLDeviceLosted();
pRender->onGLReady();
g_kReadyLock.lock();
if( !g_bEngineInited )
{
//启动js线程
g_pConch->onAppStart();
g_bEngineInited = true;
if (g_kSystemConfig.m_nThreadMODE==THREAD_MODE_SINGLE)
{
JCScriptRuntime::s_JSRT->start(JCConch::s_pConch->m_strStartJS.c_str());
}
}
g_kReadyLock.unlock();
}
JNIEXPORT void JNICALL Java_layaair_game_browser_ConchJNI_onDrawFrame(JNIEnv * env, jobject obj )
{
auto pRender = JCConch::s_pConchRender;
if (pRender)
{
pRender->renderFrame(0,false);
}
}
JNIEXPORT void JNICALL Java_layaair_game_browser_ConchJNI_onVSyncCallback(JNIEnv * env, jobject obj, jlong VSynctm) {
double vsynctm = VSynctm / 1e6;
//auto ctm = laya::tmGetCurms();
//LOGE("---TM:%f,d=%f,cur=%f,d=%f", (float)vsynctm, (float)(vsynctm - lastVSYNC1) , ctm,(ctm-vsynctm));
if (JCScriptRuntime::s_JSRT) {
JCScriptRuntime::s_JSRT->onVSyncEvent(vsynctm);
}
}
JNIEXPORT void JNICALL Java_layaair_game_browser_ConchJNI_closeExternalWebView(JNIEnv * env, jobject obj )
{
}
JNIEXPORT void JNICALL Java_layaair_game_browser_ConchJNI_alertCallback(JNIEnv * env, jobject obj )
{
}
JNIEXPORT void JNICALL Java_layaair_game_browser_ConchJNI_exportStaticMethodToC(JNIEnv * env, jobject obj, jstring packcls)
{
const char* rawPackCls = env->GetStringUTFChars(packcls, NULL);
CToJavaBridge::GetInstance()->addStaticMethod(env,rawPackCls);
env->ReleaseStringUTFChars(packcls, rawPackCls);
}
JNIEXPORT void JNICALL Java_layaair_game_browser_ConchJNI_onSensorChanged(JNIEnv * env, jobject obj,float arc )
{
}
JNIEXPORT void JNICALL Java_layaair_game_browser_ConchJNI_reloadJS(JNIEnv * env, jobject obj )
{
}
JNIEXPORT void JNICALL Java_layaair_game_browser_ConchJNI_onRunCmd(JNIEnv* env, jobject obj, jint cmd, jint nParam1, jint nParam2 )
{
if(g_pConch )
{
g_pConch->onRunCmdInMainThread( cmd, nParam1, nParam2 );
}
}
JNIEXPORT void JNICALL Java_layaair_game_browser_ConchJNI_RunJS(JNIEnv* env, jobject obj, jstring jsstr )
{
if (g_pConch && JCScriptRuntime::s_JSRT && jsstr)
{
const char* rawString = env->GetStringUTFChars(jsstr, NULL);
JCScriptRuntime::s_JSRT->callJSString(rawString);
env->ReleaseStringUTFChars(jsstr, rawString);
}
}
JNIEXPORT void JNICALL Java_layaair_game_browser_ConchJNI_postMsgToRuntime(JNIEnv* env, jobject obj, jstring msg, jstring params)
{
const char* rawMsg = env->GetStringUTFChars(msg, NULL);
const char* rawParams = env->GetStringUTFChars(params, NULL);
env->ReleaseStringUTFChars(msg, rawMsg);
env->ReleaseStringUTFChars(params, rawParams);
}
JNIEXPORT void JNICALL Java_layaair_game_browser_ConchJNI_exitToPlatform( JNIEnv * env, jobject obj )
{
}
JNIEXPORT void JNICALL Java_layaair_game_browser_ConchJNI_audioMusicPlayEnd( JNIEnv * env, jobject obj )
{
laya::JCMp3Interface* pMp3Player = laya::JCAudioManager::GetInstance()->m_pMp3Player;
if( pMp3Player )
{
pMp3Player->onPlayEnd();
}
}
JNIEXPORT void JNICALL Java_layaair_game_browser_ConchJNI_networkChanged(JNIEnv* env, jobject obj, jint nNetworkType )
{
JCScriptRuntime::s_JSRT->onNetworkChanged(nNetworkType);
}
JNIEXPORT void JNICALL Java_layaair_game_browser_ConchJNI_inputChange(JNIEnv* env, jobject obj, jint keycode)
{
if (JCScriptRuntime::s_JSRT->m_pCurEditBox)
{
JCScriptRuntime::s_JSRT->m_pCurEditBox->onInput();
}
}
JNIEXPORT void JNICALL Java_layaair_game_browser_ConchJNI_setLocalizable(JNIEnv * env, jobject obj, jboolean p_bIsLocalPackage)
{
JCSystemConfig::s_bLocalizable = p_bIsLocalPackage;
LOGI("setLocalizable%d", p_bIsLocalPackage);
}
JNIEXPORT void JNICALL Java_layaair_game_browser_ConchJNI_callConchJSFunction(JNIEnv* env, jobject obj, jstring p_sFunctionName,jstring p_sJsonParam,jstring p_sCallbackFunction)
{
const char* sFunctionName = env->GetStringUTFChars(p_sFunctionName, NULL);
const char* sJsonParam = env->GetStringUTFChars(p_sJsonParam, NULL);
const char* sCallbackFunction = env->GetStringUTFChars(p_sCallbackFunction, NULL);
LOGI(">>>>>>>>Java_layaair_game_browser_ConchJNI_callConchJSFunction functionName=%s, jsonParam=%s, callbackFuncton=%s",sFunctionName, sJsonParam,sCallbackFunction );
JCScriptRuntime::s_JSRT->callJC( sFunctionName,sJsonParam,sCallbackFunction );
env->ReleaseStringUTFChars(p_sFunctionName, sFunctionName);
env->ReleaseStringUTFChars(p_sJsonParam, sJsonParam);
env->ReleaseStringUTFChars(p_sCallbackFunction, sCallbackFunction);
}
//------------------------------------------------------------------------------
JNIEXPORT void JNICALL Java_layaair_game_browser_ConchJNI_captureScreenCallBack(JNIEnv* env, jobject obj, jint w, jint h, jbyteArray byteArray) {
jint len = env->GetArrayLength(byteArray);
jbyte* ba = env->GetByteArrayElements(byteArray, JNI_FALSE);
char* result = new char[len];
memcpy(result, ba, len);
JSInput::getInstance()->captureScreenCallBack(result,len, w, h);
env->ReleaseByteArrayElements(byteArray, ba, 0);
}
//------------------------------------------------------------------------------
JNIEXPORT jboolean JNICALL Java_layaair_game_browser_ConchJNI_onBackPressed(JNIEnv* env, jobject obj)
{
LOGI(">>>>>>>>Java_layaair_game_browser_ConchJNI_onBackPressed");
bool ret = JCScriptRuntime::s_JSRT->onBackPressed();
return jboolean(ret);
}
JNIEXPORT void JNICALL Java_layaair_game_browser_LayaVideoPlayer_emit(JNIEnv* env, jobject obj, jlong ptr, jstring str)
{
JSVideo* pVideo = reinterpret_cast<JSVideo*>(ptr);
if(!pVideo)
return;
const char* evtName = env->GetStringUTFChars(str, NULL);
// LOGI("[DEBUG][Video]Call emit function %s", evtName);
pVideo->CallHandle(evtName);
env->ReleaseStringUTFChars(str, evtName);
}
JNIEXPORT void JNICALL Java_layaair_game_browser_LayaVideoPlayer_transferBitmap(JNIEnv* env, jobject obj, jobject bitmap, jlong dataPtr)
{
AndroidBitmapInfo bmpInfo={0};
if(AndroidBitmap_getInfo(env, bitmap, &bmpInfo) < 0)
{
// LOGE("[Debug][Video]bitmap: Error getInfo");
return;
}
char** dataFromBmp=NULL;
if(AndroidBitmap_lockPixels(env,bitmap,(void**)&dataFromBmp))
{
// LOGE("[Debug][Video]bitmap: Error lockPixels ");
return;
}
// LOGI("[Debug][Video]Call native transferBitmap %ld", dataPtr);
BitmapData* pBitmapData = reinterpret_cast<BitmapData*>(dataPtr);
if(!pBitmapData)
{
// LOGE("[Debug][Video]Error pBitmapData");
AndroidBitmap_unlockPixels(env,bitmap);
return;
}
pBitmapData->reconfigure(bmpInfo.width, bmpInfo.height, 32, ImgType_unknow);
memcpy(pBitmapData->m_pImageData, dataFromBmp, sizeof(int32_t) * pBitmapData->m_nWidth * pBitmapData->m_nHeight);
AndroidBitmap_unlockPixels(env,bitmap);
}
//-----------------------------END FILE--------------------------------
@@ -0,0 +1,141 @@
#ifdef JS_JSC
#include "JSCArrayBuffer.h"
#include <JavaScriptCore/JSTypedArray.h>
#include "JSCProxyTLS.h"
#include "util/Log.h"
#include <vector>
#include "JSCProxyType.h"
namespace laya {
//TODO 这里没有考虑多线程的问题,如果js要支持多线程的话,需要修改。
struct JsStrBuff {
char* _buff;
int _len;
static std::vector<JsStrBuff> jsstrbuffs;
static int curIdx;
JsStrBuff() {
_buff = NULL;
_len = 0;
}
static JsStrBuff& getAData() {
if (JsStrBuff::curIdx >= JsStrBuff::jsstrbuffs.size()) {
JsStrBuff::jsstrbuffs.push_back(JsStrBuff());
JsStrBuff::curIdx++;
return JsStrBuff::jsstrbuffs.back();
}
else {
return JsStrBuff::jsstrbuffs[JsStrBuff::curIdx++];
}
}
};
std::vector<JsStrBuff> JsStrBuff::jsstrbuffs;
int JsStrBuff::curIdx = 0;
void resetJsStrBuf() {
JsStrBuff::curIdx = 0;
}
char* JsCharToC(JSStringRef str) {
int len = 0;
if (str == nullptr)
return nullptr;//return "";
len = JSStringGetMaximumUTF8CStringSize(str);
if (len <= 0)
return nullptr;//return "";
JsStrBuff& curdata = JsStrBuff::getAData();
char*& tocharBuf = curdata._buff;
int& tocharBufLen = curdata._len;
//tocharBuf= new char[len + 1];
if (len > tocharBufLen) {
tocharBufLen = len;
if (tocharBuf != NULL)
delete[] tocharBuf;
tocharBuf = new char[len+1];
}
else {
//如果占用空间太大,也要重新分配
if (tocharBufLen > 1024 ) {
tocharBufLen = len;
if (tocharBuf != NULL)
delete[] tocharBuf;
tocharBuf = new char[len+1];
}
}
JSStringGetUTF8CString(str,tocharBuf,len);
return tocharBuf;
}
char* JsCharToC(JSValueRef p_vl) {
JSContextRef ctx = __TlsData::GetInstance()->GetCurContext();
JSStringRef str = JSValueToStringCopy(ctx, p_vl, nullptr);
if (str == nullptr)
return nullptr;//return "";
char* ret = JsCharToC(str);
JSStringRelease(str);
return ret;
}
}
namespace laya{
static void deallocator(void* bytes, void* deallocatorContext)
{
if (bytes){
delete (char*)bytes;
}
}
JSValueRef createJSAB(char* pData, int len)
{
JSContextRef ctx = __TlsData::GetInstance()->GetCurContext();
char* pBuffer = new char[len];
memcpy(pBuffer, pData, len);
return JSObjectMakeArrayBufferWithBytesNoCopy(ctx, pBuffer, len, deallocator, pBuffer, NULL);
}
JSValueRef createJSABAligned(char* pData, int len)
{
int asz = (len+3) & 0xfffffffc;
JSContextRef ctx = __TlsData::GetInstance()->GetCurContext();
char* pBuffer = new char[asz];
memcpy(pBuffer, pData, len);
for( int i = len; i < asz; i++ )
{
pBuffer[i] = 0;
}
return JSObjectMakeArrayBufferWithBytesNoCopy(ctx, pBuffer, asz, deallocator, pBuffer, NULL);
}
bool extractJSAB(JSValueRef ab, char*& data, int& len)
{
JSContextRef ctx = __TlsData::GetInstance()->GetCurContext();
JSObjectRef arrayObj = JSValueToObject(ctx,ab,NULL);
JSTypedArrayType arrayType = JSValueGetTypedArrayType(ctx, ab, NULL);
switch(arrayType)
{
case kJSTypedArrayTypeNone:
{
data = NULL;
len = 0;
return false;
}
break;
case kJSTypedArrayTypeArrayBuffer:
{
data = (char*)JSObjectGetArrayBufferBytesPtr(ctx, arrayObj, NULL);
len = (int)JSObjectGetArrayBufferByteLength(ctx, arrayObj, NULL);
return true;
}
break;
default:
{
data = (char*)JSObjectGetTypedArrayBytesPtr(ctx, arrayObj, NULL) + JSObjectGetTypedArrayByteOffset(ctx, arrayObj, NULL);
len = (int)JSObjectGetTypedArrayByteLength(ctx, arrayObj, NULL);
return true;
}
break;
}
}
}
#endif
@@ -0,0 +1,16 @@
#ifndef _JSC_ARRAYBUFFER_H_
#define _JSC_ARRAYBUFFER_H_
#include <memory>
#include <JavaScriptCore/JSValueRef.h>
namespace laya{
JSValueRef createJSAB(char* pData, int len);
JSValueRef createJSABAligned(char* pData, int len);
bool extractJSAB(JSValueRef ab, char*& data, int& len);
}
#endif
@@ -0,0 +1,44 @@
#ifdef JS_JSC
#include "JSCBinder.h"
pthread_key_t JSClassMgr::s_tls_curThread;
JSObjBaseJSC::JSObjBaseJSC() {
m_bWeakThis = true;
}
JSObjBaseJSC::~JSObjBaseJSC() {
if (!m_bWeakThis){
JSContextRef ctx = __TlsData::GetInstance()->GetCurContext();
JSValueUnprotect(ctx, mpJsThis);
}
}
void JSObjBaseJSC::retainThis() {
JSContextRef ctx = __TlsData::GetInstance()->GetCurContext();
JSValueProtect(ctx, mpJsThis);
}
void JSObjBaseJSC::releaseThis() {
JSContextRef ctx = __TlsData::GetInstance()->GetCurContext();
JSValueUnprotect(ctx, mpJsThis);
}
void JSObjBaseJSC::createJSObj(){
JSContextRef ctx = __TlsData::GetInstance()->GetCurContext();
mpJsThis = JSObjectMake(ctx,nullptr,nullptr);
JSValueProtect(ctx, mpJsThis);
m_bWeakThis = false;
}
JSValueRef JSObjBaseJSC::callJsFunc(JSValueRef func) {
return _callJsFunc(func, 0, nullptr);
}
bool JsObjHandleJSC::Empty() {
if (!m_pObj)
return true;
return m_pValue == nullptr;
}
#endif
@@ -0,0 +1,373 @@
#ifndef _JSC_BINDER_H__
#define _JSC_BINDER_H__
#include <JavaScriptCore/JSObjectRef.h>
#include "JSCProxyTransfer.h"
#include "JSCProxyType.h"
#include "JSCProxyClass.h"
#include <pthread.h>
using namespace laya;
class JSClassMgr{
public:
static pthread_key_t s_tls_curThread;
typedef void (*RESETFUNC)();
static JSClassMgr* GetThreadInstance(){
JSClassMgr* pIns =(JSClassMgr*)pthread_getspecific(s_tls_curThread);
if(!pIns){
pIns = new JSClassMgr();
pthread_setspecific(s_tls_curThread,(void*)pIns);
}
return pIns;
}
std::vector<RESETFUNC> allCls;
void resetAllRegClass(){
for( int i=0,sz=allCls.size(); i<sz; i++){
allCls[i]();
}
allCls.clear();
}
};
#define JSP_GLOBAL_START1()
#define JSP_ADD_GLOBAL_FUNCTION(name, func, ...) \
JSCGlobal::getInstance()->addFunction( #name, func );
#define JSP_ADD_GLOBAL_PROPERTY(name, v) \
JSCGlobal::getInstance()->addProperty( #name, v );
#define JSP_CLASS(name, cls) \
JSCClass<cls>* pJSCClass = JSCClass<cls>::getInstance();
#define JSP_GLOBAL_CLASS(name, cls) \
JSCClass<cls>* pJSCClass = JSCClass<cls>::getInstance();
#define JSP_ADD_FIXED_PROPERTY(name,cls,val) \
pJSCClass->addFixedProperty(#name,val)
#define JSP_ADD_METHOD(name,fn) \
pJSCClass->addMethod(name,&fn);
#define JSP_ADD_PROPERTY_RO(name,cls,getter) \
pJSCClass->addProperty(#name,&cls::getter,nullptr);
#define JSP_ADD_PROPERTY(name,cls,getter,setter) \
pJSCClass->addProperty(#name,&cls::getter,&cls::setter);
#define JSP_REG_CONSTRUCTOR(cls,...) \
pJSCClass->addConstructor(laya::regConstructor<cls,##__VA_ARGS__>());
#define JSP_INSTALL_CLASS(name,cls) \
pJSCClass->finish(name); \
JSClassMgr::GetThreadInstance()->allCls.push_back(JSCClass<cls>::reset);
#define JSP_INSTALL_GLOBAL_CLASS(name,cls,inst) \
pJSCClass->finishToGlobal(name,inst); \
JSClassMgr::GetThreadInstance()->allCls.push_back(JSCClass<cls>::reset);
class JSObjBaseJSC {
friend class JsObjHandleJSC;
public:
JSObjBaseJSC();
virtual ~JSObjBaseJSC();
void retainThis();
void releaseThis();
void createJSObj();
bool IsMyJsEnv() {
return true;
}
inline JSValueRef _callJsFunc(JSValueRef func, size_t argumentCount, const JSValueRef arguments[]) {
JSContextRef ctx = __TlsData::GetInstance()->GetCurContext();
JSValueRef exception = nullptr;
JSObjectRef funcObj = JSValueToObject(ctx,func,&exception);
if (exception != nullptr){
__JSRun::OutputException(exception);
}
JSValueRef ret = JSObjectCallAsFunction(ctx,funcObj,mpJsThis,argumentCount,arguments,&exception);
if (exception != nullptr){
__JSRun::OutputException(exception);
}
return ret;
}
JSValueRef callJsFunc(JSValueRef func);
template<class P1>
JSValueRef callJsFunc(JSValueRef func, P1 p1) {
int argc = 1;
JSValueRef argv[1];
argv[0] = __TransferToJs<P1>::ToJs(p1);
return _callJsFunc(func, argc, argv);
}
template<class P1, class P2>
JSValueRef callJsFunc(JSValueRef func, P1 p1, P2 p2) {
int argc = 2;
JSValueRef argv[2];
argv[0] = __TransferToJs<P1>::ToJs(p1);
argv[1] = __TransferToJs<P2>::ToJs(p2);
return _callJsFunc(func, argc, argv);
}
template<class P1, class P2, class P3>
JSValueRef callJsFunc(JSValueRef func, P1 p1, P2 p2, P3 p3) {
int argc = 3;
JSValueRef argv[3];
argv[0] = __TransferToJs<P1>::ToJs(p1);
argv[1] = __TransferToJs<P2>::ToJs(p2);
argv[2] = __TransferToJs<P3>::ToJs(p3);
return _callJsFunc(func, argc, argv);
}
template<class P1, class P2, class P3, class P4>
JSValueRef callJsFunc(JSValueRef func, P1 p1, P2 p2, P3 p3, P4 p4) {
int argc = 4;
JSValueRef argv[4];
argv[0] = __TransferToJs<P1>::ToJs(p1);
argv[1] = __TransferToJs<P2>::ToJs(p2);
argv[2] = __TransferToJs<P3>::ToJs(p3);
argv[3] = __TransferToJs<P4>::ToJs(p4);
return _callJsFunc(func, argc, argv);
}
template<class P1, class P2, class P3, class P4, class P5>
JSValueRef callJsFunc(JSValueRef func, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) {
int argc = 5;
JSValueRef argv[5];
argv[0] = __TransferToJs<P1>::ToJs(p1);
argv[1] = __TransferToJs<P2>::ToJs(p2);
argv[2] = __TransferToJs<P3>::ToJs(p3);
argv[3] = __TransferToJs<P4>::ToJs(p4);
argv[4] = __TransferToJs<P5>::ToJs(p5);
return _callJsFunc(func, argc, argv);
}
template<class P1, class P2, class P3, class P4, class P5, class P6>
JSValueRef callJsFunc(JSValueRef func, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) {
int argc = 6;
JSValueRef argv[6];
argv[0] = __TransferToJs<P1>::ToJs(p1);
argv[1] = __TransferToJs<P2>::ToJs(p2);
argv[2] = __TransferToJs<P3>::ToJs(p3);
argv[3] = __TransferToJs<P4>::ToJs(p4);
argv[4] = __TransferToJs<P5>::ToJs(p5);
argv[5] = __TransferToJs<P6>::ToJs(p6);
return _callJsFunc(func, argc, argv);
}
template<class P1, class P2, class P3, class P4, class P5, class P6, class P7>
JSValueRef callJsFunc(JSValueRef func, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7) {
int argc = 7;
JSValueRef argv[7];
argv[0] = __TransferToJs<P1>::ToJs(p1);
argv[1] = __TransferToJs<P2>::ToJs(p2);
argv[2] = __TransferToJs<P3>::ToJs(p3);
argv[3] = __TransferToJs<P4>::ToJs(p4);
argv[4] = __TransferToJs<P5>::ToJs(p5);
argv[5] = __TransferToJs<P6>::ToJs(p6);
argv[6] = __TransferToJs<P7>::ToJs(p7);
return _callJsFunc(func, argc, argv);
}
template<class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8>
JSValueRef callJsFunc(JSValueRef func, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8) {
int argc = 8;
JSValueRef argv[8];
argv[0] = __TransferToJs<P1>::ToJs(p1);
argv[1] = __TransferToJs<P2>::ToJs(p2);
argv[2] = __TransferToJs<P3>::ToJs(p3);
argv[3] = __TransferToJs<P4>::ToJs(p4);
argv[4] = __TransferToJs<P5>::ToJs(p5);
argv[5] = __TransferToJs<P6>::ToJs(p6);
argv[6] = __TransferToJs<P7>::ToJs(p7);
argv[7] = __TransferToJs<P8>::ToJs(p8);
return _callJsFunc(func, argc, argv);
}
template<class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class P9, class P10, class P11, class P12>
JSValueRef callJsFunc(JSValueRef func, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9, P10 p10, P11 p11, P12 p12) {
int argc = 12;
JSValueRef argv[12];
argv[0] = __TransferToJs<P1>::ToJs(p1);
argv[1] = __TransferToJs<P2>::ToJs(p2);
argv[2] = __TransferToJs<P3>::ToJs(p3);
argv[3] = __TransferToJs<P4>::ToJs(p4);
argv[4] = __TransferToJs<P5>::ToJs(p5);
argv[5] = __TransferToJs<P6>::ToJs(p6);
argv[6] = __TransferToJs<P7>::ToJs(p7);
argv[7] = __TransferToJs<P8>::ToJs(p8);
argv[8] = __TransferToJs<P8>::ToJs(p9);
argv[9] = __TransferToJs<P8>::ToJs(p10);
argv[10] = __TransferToJs<P8>::ToJs(p11);
argv[11] = __TransferToJs<P8>::ToJs(p12);
return _callJsFunc(func, argc, argv);
}
public:
JSObjectRef mpJsThis;
bool m_bWeakThis;
};
class JsObjHandleJSC
{
public:
JsObjHandleJSC() {
m_pObj = nullptr;
m_pValue = nullptr;
m_pReturn = nullptr;
}
~JsObjHandleJSC(){
JSContextRef ctx = __TlsData::GetInstance()->GetCurContext();
if (m_pValue != nullptr && ctx != nullptr)
{
JSValueUnprotect(ctx, m_pValue);
}
}
JSObjBaseJSC* m_pObj;
JSValueRef m_pValue;
JSValueRef m_pReturn;
bool Empty();
JSValueRef getJsObj() {
return m_pValue;
}
void set(int id, JSObjBaseJSC* pobj, JSValueRef v) {
if (m_pValue != nullptr){
Reset();
}
m_pValue = v;
JSValueProtect(__TlsData::GetInstance()->GetCurContext(), m_pValue);
m_pObj = pobj;
}
template <typename _Tp>
static bool IsTypeof(JSValueRef val) {
if (val == nullptr)
return false;
JSContextRef ctx = __TlsData::GetInstance()->GetCurContext();
__InferType<_Tp> _it;
switch (_it.iType) {
case __VT_void:
return false;
case __VT_string:
return JSValueIsString(ctx, val);
case __VT_bool:
return JSValueIsBoolean(ctx, val);
case __VT_int:
case __VT_long:
case __VT_float:
case __VT_double:
case __VT_longlong:
return JSValueIsNumber(ctx,val);
default: {
return __CheckClassType::IsTypeOf<_Tp>(val);
}
}
}
template <typename _Tp>
bool IsTypeof() {
return IsTypeof<_Tp>(m_pValue);
}
template <typename _R>
static bool tryGet(JSValueRef val, _R **pRet) {
if (val == nullptr) {
*pRet = 0;
return false;
}
if (!__TransferToCpp<_R>::is(val))
return false;
*pRet = __TransferToCpp<_R*>::ToCpp(val);
return true;
}
static bool tryGetStr(JSValueRef val, char** ppRet) {
if (JSValueIsString(__TlsData::GetInstance()->GetCurContext(), val)) {
*ppRet = JsCharToC(val);
return true;
}
return false;
}
void Reset() {
JSContextRef ctx = __TlsData::GetInstance()->GetCurContext();
if (m_pValue != nullptr && ctx != nullptr){
JSValueUnprotect(ctx, m_pValue);
m_pValue = nullptr;
}
}
void __BindThis(JsObjHandleJSC &p_This) {}
bool IsFunction() {
if (!m_pObj)return false;
JSContextRef ctx = __TlsData::GetInstance()->GetCurContext();
JSObjectRef valueObj = JSValueToObject(ctx, m_pValue, nullptr);
if (!JSObjectIsFunction(ctx, valueObj))
return false;
return true;
}
bool isValid() {
return m_pValue != nullptr && m_pObj != nullptr && m_pObj->IsMyJsEnv();
}
#define CALLJSPRE \
if (!m_pObj)return false; \
JSContextRef ctx = __TlsData::GetInstance()->GetCurContext(); \
JSObjectRef func = JSValueToObject(ctx, m_pValue, nullptr); \
if (!JSObjectIsFunction(ctx,func)) \
return false;
bool Call() {
CALLJSPRE
m_pReturn = m_pObj->callJsFunc(func);
return true;
}
template <typename P1>
bool Call(P1 p1) {
CALLJSPRE
m_pReturn = m_pObj->callJsFunc(func,p1);
return true;
}
template <typename P1, typename P2>
bool Call(P1 p1, P2 p2) {
CALLJSPRE
m_pReturn = m_pObj->callJsFunc(func, p1, p2);
return true;
}
template <typename P1, typename P2, typename P3>
bool Call(P1 p1, P2 p2, P3 p3) {
CALLJSPRE
m_pReturn = m_pObj->callJsFunc(func, p1, p2, p3);
return true;
}
template <typename P1, typename P2, typename P3, typename P4>
bool Call(P1 p1, P2 p2, P3 p3, P4 p4) {
CALLJSPRE
m_pReturn = m_pObj->callJsFunc(func, p1, p2, p3, p4);
return true;
}
template <typename P1, typename P2, typename P3, typename P4, typename P5>
bool Call(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) {
CALLJSPRE
m_pReturn = m_pObj->callJsFunc(func, p1, p2, p3, p4, p5);
return true;
}
template <typename P1, typename P2, typename P3, typename P4, typename P5, typename P6>
bool Call(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) {
CALLJSPRE
m_pReturn = m_pObj->callJsFunc(func, p1, p2, p3, p4, p5, p6);
return true;
}
template <typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7>
bool Call(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7) {
CALLJSPRE
m_pReturn = m_pObj->callJsFunc(func, p1, p2, p3, p4, p5, p6, p7);
return true;
}
};
#endif
@@ -0,0 +1,97 @@
/**
@file JSCEnv.cpp
@brief
@author James
@version 1.0
@date 2018_8_23
*/
#include "JSCEnv.h"
#include "../../../CToObjectC.h"
#ifdef __APPLE__
#include <pthread.h>
#endif
namespace laya
{
pthread_key_t __TlsData::s_tls_curThread;
static JSValueRef gcCallback( JSContextRef ctx, JSObjectRef functionObject, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception )
{
JSGlobalContextRef pCtx = JSContextGetGlobalContext(ctx);
JSGarbageCollect( pCtx );
//JSSynchronousEdenCollectForDebugging(pCtx);
//JSSynchronousGarbageCollectForDebugging(pCtx);
return JSValueMakeUndefined(ctx);
}
void AlertOnJsException(bool b)
{
}
void Javascript::initJSEngine()
{
m_pGlobalContext = JSGlobalContextCreateInGroup(NULL, NULL);
m_pUndefined = JSValueMakeUndefined(m_pGlobalContext);
JSValueProtect(m_pGlobalContext, m_pUndefined);
__TlsData::GetInstance()->SetCurContext(m_pGlobalContext);
// expose gc()
JSStringRef pJSName = JSStringCreateWithUTF8CString("gc");
JSObjectRef pFunc = JSObjectMakeFunctionWithCallback(m_pGlobalContext, pJSName, gcCallback);
JSValueRef exception = 0;
JSObjectSetProperty(m_pGlobalContext, JSContextGetGlobalObject(m_pGlobalContext), pJSName, pFunc, kJSPropertyAttributeDontDelete, &exception);
if (0 != exception)
{
__JSRun::OutputException(exception);
}
JSStringRelease(pJSName);
}
void Javascript::uninitJSEngine()
{
__TlsData::GetInstance()->SetCurContext(NULL);
JSValueUnprotect(m_pGlobalContext, m_pUndefined);
JSGlobalContextRelease(m_pGlobalContext);
}
//------------------------------------------------------------------------------
JSCWorker::JSCWorker()
{
}
JSCWorker::~JSCWorker()
{
}
void JSCWorker::stop()
{
if (m_bStop)return;
m_bStop = true;
m_ThreadTasks.Stop();
m_bdbgThreadStarted = false;
}
void JSCWorker::_defRunLoop()
{
//设置tls
pthread_setspecific(s_tls_curThread, (void*)this);
//开始事件
JCEventEmitter::evtPtr startEvt(new JCEventBase);
startEvt->m_nID = JCWorkerThread::Event_threadStart;
emit(startEvt);
CToObjectCRunJSLoop();
//退出事件
JCEventEmitter::evtPtr stopEvt(new JCEventBase);
stopEvt->m_nID = JCWorkerThread::Event_threadStop;
emit(stopEvt);
}
void JSCWorker::_runLoop()
{
m_pJS->initJSEngine();
_defRunLoop();
m_pJS->uninitJSEngine();
}
};
//------------------------------------------------------------------------------
//-----------------------------END FILE--------------------------------
@@ -0,0 +1,301 @@
/**
@file JSCEnv.h
@brief
@author James
@version 1.0
@date 2018_8_23
*/
#ifndef __JSCEnv_H__
#define __JSCEnv_H__
#include <JavaScriptCore/JavaScriptCore.h>
#include "JSCProxyTLS.h"
#include <misc/JCWorkerThread.h>
namespace laya
{
void JSPrint( const char* p_sBuffer );
void JSAlert( const char* p_sBuffer );
void JSAlertExit( const char* p_sBuffer );
void evalJS( const char* p_sSource );
class Javascript
{
public:
typedef void(*voidfun)(void* data);
Javascript()
{
}
void init(int nPort)
{
}
void run(const char* sSource)
{
}
void run(const char* sSource, std::function<void(void)> preRunFunc)
{
}
void run(voidfun func, void* pdata)
{
}
void uninit()
{
}
void initJSEngine();
void uninitJSEngine();
public:
JSGlobalContextRef m_pGlobalContext;
JSValueRef m_pUndefined;
};
class JSThreadInterface
{
public:
JSThreadInterface()
{
}
virtual ~JSThreadInterface()
{
}
virtual void post(std::function<void(void)> func) = 0;
virtual void on(int nEvent, JCEventEmitter::EventHandler func, void* pInThread = 0) = 0;
virtual void start() = 0;
virtual void stop() = 0;
virtual void initialize(int nPort) = 0;
virtual void uninitialize() = 0;
virtual void setLoopFunc(std::function<bool(void)> func) = 0;
virtual void pushDbgFunc(std::function<void(void)> task) = 0;
virtual void runDbgFuncs() = 0;
virtual void waitAndRunDbgFuncs() = 0;
virtual bool hasDbgFuncs() = 0;
virtual JCWorkerThread* getWorker() = 0;
virtual void run(Javascript::voidfun func, void* pData) = 0;
virtual void clearFunc() = 0;
};
class JSCWorker : public JCWorkerThread
{
public:
JSCWorker();
~JSCWorker();
virtual void _defRunLoop();
virtual void _runLoop();
virtual void stop();
public:
Javascript* m_pJS;
};
class JSMulThread : public JSThreadInterface
{
public:
JSMulThread()
{
m_kWorker.setThreadName("JavaScript Main");
m_kWorker.m_pJS = &m_kJS;
}
~JSMulThread()
{
}
void post(std::function<void(void)> func)
{
if (m_kWorker.m_bStop)return;
CToObjectCPostFunc(func);
}
void on(int nEvent, JCEventEmitter::EventHandler func, void* pInThread = 0)
{
m_kWorker.on(nEvent, func, (JCWorkerThread*)pInThread);
}
void start()
{
m_kWorker.start();
}
void stop()
{
m_kWorker.stop();
}
void initialize(int nPort)
{
m_kJS.init(nPort);
}
void uninitialize()
{
m_kJS.uninit();
}
void setLoopFunc(std::function<bool(void)> func)
{
m_kWorker.setLoopFunc(func);
}
void pushDbgFunc(std::function<void(void)> task)
{
}
void runDbgFuncs()
{
}
void waitAndRunDbgFuncs()
{
}
bool hasDbgFuncs()
{
return false;
}
JCWorkerThread* getWorker()
{
return &m_kWorker;
}
void run(Javascript::voidfun func, void* pData)
{
m_kWorker.runQueue();
m_kWorker.m_funcLoop();
}
void clearFunc()
{
}
public:
Javascript m_kJS;
JSCWorker m_kWorker;
};
class JSSingleThread : public JSThreadInterface
{
public:
JSSingleThread()
{
}
~JSSingleThread()
{
}
void post(std::function<void(void)> func)
{
//if (m_kWorker.m_bStop)return;
//CToObjectCPostFunc(func);
m_kQueueLock.lock();
m_vFuncQueue.push_back(func);
m_kQueueLock.unlock();
}
void on(int nEvent, JCEventEmitter::EventHandler func, void* pInThread = 0)
{
switch (nEvent)
{
case JCWorkerThread::Event_threadStart:
m_kStartFunc.func = func;
m_kStartFunc.bDel = false;
break;
case JCWorkerThread::Event_threadStop:
m_kStopFunc.func = func;
m_kStopFunc.bDel = false;
break;
default:
LOGE("JSSingleThread on() event type error");
break;
}
}
void start()
{
m_kStartFunc.func(NULL);
}
void stop()
{
m_kStopFunc.func(NULL);
}
void initialize(int nPort)
{
clearFunc();
m_kJS.init(nPort);
m_kJS.initJSEngine();
}
void uninitialize()
{
clearFunc();
m_kJS.uninitJSEngine();
m_kJS.uninit();
}
void setLoopFunc(std::function<bool(void)> func)
{
m_kLoopFunc = func;
}
void pushDbgFunc(std::function<void(void)> task)
{
}
void runDbgFuncs()
{
}
void waitAndRunDbgFuncs()
{
}
bool hasDbgFuncs()
{
return false;
}
JCWorkerThread* getWorker()
{
return NULL;
}
void run(Javascript::voidfun func, void* pData)
{
runFunQueue();
m_kLoopFunc();
}
void clearFunc()
{
m_kQueueLock.lock();
m_vFuncQueue.clear();
m_kQueueLock.unlock();
}
public:
void runFunQueue()
{
std::vector<std::function<void(void)>> vWorkQueue;
m_kQueueLock.lock();
std::swap(vWorkQueue, m_vFuncQueue);
m_kQueueLock.unlock();
for (int i = 0; i < (int)vWorkQueue.size(); i++)
{
vWorkQueue[i]();
}
}
public:
Javascript m_kJS;
JCEventEmitter::EvtHandlerPack m_kStartFunc;
JCEventEmitter::EvtHandlerPack m_kStopFunc;
std::vector<std::function<void(void)>> m_vFuncQueue;
std::mutex m_kQueueLock;
std::function<bool(void)> m_kLoopFunc;
};
};
//------------------------------------------------------------------------------
#endif //__JSCEnv_H__
//-----------------------------END FILE--------------------------------
@@ -0,0 +1,73 @@
//
// JSCPropertyHandle.h
// conch
//
// Created by joychina on 15/6/27.
// Copyright (c) 2015年 LayaBox. All rights reserved.
//
#ifndef conch_JSCPropertyHandle_h
#define conch_JSCPropertyHandle_h
#include <JavaScriptCore/JavaScriptCore.h>
#include <JavaScriptCore/JavaScript.h>
#include <JavaScriptCore/JSObjectRef.h>
#include "JSCProxyTLS.h"
namespace laya
{
class JSCProxyArray
{
public:
JSValueRef pJSArray;
JSContextRef pContext;
JSValueRef pTmp;
public:
void initArrayByScript(const char* szScript)
{
__JSRun::Run(szScript,&pJSArray);
pContext = __TlsData::GetInstance()->GetCurContext();
}
int getLength()
{
JSStringRef pname = JSStringCreateWithUTF8CString("length");
JSValueRef exception = 0;
JSValueRef val = JSObjectGetProperty(pContext, (JSObjectRef)pJSArray, pname, &exception);
if( 0 != exception )
{
__JSRun::OutputException( exception );
}
double _len =JSValueToNumber(pContext, val, &exception);
if( 0 != exception )
{
__JSRun::OutputException( exception );
}
JSStringRelease(pname);
return (int)_len;
}
JSValueRef &operator [](int nIndex)
{
JSValueRef exception = 0;
pTmp = JSObjectGetPropertyAtIndex(pContext, (JSObjectRef)pJSArray, nIndex, &exception);
if( 0 != exception )
{
__JSRun::OutputException( exception );
}
return pTmp;
}
void setPropertyValue(unsigned int index,JSValueRef value){
JSValueRef exception = 0;
JSObjectSetPropertyAtIndex(pContext, (JSObjectRef)pJSArray, index, value, &exception);
if( 0 != exception )
{
__JSRun::OutputException( exception );
}
}
};
}
#endif
@@ -0,0 +1,615 @@
#ifndef _JSCProxyClass_h
#define _JSCProxyClass_h
#include <unordered_map>
#include "JSCProxyTransfer.h"
#include "JSCProxyFunction.h"
#include "JSCProxyType.h"
namespace laya
{
class JSCGlobal
{
public:
JSCGlobal(){}
~JSCGlobal(){
reset();
}
template <typename T>
void addProperty( const std::string& name, T value ){
assert( !name.empty());
JSContextRef pCtx = __TlsData::GetInstance()->GetCurContext();
JSStringRef pJSStrName = JSStringCreateWithUTF8CString( name.c_str() );
JSValueRef pVal = __TransferToJs<T>::ToJs( value );
JSObjectSetProperty( pCtx, JSContextGetGlobalObject( pCtx ), pJSStrName, pVal, kJSPropertyAttributeDontDelete|kJSPropertyAttributeReadOnly, nullptr );
JSStringRelease( pJSStrName );
}
template <typename T>
void addFunction( const std::string& name, T fun ){
assert( !name.empty() );
IJSCFunction* pJSCFunction = new JSCFunction<T>( fun );
JSContextRef pCtx = __TlsData::GetInstance()->GetCurContext();
JSStringRef pjsName = JSStringCreateWithUTF8CString( name.c_str() );
JSObjectRef pFunc = JSObjectMakeFunctionWithCallback(pCtx, pjsName, JSObjectCallAsFunctionCallback);
JSObjectSetProperty(pCtx, JSContextGetGlobalObject(pCtx), pjsName, pFunc, kJSPropertyAttributeDontDelete|kJSPropertyAttributeReadOnly, nullptr);
JSStringRelease( pjsName );
FunctionMapRes rs = m_FunctionMap.insert(FunctionMapValue((unsigned long)pFunc, pJSCFunction));
assert( rs.second );
}
IJSCFunction* getFunction(unsigned long func){
FunctionMapItr itrFun = m_FunctionMap.find( func );
if ( itrFun != m_FunctionMap.end() ){
return itrFun->second;
}
else {
return nullptr;
}
}
static JSValueRef JSObjectCallAsFunctionCallback(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
IJSCFunction* pJSCFunction = JSCGlobal::getInstance()->getFunction( (unsigned long)function );
if ( pJSCFunction == nullptr ){
__JsThrow::Throw(exception,"JSCGlobal::JSObjectCallAsFunctionCallback can't find function");
return nullptr;
}
return pJSCFunction->call(ctx, function, thisObject, argumentCount, arguments, exception);
}
static JSCGlobal* getInstance(){
static JSCGlobal instance;
return &instance;
}
void reset(){
FunctionMapItr iter = m_FunctionMap.begin();
for (; iter != m_FunctionMap.end(); iter++){
delete iter->second;
}
m_FunctionMap.clear();
}
private:
typedef std::unordered_map<unsigned long,IJSCFunction*> FunctionMap;
typedef FunctionMap::value_type FunctionMapValue;
typedef FunctionMap::iterator FunctionMapItr;
typedef std::pair<FunctionMapItr,bool> FunctionMapRes;
FunctionMap m_FunctionMap;
};
template<typename T>
class JSCClass
{
public:
inline unsigned int __hash_BKDR(const char *p_str){
if( 0 == p_str )
return 0;
unsigned int seed = 131; // 31 131 1313 13131 131313 etc..
unsigned int hash = 0;
for(;0!=*p_str;){
hash = hash * seed + (*p_str++);
}
return (hash & 0x7FFFFFFF);
}
class FuncEntry
{
enum
{
Max_Arg_Size = 12,
Invalid_size = -1,
};
IJSCCallback *m_funcs[Max_Arg_Size+1];
int m_iMaxArgSize;
public:
FuncEntry(){
m_iMaxArgSize = Invalid_size;
memset( m_funcs, 0, sizeof(m_funcs) );
}
~FuncEntry(){
reset();
}
void reset(){
for(int i=0;i<=Max_Arg_Size;++i){
if( 0 != m_funcs[i] ){
delete m_funcs[i];
m_funcs[i] = 0;
}
}
}
void add( IJSCCallback *p_fn ){
assert(p_fn != nullptr && p_fn->getNumArgs() <= Max_Arg_Size && m_funcs[p_fn->getNumArgs()] == nullptr );
if( m_iMaxArgSize < p_fn->getNumArgs() )
m_iMaxArgSize = p_fn->getNumArgs();
m_funcs[p_fn->getNumArgs()] = p_fn;
}
IJSCCallback *get( int p_iArgNum ){
if( Invalid_size == m_iMaxArgSize ){
return 0;
}
if( p_iArgNum > m_iMaxArgSize )
p_iArgNum = m_iMaxArgSize;
for(;p_iArgNum>=0;p_iArgNum--){
if( 0 != m_funcs[p_iArgNum] )
return m_funcs[p_iArgNum];
}
return 0;
}
};
enum
{
CallbackType_Property,
CallbackType_Function,
};
struct CallbackDefine
{
int m_iType;
std::string m_name;
IJSCCallback* m_pSetter;
IJSCCallback* m_pGetter;
FuncEntry m_Method;
JSValueRef m_pCallAsFunction;
CallbackDefine(const std::string& name, IJSCCallback* setter, IJSCCallback* getter)
:m_name(name), m_iType(CallbackType_Property), m_pSetter(setter), m_pGetter(getter),m_pCallAsFunction(nullptr){
}
CallbackDefine(const std::string& name,IJSCCallback* method)
:m_name(name), m_iType(CallbackType_Function), m_pSetter(nullptr), m_pGetter(nullptr),m_pCallAsFunction(nullptr){
m_Method.add(method);
}
void addMethod( IJSCCallback *p_pfn ){
m_Method.add(p_pfn);
}
IJSCCallback *getMethod( size_t p_iArgNum ){
return m_Method.get( (int)p_iArgNum );
}
~CallbackDefine(){
if (m_pGetter){
delete m_pGetter;
m_pGetter = nullptr;
}
if (m_pSetter){
delete m_pSetter;
m_pSetter = nullptr;
}
m_Method.reset();
JSContextRef ctx = __TlsData::GetInstance()->GetCurContext();
if (ctx != nullptr && m_pCallAsFunction != nullptr){
JSValueUnprotect(ctx, m_pCallAsFunction);
}
}
};
struct FixedProperty
{
private:
JSValueRef m_pszName;
JSValueRef m_pValue;
public:
template <typename _Tp>
explicit FixedProperty( const char *p_pszName, _Tp p_Val )
{
JSContextRef pCtx = __TlsData::GetInstance()->GetCurContext();
JSStringRef pszName = JSStringCreateWithUTF8CString(p_pszName);
m_pszName = JSValueMakeString(pCtx, pszName);
JSStringRelease(pszName);
m_pValue = __TransferToJs<_Tp>::ToJs(p_Val);
JSValueProtect( pCtx, m_pszName );
JSValueProtect( pCtx, m_pValue );
}
~FixedProperty()
{
JSContextRef pCtx = __TlsData::GetInstance()->GetCurContext();
if( 0 != pCtx )
{
if( 0 != m_pszName )
{
JSValueUnprotect( pCtx, m_pszName );
}
if( 0 != m_pValue )
{
JSValueUnprotect( pCtx, m_pValue );
}
}
}
JSStringRef GetName()
{
return JSValueToStringCopy(__TlsData::GetInstance()->GetCurContext(), m_pszName, 0);
}
JSValueRef GetValue()
{
return m_pValue;
}
};
typedef std::vector<FixedProperty *> FixedProperties;
typedef typename FixedProperties::iterator FixedPropertiesIter;
FixedProperties m_FixedProperties;
JSCClass(){
m_bIsGlobal = false;
m_ClassDefine = kJSClassDefinitionEmpty;
m_ClassObject = nullptr;
m_iTypeID = __hash_BKDR(typeid(T).name());
}
~JSCClass(){
_reset();
}
unsigned int getTypeID(){
return m_iTypeID;
}
static JSCClass* getInstance(){
static JSCClass<T> instance;
return &instance;
}
template <typename P>
void addFixedProperty(const std::string& name,const P& val){
assert(!name.empty());
m_FixedProperties.push_back(new FixedProperty(name.c_str(),val));
}
template <typename G,typename S>
void addProperty( const std::string& name, G getter, S setter){
assert( !name.empty() );
IJSCCallback* pGetter = new JSCCallback<G>(getter);
IJSCCallback* pSetter = nullptr;
if (setter != nullptr){
pSetter = new JSCCallback<S>(setter);
}
PropertyMapRes rs = m_PropertyMap.insert(PropertyMapValue(name,new CallbackDefine(name,pSetter,pGetter)));
assert(rs.second && "JSCClass::addProperty name is dumplicate value");
}
void addConstructor( IJSCCallback* constructor ){
m_Constructor.add(constructor);
}
template<typename M>
void addMethod( const std::string& name, M method ){
PropertyMapItr iter = m_PropertyMap.find(name);
if ( iter != m_PropertyMap.end() ){
assert( iter->second->m_iType == CallbackType_Function );
iter->second->addMethod(new JSCCallback<M>(method));
return;
}
CallbackDefine* pProperty = new CallbackDefine(name,new JSCCallback<M>(method));
JSStringRef pName = JSStringCreateWithUTF8CString(name.c_str());
JSContextRef pCtx = __TlsData::GetInstance()->GetCurContext();
pProperty->m_pCallAsFunction = JSObjectMakeFunctionWithCallback(pCtx, pName, JSCClass<T>::callAsFunctionCallback);
JSStringRelease(pName);
JSValueProtect(pCtx, pProperty->m_pCallAsFunction);
PropertyMapRes rsp = m_PropertyMap.insert(PropertyMapValue(name,pProperty));
assert(rsp.second);
FunctionMapRes rsf = m_FunctionMap.insert(FunctionMapValue((unsigned long)pProperty->m_pCallAsFunction,pProperty));
assert(rsf.second);
}
void finish( const std::string& name ){
m_bIsGlobal = false;
finishImpl( name, nullptr);
}
void finishToGlobal( const std::string& name, T* pIns){
assert(pIns != nullptr);
m_bIsGlobal = false;
finishImpl( name, pIns);
m_bIsGlobal = true;
}
JSObjectRef transferObjPtrToJS( T *p_pIns ){
assert( !m_bIsGlobal );
JSContextRef pCtx = __TlsData::GetInstance()->GetCurContext();
JSObjectRef pRet = JSObjectMake( pCtx, m_ClassObject, p_pIns );
p_pIns->mpJsThis = pRet;
JSValueRef pProperty = JSValueMakeNumber(pCtx, (double)getTypeID());
JSStringRef pszName = JSStringCreateWithUTF8CString(__Js_class_typeid_property);
JSObjectSetProperty(pCtx, pRet, pszName, pProperty, kJSPropertyAttributeReadOnly|kJSPropertyAttributeDontDelete, 0);
JSStringRelease(pszName);
if( m_FixedProperties.size() ){
FixedPropertiesIter iter;
for(iter=m_FixedProperties.begin();iter!=m_FixedProperties.end();iter++){
JSStringRef sName = (*iter)->GetName();
JSObjectSetProperty(pCtx, pRet, sName, (*iter)->GetValue(), kJSPropertyAttributeReadOnly/*|kJSPropertyAttributeDontDelete*/, 0);
//kJSPropertyAttributeDontDelete 就意味着这个值不能改了 fuck
JSStringRelease(sName);
}
}
return pRet;
}
static void reset(){
JSCClass<T>::getInstance()->_reset();
}
private:
static JSObjectRef newWrap(JSContextRef ctx, JSObjectRef constructor, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
if( JSCClass<T>::getInstance()->m_bIsGlobal ){
__JsThrow::Throw(exception,"can't new a global object");
return NULL;
}
IJSCCallback *pfn = JSCClass<T>::getInstance()->m_Constructor.get( (int)argumentCount );
if( 0 == pfn ){
return JSCClass<T>::getInstance()->transferObjPtrToJS(new T);
}
else{
return pfn->constructor(ctx, constructor, argumentCount, arguments, exception);
}
}
static void destroyWrap(JSObjectRef object){
T *p = (T *)JSObjectGetPrivate(object);
delete p;
}
static bool isInstanceOf(JSContextRef ctx, JSObjectRef constructor, JSValueRef possibleInstance, JSValueRef* exception){
if( !JSValueIsObject(ctx, possibleInstance) ){
return false;
}
bool bRet = __CheckClassType::IsTypeOf<T>((JSObjectRef)possibleInstance);
return bRet;
}
static bool hasProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName){
std::string strPropertyName = __TransferToCpp<char *>::ToCpp(propertyName);
resetJsStrBuf();
if( !strPropertyName.length() ){
return false;
}
return (0 != JSCClass<T>::getInstance()->findProperty(strPropertyName.c_str()));
}
static JSValueRef getProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception){
T *pThis = (T *)JSObjectGetPrivate( object );
if( 0 == pThis ){
__JsThrow::Throw(exception,"not a global object");
return NULL;
}
std::string strPropertyName = __TransferToCpp<char *>::ToCpp(propertyName);
resetJsStrBuf();
if( !strPropertyName.length() ){
__JsThrow::Throw(exception,"GetProperty PropertyName is null");
return NULL;
}
CallbackDefine *pProperty = JSCClass<T>::getInstance()->findProperty(strPropertyName.c_str());
if( 0 == pProperty ){
__JsThrow::Throw(exception,"GetProperty can't find property");
return NULL;
}
JSValueRef pRet = NULL;
if( CallbackType_Property == pProperty->m_iType ){
// is property
pRet = pProperty->m_pGetter->call(ctx, nullptr, object, 0, nullptr, nullptr);//?????????????????????
}
else
{ // is function
pRet = pProperty->m_pCallAsFunction;
}
return pRet;
}
static bool setProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef value, JSValueRef* exception){
T *pThis = (T *)JSObjectGetPrivate( object );
if( 0 == pThis ){
__JsThrow::Throw(exception,"not a global object");
return false;
}
std::string sPropertyName = __TransferToCpp<char *>::ToCpp(propertyName);
resetJsStrBuf();
if( sPropertyName.empty() ){
__JsThrow::Throw(exception,"SetProperty PropertyName is null");
return false;
}
CallbackDefine *pProperty = JSCClass<T>::getInstance()->findProperty(sPropertyName);
if( 0 == pProperty ){
return false;
}
if( CallbackType_Property != pProperty->m_iType )
{
if( pProperty->m_iType == CallbackType_Function ){
JSObjectRef _obj = JSValueToObject(ctx, value, 0);
if( JSObjectIsFunction(ctx,_obj) ){
getInstance()->JSDefineFunction[sPropertyName] = _obj;
return true;
}
}
__JsThrow::Throw(exception,"SetProperty property is function object");
return false;
}
if( 0 == pProperty->m_pSetter ){
__JsThrow::Throw(exception,"SetProperty property is read only");
return false;
}
JSValueRef arguments[1];
arguments[0] = value;
pProperty->m_pSetter->call(ctx, nullptr, object, 1, arguments, nullptr);
return true;
}
static JSValueRef callAsFunctionCallback(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
T *pThis = (T *)JSObjectGetPrivate( thisObject );
if( nullptr == pThis ){
__JsThrow::Throw(exception,"CallAsFunctionCallback this is null");
return JSValueMakeUndefined(ctx);
}
CallbackDefine *pProperty = JSCClass<T>::getInstance()->findFunction((unsigned long)function);
if( pProperty != NULL ){
JSDefineFunctionIter it = getInstance()->JSDefineFunction.find(pProperty->m_name);
if( it != getInstance()->JSDefineFunction.end() ){
return JSObjectCallAsFunction(ctx,it->second,thisObject,argumentCount,arguments,0);
}
}
if( nullptr == pProperty ){
__JsThrow::Throw(exception,"CallAsFunctionCallback can't find function");
return JSValueMakeUndefined(ctx);
}
IJSCCallback *pMethod = pProperty->getMethod(argumentCount);
if( 0 != pMethod ){
//__JsThrow::GetInstance()->UpdateException(exception);
return pMethod->call(ctx, function, thisObject, argumentCount, arguments, exception);
}
else
{
__JsThrow::Throw(exception,"callAsFunctionCallback can't find function");
return JSValueMakeUndefined(ctx);
}
}
private:
void _reset(){
if( m_FixedProperties.size() ){
FixedPropertiesIter iter;
for(iter=m_FixedProperties.begin();iter!=m_FixedProperties.end();iter++){
delete *iter;
}
m_FixedProperties.clear();
}
for (PropertyMapItr itr = m_PropertyMap.begin(); itr != m_PropertyMap.end(); itr++ ){
delete itr->second;
}
m_PropertyMap.clear();
m_FunctionMap.clear();
m_bIsGlobal = false;
m_ClassDefine = kJSClassDefinitionEmpty;
if ( m_ClassObject != nullptr ){
JSClassRelease(m_ClassObject);
m_ClassObject = nullptr;
}
JSDefineFunction.clear();
m_Constructor.reset();
}
void finishImpl( const std::string& name, T *p_pIns ){
assert(!name.empty());
m_ClassDefine = kJSClassDefinitionEmpty;
m_ClassDefine.attributes = kJSClassAttributeNone;
m_ClassDefine.className = name.c_str();
m_ClassDefine.callAsConstructor = JSCClass<T>::newWrap;
m_ClassDefine.finalize = JSCClass<T>::destroyWrap;
m_ClassDefine.hasProperty = JSCClass<T>::hasProperty;
m_ClassDefine.hasInstance = JSCClass<T>::isInstanceOf;
m_ClassDefine.getProperty = JSCClass<T>::getProperty;
m_ClassDefine.setProperty = JSCClass<T>::setProperty;
m_ClassDefine.callAsFunction = JSCClass<T>::callAsFunctionCallback;
m_ClassObject = JSClassCreate(&m_ClassDefine);
JSContextRef pCtx = __TlsData::GetInstance()->GetCurContext();
JSStringRef jsName = JSStringCreateWithUTF8CString(name.c_str());
JSObjectRef myObject;
if( 0 != p_pIns ){
myObject = transferObjPtrToJS( p_pIns );
p_pIns->mpJsThis = myObject;
}
else
{
myObject = JSObjectMake(pCtx, m_ClassObject, 0);
}
JSObjectSetProperty( pCtx, JSContextGetGlobalObject(pCtx), jsName, myObject, kJSPropertyAttributeNone, NULL );//???
JSStringRelease(jsName);
}
CallbackDefine *findFunction( unsigned long p_ulObj ){
FunctionMapItr iter = m_FunctionMap.find(p_ulObj);
if( iter == m_FunctionMap.end() ){
return nullptr;
}
else
{
return (*iter).second;
}
}
CallbackDefine *findProperty( const std::string& name ){
PropertyMapItr iter = m_PropertyMap.find(name);
if( iter == m_PropertyMap.end() ){
return nullptr;
}
else
{
return (*iter).second;
}
}
private:
typedef std::unordered_map<std::string,CallbackDefine*> PropertyMap;
typedef typename PropertyMap::value_type PropertyMapValue;
typedef typename PropertyMap::iterator PropertyMapItr;
typedef std::pair<PropertyMapItr,bool> PropertyMapRes;
PropertyMap m_PropertyMap;
typedef std::unordered_map<unsigned long,CallbackDefine*> FunctionMap;
typedef typename FunctionMap::value_type FunctionMapValue;
typedef typename FunctionMap::iterator FunctionMapItr;
typedef std::pair<FunctionMapItr,bool> FunctionMapRes;
FunctionMap m_FunctionMap;
bool m_bIsGlobal;
JSClassDefinition m_ClassDefine;
JSClassRef m_ClassObject;
typedef std::unordered_map<std::string,JSObjectRef>::iterator JSDefineFunctionIter;
std::unordered_map<std::string, JSObjectRef> JSDefineFunction;
unsigned int m_iTypeID;
FuncEntry m_Constructor;
};
}
#endif
@@ -0,0 +1,826 @@
#ifndef _JSCProxyFunction_h
#define _JSCProxyFunction_h
namespace laya
{
template<class T>
JSValueRef ToJSValue(T t) {
return __TransferToJs<T>::ToJs(t);
}
inline bool checkJSToCArgs(size_t given, size_t expect) {
assert(given >= expect);
if (given >= expect)
return true;
static char buff[512];
sprintf(buff, "console.log('arguments number err: %d:%d');var e = new Error();console.log(e.stack);", expect, given);
//__JSRun::Run(buff);
return false;
}
#define JS2CCALL_GET_COBJ \
Cls* pThis = (Cls*)JSObjectGetPrivate( thisObject );
#define JS2CCALL_GET_PARAMS1 \
if(!checkJSToCArgs(argumentCount,1))return JSValueMakeUndefined(ctx);\
P1 p1 = __TransferToCpp<P1>::ToCpp(arguments[0]);
#define JS2CCALL_GET_PARAMS2 \
if(!checkJSToCArgs(argumentCount,2))return JSValueMakeUndefined(ctx);\
P1 p1 = __TransferToCpp<P1>::ToCpp(arguments[0]);\
P2 p2 = __TransferToCpp<P2>::ToCpp(arguments[1]);
#define JS2CCALL_GET_PARAMS3 \
if(!checkJSToCArgs(argumentCount,3))return JSValueMakeUndefined(ctx);\
P1 p1 = __TransferToCpp<P1>::ToCpp(arguments[0]);\
P2 p2 = __TransferToCpp<P2>::ToCpp(arguments[1]);\
P3 p3 = __TransferToCpp<P3>::ToCpp(arguments[2]);
#define JS2CCALL_GET_PARAMS4 \
if(!checkJSToCArgs(argumentCount,4))return JSValueMakeUndefined(ctx);\
P1 p1 = __TransferToCpp<P1>::ToCpp(arguments[0]);\
P2 p2 = __TransferToCpp<P2>::ToCpp(arguments[1]);\
P3 p3 = __TransferToCpp<P3>::ToCpp(arguments[2]);\
P4 p4 = __TransferToCpp<P4>::ToCpp(arguments[3]);
#define JS2CCALL_GET_PARAMS5 \
if(!checkJSToCArgs(argumentCount,5))return JSValueMakeUndefined(ctx);\
P1 p1 = __TransferToCpp<P1>::ToCpp(arguments[0]);\
P2 p2 = __TransferToCpp<P2>::ToCpp(arguments[1]);\
P3 p3 = __TransferToCpp<P3>::ToCpp(arguments[2]);\
P4 p4 = __TransferToCpp<P4>::ToCpp(arguments[3]);\
P5 p5 = __TransferToCpp<P5>::ToCpp(arguments[4]);
#define JS2CCALL_GET_PARAMS6 \
if(!checkJSToCArgs(argumentCount,6))return JSValueMakeUndefined(ctx);\
P1 p1 = __TransferToCpp<P1>::ToCpp(arguments[0]);\
P2 p2 = __TransferToCpp<P2>::ToCpp(arguments[1]);\
P3 p3 = __TransferToCpp<P3>::ToCpp(arguments[2]);\
P4 p4 = __TransferToCpp<P4>::ToCpp(arguments[3]);\
P5 p5 = __TransferToCpp<P5>::ToCpp(arguments[4]);\
P6 p6 = __TransferToCpp<P6>::ToCpp(arguments[5]);
#define JS2CCALL_GET_PARAMS7 \
if(!checkJSToCArgs(argumentCount,7))return JSValueMakeUndefined(ctx);\
P1 p1 = __TransferToCpp<P1>::ToCpp(arguments[0]);\
P2 p2 = __TransferToCpp<P2>::ToCpp(arguments[1]);\
P3 p3 = __TransferToCpp<P3>::ToCpp(arguments[2]);\
P4 p4 = __TransferToCpp<P4>::ToCpp(arguments[3]);\
P5 p5 = __TransferToCpp<P5>::ToCpp(arguments[4]);\
P6 p6 = __TransferToCpp<P6>::ToCpp(arguments[5]);\
P7 p7 = __TransferToCpp<P7>::ToCpp(arguments[6]);
#define JS2CCALL_GET_PARAMS8 \
if(!checkJSToCArgs(argumentCount,8))return JSValueMakeUndefined(ctx);\
P1 p1 = __TransferToCpp<P1>::ToCpp(arguments[0]);\
P2 p2 = __TransferToCpp<P2>::ToCpp(arguments[1]);\
P3 p3 = __TransferToCpp<P3>::ToCpp(arguments[2]);\
P4 p4 = __TransferToCpp<P4>::ToCpp(arguments[3]);\
P5 p5 = __TransferToCpp<P5>::ToCpp(arguments[4]);\
P6 p6 = __TransferToCpp<P6>::ToCpp(arguments[5]);\
P7 p7 = __TransferToCpp<P7>::ToCpp(arguments[6]);\
P8 p8 = __TransferToCpp<P8>::ToCpp(arguments[7]);
#define JS2CCALL_GET_PARAMS9 \
if(!checkJSToCArgs(argumentCount,9))return JSValueMakeUndefined(ctx);\
P1 p1 = __TransferToCpp<P1>::ToCpp(arguments[0]);\
P2 p2 = __TransferToCpp<P2>::ToCpp(arguments[1]);\
P3 p3 = __TransferToCpp<P3>::ToCpp(arguments[2]);\
P4 p4 = __TransferToCpp<P4>::ToCpp(arguments[3]);\
P5 p5 = __TransferToCpp<P5>::ToCpp(arguments[4]);\
P6 p6 = __TransferToCpp<P6>::ToCpp(arguments[5]);\
P7 p7 = __TransferToCpp<P7>::ToCpp(arguments[6]);\
P8 p8 = __TransferToCpp<P8>::ToCpp(arguments[7]);\
P9 p9 = __TransferToCpp<P9>::ToCpp(arguments[8]);
#define JS2CCALL_GET_PARAMS11 \
if(!checkJSToCArgs(argumentCount,11))return JSValueMakeUndefined(ctx);\
P1 p1 = __TransferToCpp<P1>::ToCpp(arguments[0]);\
P2 p2 = __TransferToCpp<P2>::ToCpp(arguments[1]);\
P3 p3 = __TransferToCpp<P3>::ToCpp(arguments[2]);\
P4 p4 = __TransferToCpp<P4>::ToCpp(arguments[3]);\
P5 p5 = __TransferToCpp<P5>::ToCpp(arguments[4]);\
P6 p6 = __TransferToCpp<P6>::ToCpp(arguments[5]);\
P7 p7 = __TransferToCpp<P7>::ToCpp(arguments[6]);\
P8 p8 = __TransferToCpp<P8>::ToCpp(arguments[7]);\
P9 p9 = __TransferToCpp<P9>::ToCpp(arguments[8]);\
P10 p10 = __TransferToCpp<P10>::ToCpp(arguments[9]);\
P11 p11 = __TransferToCpp<P11>::ToCpp(arguments[10]);
#define JS2CCALL_GET_PARAMS12 \
if(!checkJSToCArgs(argumentCount,12))return JSValueMakeUndefined(ctx);\
P1 p1 = __TransferToCpp<P1>::ToCpp(arguments[0]);\
P2 p2 = __TransferToCpp<P2>::ToCpp(arguments[1]);\
P3 p3 = __TransferToCpp<P3>::ToCpp(arguments[2]);\
P4 p4 = __TransferToCpp<P4>::ToCpp(arguments[3]);\
P5 p5 = __TransferToCpp<P5>::ToCpp(arguments[4]);\
P6 p6 = __TransferToCpp<P6>::ToCpp(arguments[5]);\
P7 p7 = __TransferToCpp<P7>::ToCpp(arguments[6]);\
P8 p8 = __TransferToCpp<P8>::ToCpp(arguments[7]);\
P9 p9 = __TransferToCpp<P9>::ToCpp(arguments[8]);\
P10 p10 = __TransferToCpp<P10>::ToCpp(arguments[9]);\
P11 p11 = __TransferToCpp<P11>::ToCpp(arguments[10]);\
P11 p12 = __TransferToCpp<P11>::ToCpp(arguments[11]);
struct IJSCCallback
{
virtual ~IJSCCallback(){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){assert(false);return nullptr;}
virtual JSObjectRef constructor(JSContextRef ctx, JSObjectRef constructor, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){assert(false);return nullptr;}
virtual uint16_t getNumArgs() = 0;
};
template<typename T>
struct JSCCallback: public IJSCCallback {
JSCCallback(T func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
assert(false && "JSCCallback::call not implemented");
return nullptr;
}
virtual uint16_t getNumArgs() { return 0; }
};
template<typename R, typename Cls>
struct JSCCallback<R(Cls::*)(void)> :public IJSCCallback{
typedef R(Cls::*F)(void);
JSCCallback(F func):m_func(func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JS2CCALL_GET_COBJ;
JSValueRef ret = ToJSValue<R>((pThis->*m_func)());
resetJsStrBuf();
return ret;
}
virtual uint16_t getNumArgs() { return 0; }
F m_func;
};
template<typename R, typename Cls, typename P1>
struct JSCCallback<R(Cls::*)(P1)>: public IJSCCallback {
typedef R(Cls::*F)(P1);
JSCCallback(F func):m_func(func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JS2CCALL_GET_COBJ;
JS2CCALL_GET_PARAMS1;
JSValueRef ret = ToJSValue<R>((pThis->*m_func)(p1));
resetJsStrBuf();
return ret;
}
virtual uint16_t getNumArgs() { return 1; }
F m_func;
};
template<typename R, typename Cls, typename P1, typename P2>//2
struct JSCCallback<R(Cls::*)(P1, P2)>:public IJSCCallback {
typedef R(Cls::*F)(P1, P2);
JSCCallback(F func):m_func(func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JS2CCALL_GET_COBJ;
JS2CCALL_GET_PARAMS2;
JSValueRef ret = ToJSValue<R>((pThis->*m_func)(p1,p2));
resetJsStrBuf();
return ret;
}
virtual uint16_t getNumArgs() { return 2; }
F m_func;
};
template<typename R, typename Cls, typename P1, typename P2, typename P3>//3
struct JSCCallback<R(Cls::*)(P1, P2, P3)>:public IJSCCallback {
typedef R(Cls::*F)(P1, P2, P3);
JSCCallback(F func):m_func(func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JS2CCALL_GET_COBJ;
JS2CCALL_GET_PARAMS3;
JSValueRef ret = ToJSValue<R>((pThis->*m_func)(p1, p2,p3));
resetJsStrBuf();
return ret;
}
virtual uint16_t getNumArgs() { return 3; }
F m_func;
};
template<typename R, typename Cls, typename P1, typename P2, typename P3, typename P4>//4
struct JSCCallback<R(Cls::*)(P1, P2, P3, P4)>:public IJSCCallback {
typedef R(Cls::*F)(P1, P2, P3, P4);
JSCCallback(F func):m_func(func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JS2CCALL_GET_COBJ;
JS2CCALL_GET_PARAMS4;
JSValueRef ret = ToJSValue<R>((pThis->*m_func)(p1, p2, p3, p4));
resetJsStrBuf();
return ret;
}
virtual uint16_t getNumArgs() { return 4; }
F m_func;
};
template<typename R, typename Cls, typename P1, typename P2, typename P3, typename P4, typename P5>//5
struct JSCCallback<R(Cls::*)(P1, P2, P3, P4, P5)>:public IJSCCallback {
typedef R(Cls::*F)(P1, P2, P3, P4, P5);
JSCCallback(F func):m_func(func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JS2CCALL_GET_COBJ;
JS2CCALL_GET_PARAMS5;
JSValueRef ret = ToJSValue<R>((pThis->*m_func)(p1, p2, p3, p4,p5));
resetJsStrBuf();
return ret;
}
virtual uint16_t getNumArgs() { return 5; }
F m_func;
};
template<typename R, typename Cls, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6>//6
struct JSCCallback<R(Cls::*)(P1, P2, P3, P4, P5, P6)>:public IJSCCallback {
typedef R(Cls::*F)(P1, P2, P3, P4, P5, P6);
JSCCallback(F func):m_func(func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JS2CCALL_GET_COBJ;
JS2CCALL_GET_PARAMS6;
JSValueRef ret = ToJSValue<R>((pThis->*m_func)(p1, p2, p3, p4, p5,p6));
resetJsStrBuf();
return ret;
}
virtual uint16_t getNumArgs() { return 6; }
F m_func;
};
template<typename R, typename Cls, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7>//7
struct JSCCallback<R(Cls::*)(P1, P2, P3, P4, P5, P6, P7)>:public IJSCCallback {
typedef R(Cls::*F)(P1, P2, P3, P4, P5, P6, P7);
JSCCallback(F func):m_func(func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JS2CCALL_GET_COBJ;
JS2CCALL_GET_PARAMS7;
JSValueRef ret = ToJSValue<R>((pThis->*m_func)(p1, p2, p3, p4, p5,p7));
resetJsStrBuf();
return ret;
}
virtual uint16_t getNumArgs() { return 7; }
F m_func;
};
template<typename R, typename Cls, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9, typename P10, typename P11, typename P12>//12
struct JSCCallback<R(Cls::*)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12)>:public IJSCCallback {
typedef R(Cls::*F)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12);
JSCCallback(F func):m_func(func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JS2CCALL_GET_COBJ;
JS2CCALL_GET_PARAMS12;
JSValueRef ret = ToJSValue<R>((pThis->*m_func)(p1, p2, p3, p4, p5, p7, p8, p9, p10, p11, p12));
resetJsStrBuf();
return ret;
}
virtual uint16_t getNumArgs() { return 12; }
F m_func;
};
template<typename Cls>
struct JSCCallback<void(Cls::*)(void)>:public IJSCCallback {
typedef void(Cls::*F)(void);
JSCCallback(F func):m_func(func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JS2CCALL_GET_COBJ;
(pThis->*m_func)();
resetJsStrBuf();
return JSValueMakeUndefined(ctx);
}
virtual uint16_t getNumArgs() { return 0; }
F m_func;
};
template< typename P1, typename Cls>//1
struct JSCCallback<void(Cls::*)(P1)> :public IJSCCallback{
typedef void(Cls::*F)(P1);
JSCCallback(F func):m_func(func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JS2CCALL_GET_COBJ;
JS2CCALL_GET_PARAMS1;
(pThis->*m_func)(p1);
resetJsStrBuf();
return JSValueMakeUndefined(ctx);
}
virtual uint16_t getNumArgs() { return 1; }
F m_func;
};
template<typename Cls, typename P1, typename P2>//2
struct JSCCallback<void(Cls::*)(P1, P2)>:public IJSCCallback {
typedef void(Cls::*F)(P1, P2);
JSCCallback(F func):m_func(func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JS2CCALL_GET_COBJ;
JS2CCALL_GET_PARAMS2;
(pThis->*m_func)(p1,p2);
resetJsStrBuf();
return JSValueMakeUndefined(ctx);
}
virtual uint16_t getNumArgs() { return 2; }
F m_func;
};
template<typename Cls, typename P1, typename P2, typename P3>//3
struct JSCCallback<void(Cls::*)(P1, P2, P3)>:public IJSCCallback {
typedef void(Cls::*F)(P1, P2, P3);
JSCCallback(F func):m_func(func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JS2CCALL_GET_COBJ;
JS2CCALL_GET_PARAMS3;
(pThis->*m_func)(p1,p2,p3);
resetJsStrBuf();
return JSValueMakeUndefined(ctx);
}
virtual uint16_t getNumArgs() { return 3; }
F m_func;
};
template< typename Cls, typename P1, typename P2, typename P3, typename P4>//4
struct JSCCallback<void(Cls::*)(P1, P2, P3, P4)>:public IJSCCallback {
typedef void(Cls::*F)(P1, P2, P3, P4);
JSCCallback(F func):m_func(func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JS2CCALL_GET_COBJ;
JS2CCALL_GET_PARAMS4;
(pThis->*m_func)(p1, p2, p3, p4);
resetJsStrBuf();
return JSValueMakeUndefined(ctx);
}
virtual uint16_t getNumArgs() { return 4; }
F m_func;
};
template< typename Cls, typename P1, typename P2, typename P3, typename P4, typename P5>//5
struct JSCCallback<void(Cls::*)(P1, P2, P3, P4, P5)>:public IJSCCallback {
typedef void(Cls::*F)(P1, P2, P3, P4, P5);
JSCCallback(F func):m_func(func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JS2CCALL_GET_COBJ;
JS2CCALL_GET_PARAMS5;
(pThis->*m_func)(p1, p2, p3, p4, p5);
resetJsStrBuf();
return JSValueMakeUndefined(ctx);
}
virtual uint16_t getNumArgs() { return 5; }
F m_func;
};
template< typename Cls, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6>//6
struct JSCCallback<void(Cls::*)(P1, P2, P3, P4, P5, P6)>:public IJSCCallback {
typedef void(Cls::*F)(P1, P2, P3, P4, P5, P6);
JSCCallback(F func):m_func(func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JS2CCALL_GET_COBJ;
JS2CCALL_GET_PARAMS6;
(pThis->*m_func)(p1, p2, p3, p4, p5, p6);
resetJsStrBuf();
return JSValueMakeUndefined(ctx);
}
virtual uint16_t getNumArgs() { return 6; }
F m_func;
};
template< typename Cls, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7>//7
struct JSCCallback<void(Cls::*)(P1, P2, P3, P4, P5, P6, P7)>:public IJSCCallback {
typedef void(Cls::*F)(P1, P2, P3, P4, P5, P6, P7);
JSCCallback(F func):m_func(func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JS2CCALL_GET_COBJ;
JS2CCALL_GET_PARAMS7;
(pThis->*m_func)(p1, p2, p3, p4, p5, p6, p7);
resetJsStrBuf();
return JSValueMakeUndefined(ctx);
}
virtual uint16_t getNumArgs() { return 7; }
F m_func;
};
template< typename Cls, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9>//9
struct JSCCallback<void(Cls::*)(P1, P2, P3, P4, P5, P6, P7, P8, P9)>:public IJSCCallback {
typedef void(Cls::*F)(P1, P2, P3, P4, P5, P6, P7, P8, P9);
JSCCallback(F func):m_func(func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JS2CCALL_GET_COBJ;
JS2CCALL_GET_PARAMS9;
(pThis->*m_func)(p1, p2, p3, p4, p5, p6, p7, p8, p9);
resetJsStrBuf();
return JSValueMakeUndefined(ctx);
}
virtual uint16_t getNumArgs() { return 9; }
F m_func;
};
template< typename Cls, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9, typename P10, typename P11>//11
struct JSCCallback<void(Cls::*)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11)>:public IJSCCallback {
typedef void(Cls::*F)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11);
JSCCallback(F func):m_func(func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JS2CCALL_GET_COBJ;
JS2CCALL_GET_PARAMS11;
(pThis->*m_func)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11);
resetJsStrBuf();
return JSValueMakeUndefined(ctx);
}
virtual uint16_t getNumArgs() { return 11; }
F m_func;
};
template< typename Cls, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9, typename P10, typename P11, typename P12>//12
struct JSCCallback<void(Cls::*)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12)>:public IJSCCallback {
typedef void(Cls::*F)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12);
JSCCallback(F func):m_func(func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JS2CCALL_GET_COBJ;
JS2CCALL_GET_PARAMS12;
(pThis->*m_func)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12);
resetJsStrBuf();
return JSValueMakeUndefined(ctx);
}
virtual uint16_t getNumArgs() { return 12; }
F m_func;
};
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
#define JS2CCONSTRUCTOR_GET_PARAMS1 \
P1 p1 = __TransferToCpp<P1>::ToCpp(arguments[0]);
#define JS2CCONSTRUCTOR_GET_PARAMS2 \
P1 p1 = __TransferToCpp<P1>::ToCpp(arguments[0]);\
P2 p2 = __TransferToCpp<P2>::ToCpp(arguments[1]);
#define JS2CCONSTRUCTOR_GET_PARAMS3 \
P1 p1 = __TransferToCpp<P1>::ToCpp(arguments[0]);\
P2 p2 = __TransferToCpp<P2>::ToCpp(arguments[1]);\
P3 p3 = __TransferToCpp<P3>::ToCpp(arguments[2]);
template<typename Cls>
struct JSCConstructor0: public IJSCCallback {
virtual JSObjectRef constructor(JSContextRef ctx, JSObjectRef constructor, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
return JSCClass<Cls>::getInstance()->transferObjPtrToJS(new Cls());
}
virtual uint16_t getNumArgs() { return 0; }
};
template<typename Cls>
IJSCCallback* regConstructor(){
return new JSCConstructor0<Cls>();
}
template<typename Cls, typename P1>
struct JSCConstructor1:public IJSCCallback{
virtual JSObjectRef constructor(JSContextRef ctx, JSObjectRef constructor, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JS2CCONSTRUCTOR_GET_PARAMS1;
return JSCClass<Cls>::getInstance()->transferObjPtrToJS(new Cls(p1));
}
virtual uint16_t getNumArgs() { return 1; }
};
template<typename Cls,typename P1>
IJSCCallback* regConstructor(){
return new JSCConstructor1<Cls,P1>();
}
template<typename Cls, typename P1,typename P2>
struct JSCConstructor2:public IJSCCallback{
virtual JSObjectRef constructor(JSContextRef ctx, JSObjectRef constructor, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JS2CCONSTRUCTOR_GET_PARAMS2;
return JSCClass<Cls>::getInstance()->transferObjPtrToJS(new Cls(p1,p2));
}
virtual uint16_t getNumArgs() { return 2; }
};
template<typename Cls,typename P1,typename P2>
IJSCCallback* regConstructor(){
return new JSCConstructor2<Cls,P1,P2>();
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
struct IJSCFunction
{
virtual ~IJSCFunction(){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) = 0;
virtual uint16_t getNumArgs() = 0;
};
template<typename T>
struct JSCFunction: public IJSCFunction {
JSCFunction(T func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
assert(false && "JSCFunction::call not implemented");
return nullptr;
}
virtual uint16_t getNumArgs() { return 0; }
};
template<typename R>//R(void)
struct JSCFunction<R(*)(void)>: public IJSCFunction {
typedef R(*F)(void);
JSCFunction(F func):m_func(func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JSValueRef ret = ToJSValue<R>((*m_func)());
resetJsStrBuf();
return ret;
}
virtual uint16_t getNumArgs() { return 0; }
F m_func;
};
template<typename R, typename P1>//R(p1)
struct JSCFunction<R(*)(P1)>: public IJSCFunction {
typedef R(*F)(P1);
JSCFunction(F func):m_func(func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JS2CCALL_GET_PARAMS1;
JSValueRef ret = ToJSValue<R>((*m_func)(p1));
resetJsStrBuf();
return ret;
}
virtual uint16_t getNumArgs() { return 1; }
F m_func;
};
template<typename R, typename P1>//const R(p1)
struct JSCFunction<const R(*)(P1)>:public IJSCFunction {
typedef const R(*F)(P1);
JSCFunction(F func):m_func(func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JS2CCALL_GET_PARAMS1;
JSValueRef ret = ToJSValue<R>((*m_func)(p1));
resetJsStrBuf();
return ret;
}
virtual uint16_t getNumArgs() { return 1; }
F m_func;
};
template<typename R, typename P1, typename P2>//R(p1,p2)
struct JSCFunction<R(*)(P1, P2)>: public IJSCFunction {
typedef R(*F)(P1,P2);
JSCFunction(F func):m_func(func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JS2CCALL_GET_PARAMS2;
JSValueRef ret = ToJSValue<R>((*m_func)(p1, p2));
resetJsStrBuf();
return ret;
}
virtual uint16_t getNumArgs() { return 2; }
F m_func;
};
template<typename R, typename P1, typename P2, typename P3>//3
struct JSCFunction<R(*)(P1, P2, P3)>: public IJSCFunction {
typedef R(*F)(P1, P2, P3);
JSCFunction(F func):m_func(func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JS2CCALL_GET_PARAMS3;
JSValueRef ret = ToJSValue<R>((*m_func)(p1, p2, p3));
resetJsStrBuf();
return ret;
}
virtual uint16_t getNumArgs() { return 3; }
F m_func;
};
template<typename R, typename P1, typename P2, typename P3, typename P4>//4
struct JSCFunction<R(*)(P1, P2, P3, P4)>: public IJSCFunction {
typedef R(*F)(P1, P2, P3, P4);
JSCFunction(F func):m_func(func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JS2CCALL_GET_PARAMS4;
JSValueRef ret = ToJSValue<R>((*m_func)(p1, p2, p3, p4));
resetJsStrBuf();
return ret;
}
virtual uint16_t getNumArgs() { return 4; }
F m_func;
};
template<typename R, typename P1, typename P2, typename P3, typename P4, typename P5>//5
struct JSCFunction<R(*)(P1, P2, P3, P4, P5)>: public IJSCFunction {
typedef R(*F)(P1, P2, P3, P4, P5);
JSCFunction(F func):m_func(func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JS2CCALL_GET_PARAMS5;
JSValueRef ret = ToJSValue<R>((*m_func)(p1, p2, p3, p4, p5));
resetJsStrBuf();
return ret;
}
virtual uint16_t getNumArgs() { return 5; }
F m_func;
};
template<typename R, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6>//6
struct JSCFunction<R(*)(P1, P2, P3, P4, P5, P6)>: public IJSCFunction {
typedef R(*F)(P1, P2, P3, P4, P5, P6);
JSCFunction(F func):m_func(func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JS2CCALL_GET_PARAMS6;
JSValueRef ret = ToJSValue<R>((*m_func)(p1, p2, p3, p4, p5, p6));
resetJsStrBuf();
return ret;
}
virtual uint16_t getNumArgs() { return 6; }
F m_func;
};
template<typename R, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7>//7
struct JSCFunction<R(*)(P1, P2, P3, P4, P5, P6, P7)>: public IJSCFunction {
typedef R(*F)(P1, P2, P3, P4, P5, P6, P7);
JSCFunction(F func):m_func(func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JS2CCALL_GET_PARAMS7;
JSValueRef ret = ToJSValue<R>((*m_func)(p1, p2, p3, p4, p5, p6, p7));
resetJsStrBuf();
return ret;
}
virtual uint16_t getNumArgs() { return 7; }
F m_func;
};
template<typename R, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8>//8
struct JSCFunction<R(*)(P1, P2, P3, P4, P5, P6, P7, P8)>: public IJSCFunction {
typedef R(*F)(P1, P2, P3, P4, P5, P6, P7, P8);
JSCFunction(F func):m_func(func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JS2CCALL_GET_PARAMS8;
JSValueRef ret = ToJSValue<R>((*m_func)(p1, p2, p3, p4, p5, p6, p7, p8));
resetJsStrBuf();
return ret;
}
virtual uint16_t getNumArgs() { return 8; }
F m_func;
};
template<typename R, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9>//9
struct JSCFunction<R(*)(P1, P2, P3, P4, P5, P6, P7, P8, P9)>: public IJSCFunction {
typedef R(*F)(P1, P2, P3, P4, P5, P6, P7, P8, P9);
JSCFunction(F func):m_func(func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JS2CCALL_GET_PARAMS9;
JSValueRef ret = ToJSValue<R>((*m_func)(p1, p2, p3, p4, p5, p6, p7, p8, p9));
resetJsStrBuf();
return ret;
}
virtual uint16_t getNumArgs() { return 9; }
F m_func;
};
//void
template<> //void(void)
struct JSCFunction<void(*)(void)>: public IJSCFunction {
typedef void(*F)(void);
JSCFunction(F func):m_func(func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
(*m_func)();
resetJsStrBuf();
return JSValueMakeUndefined(ctx);
}
virtual uint16_t getNumArgs() { return 0; }
F m_func;
};
template<typename P1>
struct JSCFunction<void(*)(P1)>: public IJSCFunction {//void(p1)
typedef void(*F)(P1);
JSCFunction(F func):m_func(func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JS2CCALL_GET_PARAMS1;
(*m_func)(p1);
resetJsStrBuf();
return JSValueMakeUndefined(ctx);
}
virtual uint16_t getNumArgs() { return 1; }
F m_func;
};
template<typename P1, typename P2>//void(p1,p2)
struct JSCFunction<void(*)(P1, P2)>: public IJSCFunction {
typedef void(*F)(P1, P2);
JSCFunction(F func):m_func(func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JS2CCALL_GET_PARAMS2;
(*m_func)(p1, p2);
resetJsStrBuf();
return JSValueMakeUndefined(ctx);
}
virtual uint16_t getNumArgs() { return 2; }
F m_func;
};
template< typename P1, typename P2, typename P3>//3
struct JSCFunction<void(*)(P1, P2, P3)>: public IJSCFunction {
typedef void(*F)(P1, P2, P3);
JSCFunction(F func):m_func(func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JS2CCALL_GET_PARAMS3;
(*m_func)(p1, p2, p3);
resetJsStrBuf();
return JSValueMakeUndefined(ctx);
}
virtual uint16_t getNumArgs() { return 3; }
F m_func;
};
template<typename P1, typename P2, typename P3, typename P4>//4
struct JSCFunction<void(*)(P1, P2, P3, P4)>: public IJSCFunction {
typedef void(*F)(P1, P2, P3, P4);
JSCFunction(F func):m_func(func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JS2CCALL_GET_PARAMS4;
(*m_func)(p1, p2, p3, p4);
resetJsStrBuf();
return JSValueMakeUndefined(ctx);
}
virtual uint16_t getNumArgs() { return 4; }
F m_func;
};
template<typename P1, typename P2, typename P3, typename P4, typename P5>//5
struct JSCFunction<void(*)(P1, P2, P3, P4, P5)>: public IJSCFunction {
typedef void(*F)(P1, P2, P3, P4, P5);
JSCFunction(F func):m_func(func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JS2CCALL_GET_PARAMS5;
(*m_func)(p1, p2, p3, p4, p5);
resetJsStrBuf();
return JSValueMakeUndefined(ctx);
}
virtual uint16_t getNumArgs() { return 5; }
F m_func;
};
template<typename P1, typename P2, typename P3, typename P4, typename P5, typename P6>//6
struct JSCFunction<void(*)(P1, P2, P3, P4, P5, P6)>: public IJSCFunction {
typedef void(*F)(P1, P2, P3, P4, P5, P6);
JSCFunction(F func):m_func(func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JS2CCALL_GET_PARAMS6;
(*m_func)(p1, p2, p3, p4, p5, p6);
resetJsStrBuf();
return JSValueMakeUndefined(ctx);
}
virtual uint16_t getNumArgs() { return 6; }
F m_func;
};
template< typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7>//7
struct JSCFunction<void(*)(P1, P2, P3, P4, P5, P6, P7)>: public IJSCFunction {
typedef void(*F)(P1, P2, P3, P4, P5, P6, P7);
JSCFunction(F func):m_func(func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JS2CCALL_GET_PARAMS7;
(*m_func)(p1, p2, p3, p4, p5, p6, p7);
resetJsStrBuf();
return JSValueMakeUndefined(ctx);
}
virtual uint16_t getNumArgs() { return 7; }
F m_func;
};
template<typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8>//8
struct JSCFunction<void(*)(P1, P2, P3, P4, P5, P6, P7, P8)>: public IJSCFunction {
typedef void(*F)(P1, P2, P3, P4, P5, P6, P7, P8);
JSCFunction(F func):m_func(func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JS2CCALL_GET_PARAMS8;
(*m_func)(p1, p2, p3, p4, p5, p6, p7, p8);
resetJsStrBuf();
return JSValueMakeUndefined(ctx);
}
virtual uint16_t getNumArgs() { return 8; }
F m_func;
};
template<typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9>//9
struct JSCFunction<void(*)(P1, P2, P3, P4, P5, P6, P7, P8, P9)>: public IJSCFunction {
typedef void(*F)(P1, P2, P3, P4, P5, P6, P7, P8, P9);
JSCFunction(F func):m_func(func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JS2CCALL_GET_PARAMS9;
(*m_func)(p1, p2, p3, p4, p5, p6, p7, p8, p9);
resetJsStrBuf();
return JSValueMakeUndefined(ctx);
}
virtual uint16_t getNumArgs() { return 9; }
F m_func;
};
template<typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9, typename P10, typename P11, typename P12>//12
struct JSCFunction<void(*)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12)>: public IJSCFunction {
typedef void(*F)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12);
JSCFunction(F func):m_func(func){}
virtual JSValueRef call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){
JS2CCALL_GET_PARAMS12;
(*m_func)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12);
resetJsStrBuf();
return JSValueMakeUndefined(ctx);
}
virtual uint16_t getNumArgs() { return 12; }
F m_func;
};
} // namespace __JSCProxy
#endif
@@ -0,0 +1,172 @@
#ifndef _JSCProxyTLS_h
#define _JSCProxyTLS_h
#include <JavaScriptCore/JSContextRef.h>
#include <JavaScriptCore/JSStringRef.h>
#include <JavaScriptCore/JSValueRef.h>
#include "../../../CToObjectC.h"
#include <util/JCCommonMethod.h>
#include <util/Log.h>
#include <pthread.h>
namespace laya
{
class __TlsData
{
__TlsData(){}
~__TlsData(){}
public:
static pthread_key_t s_tls_curThread;
static __TlsData *GetInstance()
{
static __TlsData _Ins;
return &_Ins;
}
void *SetCurContext( JSContextRef p_pContext )
{
void *pRet = (void *)pthread_getspecific(s_tls_curThread);
pthread_setspecific(s_tls_curThread,(void*)p_pContext);
return pRet;
}
JSContextRef GetCurContext()
{
return (JSContextRef)pthread_getspecific(s_tls_curThread);
}
};
class __JsThrow
{
JSValueRef *m_pException;
public:
__JsThrow()
{
m_pException = 0;
}
static __JsThrow *GetInstance()
{
static __JsThrow _Ins;
return &_Ins;
}
static void Throw( JSValueRef* exception, const char *p_pszInfo=0 )
{
if( 0 != exception )
{
JSStringRef message = JSStringCreateWithUTF8CString((0==p_pszInfo)?"unknown error":p_pszInfo);
*exception = JSValueMakeString(__TlsData::GetInstance()->GetCurContext(), message);
JSStringRelease(message);
}
}
void UpdateException( JSValueRef* exception )
{
m_pException = exception;
}
void RuntimeThrow( const char *p_pszInfo )
{
__JsThrow::Throw(m_pException,p_pszInfo);
}
};
extern bool gbAlertException;
class __JSRun
{
static char *__ToCppString( JSValueRef p_vl, JSContextRef p_pContext )
{
char *pRet = 0;
JSStringRef _jsStr = JSValueToStringCopy(p_pContext, p_vl, 0);
if( _jsStr )
{
size_t iSize = JSStringGetMaximumUTF8CStringSize(_jsStr);
if(iSize>0)
{
pRet=new char[iSize+1];
JSStringGetUTF8CString( _jsStr, pRet, iSize+1 );
}
JSStringRelease( _jsStr );
}
return pRet;
}
public:
static void OutputException( JSValueRef exception )
{
if( NULL != exception )
{
JSContextRef pContext = __TlsData::GetInstance()->GetCurContext();
JSStringRef jsLinePropertyName = JSStringCreateWithUTF8CString("line");
JSStringRef jsColumnPropertyName = JSStringCreateWithUTF8CString("column");
JSStringRef jsUrlPropertyName = JSStringCreateWithUTF8CString("sourceURL");
JSObjectRef exObject = JSValueToObject( pContext, exception, NULL );
JSValueRef line = JSObjectGetProperty( pContext, exObject, jsLinePropertyName, NULL );
JSValueRef column = JSObjectGetProperty( pContext, exObject, jsColumnPropertyName, NULL );
JSValueRef url = JSObjectGetProperty( pContext, exObject, jsUrlPropertyName, NULL );
char *pEx = __ToCppString(exception,pContext);
char *pLine = __ToCppString(line,pContext);
char *pColumn = __ToCppString(column,pContext);
char *pUrl = __ToCppString(url,pContext);
//通知全局错误处理脚本
std::string kBuf = "if(conch.onerror){conch.onerror('";
kBuf += UrlEncode(pEx);
kBuf += "','undefined','";
kBuf += UrlEncode(pLine);
kBuf += "','";
kBuf += UrlEncode(pColumn);
kBuf += "','";
kBuf += UrlEncode(pEx);
kBuf += "');};";
__JSRun::Run(kBuf.c_str());
static char sBuffer[10240]={0};
sprintf( sBuffer,"exception info: [%s] at line %s\n", pEx, pLine );
if (gbAlertException)
CToObjectCAlert( sBuffer );
else {
LOGE("==JSERROR:\n%s", sBuffer);
}
delete[] pEx;
delete[] pLine;
delete[] pColumn;
delete[] pUrl;
JSStringRelease(jsLinePropertyName);
JSStringRelease(jsColumnPropertyName);
JSStringRelease(jsUrlPropertyName);
}
}
static bool Run( const char *p_pszScript,JSValueRef* result = NULL )
{
bool bRet = true;
JSContextRef pContext = __TlsData::GetInstance()->GetCurContext();
JSStringRef pScript = JSStringCreateWithUTF8CString( p_pszScript );
JSValueRef exception = NULL;
JSValueRef ret = JSEvaluateScript(pContext, pScript, NULL, NULL, 0, &exception );
if( 0 != exception )
{
OutputException( exception );
bRet = false;
}
if( ret != NULL && result != NULL ){
*result = ret;
}
JSStringRelease( pScript );
return bRet;
}
};
}
#endif
@@ -0,0 +1,443 @@
#ifndef _JSCProxyTrnasfer_h
#define _JSCProxyTrnasfer_h
#include <JavaScriptCore/JSContextRef.h>
#include <JavaScriptCore/JSStringRef.h>
#include <JavaScriptCore/JSValueRef.h>
#include <string>
#include <vector>
#include "JSCProxyTLS.h"
#include "JSCProxyType.h"
namespace laya
{
void resetJsStrBuf();
template <typename T>class JSCClass;
template <typename T> class __TransferToCpp
{
public:
static T ToCpp( JSValueRef p_vl ){
assert(false && "type not supported!");
}
static bool is( JSValueRef p_vl ){
return __CheckClassType::IsTypeOf<T>(p_vl);
}
};
template <typename T> class __TransferToCpp<T*>
{
public:
static T* ToCpp( JSValueRef p_vl ){
JSContextRef pCtx = __TlsData::GetInstance()->GetCurContext();
if( 0 == p_vl || JSValueIsUndefined(pCtx, p_vl) || JSValueIsNull(pCtx, p_vl) )
return nullptr;
else
return (T*)JSObjectGetPrivate((JSObjectRef)p_vl);
}
static bool is( JSValueRef p_vl ){
return __CheckClassType::IsTypeOf<T>(p_vl);
}
};
template <> class __TransferToCpp<int>
{
public:
static int ToCpp( JSValueRef p_vl ){
JSContextRef pCtx = __TlsData::GetInstance()->GetCurContext();
if(0!=p_vl)
return (int)JSValueToNumber(pCtx,p_vl,0);
else return 0;
}
static bool is( JSValueRef p_vl ){
JSContextRef pCtx = __TlsData::GetInstance()->GetCurContext();
return JSValueIsNumber(pCtx, p_vl);
}
};
template <> class __TransferToCpp<short>
{
public:
static int ToCpp( JSValueRef p_vl ){
JSContextRef pCtx = __TlsData::GetInstance()->GetCurContext();
if(0!=p_vl)
return (short)JSValueToNumber(pCtx,p_vl,0);
else return 0;
}
static bool is( JSValueRef p_vl ){
JSContextRef pCtx = __TlsData::GetInstance()->GetCurContext();
return JSValueIsNumber(pCtx, p_vl);
}
};
template <> class __TransferToCpp<unsigned int>
{
public:
static unsigned int ToCpp( JSValueRef p_vl ){
JSContextRef pCtx=__TlsData::GetInstance()->GetCurContext();
if(0!=p_vl)
return (unsigned int)JSValueToNumber(pCtx,p_vl,0);
else
return 0;
}
static bool is( JSValueRef p_vl ){
JSContextRef pCtx = __TlsData::GetInstance()->GetCurContext();
return JSValueIsNumber(pCtx, p_vl);
}
};
template <> class __TransferToCpp<long>
{
public:
static long ToCpp( JSValueRef p_vl ){
JSContextRef pCtx=__TlsData::GetInstance()->GetCurContext();
if(0!=p_vl)
return (long)JSValueToNumber(pCtx,p_vl,0);
else
return 0;
}
static bool is( JSValueRef p_vl ){
JSContextRef pCtx = __TlsData::GetInstance()->GetCurContext();
return JSValueIsNumber(pCtx, p_vl);
}
};
template <> class __TransferToCpp<unsigned long>
{
public:
static unsigned long ToCpp( JSValueRef p_vl ){
JSContextRef pCtx=__TlsData::GetInstance()->GetCurContext();
if(0!=p_vl)
return (unsigned long)JSValueToNumber(pCtx,p_vl,0);
else
return 0;
}
static bool is( JSValueRef p_vl ){
JSContextRef pCtx = __TlsData::GetInstance()->GetCurContext();
return JSValueIsNumber(pCtx, p_vl);
}
};
template <> class __TransferToCpp<bool>
{
public:
static bool ToCpp( JSValueRef p_vl ){
JSContextRef pCtx=__TlsData::GetInstance()->GetCurContext();
if(0!=p_vl)
return JSValueToBoolean(pCtx,p_vl);
else
return false;
}
static bool is( JSValueRef p_vl ){
JSContextRef pCtx = __TlsData::GetInstance()->GetCurContext();
return JSValueIsBoolean(pCtx, p_vl);
}
};
template <> class __TransferToCpp<float>
{
public:
static float ToCpp( JSValueRef p_vl ){
JSContextRef pCtx=__TlsData::GetInstance()->GetCurContext();
if(0!=p_vl)
return (float)JSValueToNumber(pCtx,p_vl,0);
else
return 0;
}
static bool is( JSValueRef p_vl ){
JSContextRef pCtx = __TlsData::GetInstance()->GetCurContext();
return JSValueIsNumber(pCtx, p_vl);
}
};
template <> class __TransferToCpp<double>
{
public:
static double ToCpp( JSValueRef p_vl ){
JSContextRef pCtx=__TlsData::GetInstance()->GetCurContext();
if(0!=p_vl)
return JSValueToNumber(pCtx,p_vl,0);
else
return 0;
}
static bool is( JSValueRef p_vl ){
JSContextRef pCtx = __TlsData::GetInstance()->GetCurContext();
return JSValueIsNumber(pCtx, p_vl);
}
};
template <> class __TransferToCpp<long long>
{
public:
static long long ToCpp( JSValueRef p_vl ){
JSContextRef pCtx=__TlsData::GetInstance()->GetCurContext();
if(0!=p_vl)
return (long long)JSValueToNumber(pCtx,p_vl,0);
else
return 0;
}
static bool is( JSValueRef p_vl ){
JSContextRef pCtx = __TlsData::GetInstance()->GetCurContext();
return JSValueIsNumber(pCtx, p_vl);
}
};
template <> class __TransferToCpp<unsigned long long>
{
public:
static unsigned long long ToCpp( JSValueRef p_vl ){
JSContextRef pCtx=__TlsData::GetInstance()->GetCurContext();
if(0!=p_vl)return (unsigned long long)JSValueToNumber(pCtx,p_vl,0);
else return 0;
}
static bool is( JSValueRef p_vl ){
JSContextRef pCtx = __TlsData::GetInstance()->GetCurContext();
return JSValueIsNumber(pCtx, p_vl);
}
};
template <> class __TransferToCpp<JSValueRef>
{
public:
static JSValueRef ToCpp( JSValueRef p_vl ){
return p_vl;
}
static bool is( JSValueRef p_vl ){
return true;
}
};
char* JsCharToC(JSValueRef p_vl);
char* JsCharToC(JSStringRef p_vl);
#define __DeclareStringTransferToCpp(Tp) \
template <> class __TransferToCpp<Tp> \
{ \
public: \
static char *ToCpp( JSValueRef p_vl ) \
{ \
return JsCharToC(p_vl); \
} \
static char *ToCpp( JSStringRef p_vl ) \
{ \
return JsCharToC(p_vl); \
} \
static std::string ToCppStd( JSValueRef p_vl ) \
{ \
return JsCharToC(p_vl); \
} \
static std::string ToCppStd( JSStringRef p_vl ) \
{ \
return JsCharToC(p_vl); \
} \
static bool is( JSValueRef p_vl ){ \
JSContextRef pCtx = __TlsData::GetInstance()->GetCurContext(); \
return JSValueIsString(pCtx, p_vl); \
} \
};
__DeclareStringTransferToCpp(char *);
__DeclareStringTransferToCpp(const char *);
__DeclareStringTransferToCpp(unsigned char *);
__DeclareStringTransferToCpp(const unsigned char *);
template <typename T> class __TransferToJs
{
public:
static JSValueRef ToJs( T *p_vl ){
return JSCClass<T>::getInstance()->transferObjPtrToJS(p_vl);
}
};
template <> class __TransferToJs<void>
{public:static JSValueRef ToJs( int p_vl )
{
JSContextRef pCtx=__TlsData::GetInstance()->GetCurContext();
if(0==p_vl)
return JSValueMakeUndefined(pCtx);
else
return JSValueMakeNull(pCtx);
}};
template <> class __TransferToJs<JSValueRef>
{public:static JSValueRef ToJs( JSValueRef p_vl ){return p_vl;}};
template <> class __TransferToJs<bool>
{public:static JSValueRef ToJs( bool p_vl ){return JSValueMakeBoolean(__TlsData::GetInstance()->GetCurContext(),p_vl);}};
template <> class __TransferToJs<int>
{public:static JSValueRef ToJs( int p_vl ){return JSValueMakeNumber(__TlsData::GetInstance()->GetCurContext(),(double)p_vl);}};
template <> class __TransferToJs<unsigned int>
{public:static JSValueRef ToJs( unsigned int p_vl ){return JSValueMakeNumber(__TlsData::GetInstance()->GetCurContext(),(double)p_vl);}};
template <> class __TransferToJs<float>
{public:static JSValueRef ToJs( float p_vl ){return JSValueMakeNumber(__TlsData::GetInstance()->GetCurContext(),(double)p_vl);}};
template <> class __TransferToJs<double>
{public:static JSValueRef ToJs( double p_vl ){return JSValueMakeNumber(__TlsData::GetInstance()->GetCurContext(),p_vl);}};
template <> class __TransferToJs<long long>
{
public:
static JSValueRef ToJs( long long p_vl ){return JSValueMakeNumber(__TlsData::GetInstance()->GetCurContext(),(double)p_vl);}
static JSValueRef ToJsDate( long long p_vl )
{
JSValueRef n = ToJs(p_vl);
return JSObjectMakeDate(__TlsData::GetInstance()->GetCurContext(), 1, &n, 0);
}
};
template <> class __TransferToJs<long>
{
public:
static JSValueRef ToJs( long p_vl ){return JSValueMakeNumber(__TlsData::GetInstance()->GetCurContext(),(double)p_vl);}
static JSValueRef ToJsDate( long p_vl )
{
JSValueRef n = ToJs(p_vl);
return JSObjectMakeDate(__TlsData::GetInstance()->GetCurContext(), 1, &n, 0);
}
};
template <> class __TransferToJs<unsigned long long>
{
public:
static JSValueRef ToJs( unsigned long long p_vl ){return JSValueMakeNumber(__TlsData::GetInstance()->GetCurContext(),(double)p_vl);}
static JSValueRef ToJsDate( unsigned long long p_vl )
{
JSValueRef n = ToJs(p_vl);
return JSObjectMakeDate(__TlsData::GetInstance()->GetCurContext(), 1, &n, 0);
}
};
template <> class __TransferToJs<char *>
{public:static JSValueRef ToJs( char *p_vl )
{
JSStringRef pStr = JSStringCreateWithUTF8CString(p_vl);
JSValueRef pRet = JSValueMakeString(__TlsData::GetInstance()->GetCurContext(), pStr);
JSStringRelease(pStr);
return pRet;
}};
template <> class __TransferToJs<const char *>
{public:static JSValueRef ToJs( const char *p_vl )
{
JSStringRef pStr = JSStringCreateWithUTF8CString(p_vl);
JSValueRef pRet = JSValueMakeString(__TlsData::GetInstance()->GetCurContext(), pStr);
JSStringRelease(pStr);
return pRet;
}};
template <> class __TransferToJs<unsigned char *>
{public:static JSValueRef ToJs( unsigned char *p_vl )
{
JSStringRef pStr = JSStringCreateWithUTF8CString((char *)p_vl);
JSValueRef pRet = JSValueMakeString(__TlsData::GetInstance()->GetCurContext(), pStr);
JSStringRelease(pStr);
return pRet;
}};
template <> class __TransferToJs<const unsigned char *>
{public:static JSValueRef ToJs( const unsigned char *p_vl )
{
JSStringRef pStr = JSStringCreateWithUTF8CString((char *)p_vl);
JSValueRef pRet = JSValueMakeString(__TlsData::GetInstance()->GetCurContext(), pStr);
JSStringRelease(pStr);
return pRet;
}};
template <> class __TransferToJs<std::string>
{public:static JSValueRef ToJs( std::string p_vl )
{
JSStringRef pStr = JSStringCreateWithUTF8CString(p_vl.c_str());
JSValueRef pRet = JSValueMakeString(__TlsData::GetInstance()->GetCurContext(), pStr);
JSStringRelease(pStr);
return pRet;
}};
template <typename T> class __JsArray{
public:
static JSObjectRef ToJsArray(const std::vector<T*>& p_vl)
{
int p_iSize = p_vl.size();
JSValueRef pValArray[p_iSize];
for(int i=0;i<p_iSize;++i)
{
pValArray[i] = __TransferToJs<T>::ToJs(p_vl[i]);
}
JSObjectRef pRet = JSObjectMakeArray( __TlsData::GetInstance()->GetCurContext(), p_iSize, pValArray, 0 );
return pRet;
}
static JSObjectRef ToJsArray(const std::vector<T>& p_vl)
{
int p_iSize = p_vl.size();
JSValueRef pValArray[p_iSize];
for(int i=0;i<p_iSize;++i)
{
pValArray[i] = __TransferToJs<T>::ToJs(p_vl[i]);
}
JSObjectRef pRet = JSObjectMakeArray( __TlsData::GetInstance()->GetCurContext(), p_iSize, pValArray, 0 );
return pRet;
}
};
class __JsByteArray
{
public:
static JSObjectRef ToJsByteArray( const unsigned char *p_vl, int p_iSize )
{
if( 0 == p_vl || p_iSize <= 0 )
{
return NULL;
}
else
{
JSValueRef pValArray[p_iSize];
for(int i=0;i<p_iSize;++i)
{
pValArray[i] = __TransferToJs<unsigned int>::ToJs(p_vl[i]);
}
JSObjectRef pRet = JSObjectMakeArray( __TlsData::GetInstance()->GetCurContext(), p_iSize, pValArray, 0 );
return pRet;
}
}
};
template <typename T> class __TransferToJs<std::vector<T*> >
{
public:static JSObjectRef ToJs( const std::vector<T*>& p_vl )
{
return __JsArray<T>::ToJsArray(p_vl);
}
};
template <typename T> class __TransferToJs<std::vector<T> >
{
public:static JSObjectRef ToJs(const std::vector<T>& p_vl)
{
return __JsArray<T>::ToJsArray(p_vl);
}
};
}
#endif
@@ -0,0 +1,121 @@
#ifndef __JSCProxyType_h
#define __JSCProxyType_h
#define NDEBUG
#include <assert.h>
#include "JSCProxyTLS.h"
#define __Js_class_typeid_property "__cppclstypeid"
namespace laya
{
typedef enum
{
__VT_void = 0,
__VT_string,
__VT_bool,
__VT_int,
__VT_long,
__VT_float,
__VT_double,
__VT_longlong,
__VT_ArrayBuffer,
__VT_object,
} __ValueType;
template <class _Key> struct __InferType
{__ValueType iType;__InferType(){iType=__VT_object;}};
template<> struct __InferType<void>
{__ValueType iType;__InferType(){iType=__VT_void;}};
template<> struct __InferType<bool>
{__ValueType iType;__InferType(){iType=__VT_bool;}};
template<> struct __InferType<char *>
{__ValueType iType;__InferType(){iType=__VT_string;}};
template<> struct __InferType<const char *>
{__ValueType iType;__InferType(){iType=__VT_string;}};
template<> struct __InferType<unsigned char *>
{__ValueType iType;__InferType(){iType=__VT_string;}};
template<> struct __InferType<const unsigned char *>
{__ValueType iType;__InferType(){iType=__VT_string;}};
template<> struct __InferType<int>
{__ValueType iType;__InferType(){iType=__VT_int;}};
template<> struct __InferType<unsigned int>
{__ValueType iType;__InferType(){iType=__VT_int;}};
template<> struct __InferType<long>
{__ValueType iType;__InferType(){iType=__VT_long;}};
template<> struct __InferType<unsigned long>
{__ValueType iType;__InferType(){iType=__VT_long;}};
template<> struct __InferType<float>
{__ValueType iType;__InferType(){iType=__VT_float;}};
template<> struct __InferType<double>
{__ValueType iType;__InferType(){iType=__VT_double;}};
template<> struct __InferType<long long>
{__ValueType iType;__InferType(){iType=__VT_longlong;}};
template<> struct __InferType<unsigned long long>
{__ValueType iType;__InferType(){iType=__VT_longlong;}};
template<typename T>
class JSCClass;
class __CheckClassType
{
public:
template <typename T>
static bool IsTypeOf( JSObjectRef p_pObj )
{
if( 0 == p_pObj )
return false;
JSStringRef pszName = JSStringCreateWithUTF8CString(__Js_class_typeid_property);
JSValueRef pProperty = JSObjectGetProperty(__TlsData::GetInstance()->GetCurContext(), p_pObj, pszName, 0);
JSStringRelease(pszName);
if( 0 == pProperty )
{
return false;
}
else
{
JSContextRef pCtx = __TlsData::GetInstance()->GetCurContext();
int nID = (int)JSValueToNumber(pCtx,pProperty,0);
return (nID == (JSCClass<T>::getInstance()->getTypeID()));
}
}
template <typename T>
static bool IsTypeOf( JSValueRef p_pVal )
{
if( 0 == p_pVal )
return false;
JSContextRef pCtx = __TlsData::GetInstance()->GetCurContext();
if( !JSValueIsObject(pCtx, p_pVal) )
{
return false;
}
return IsTypeOf<T>((JSObjectRef)p_pVal);
}
};
} // namespace __JSCProxy
#endif
@@ -0,0 +1,55 @@
/**
@file JSInterface.cpp
@brief
@author wyw
@version 1.0
@date 2014_7_29
*/
#include "JSInterface.h"
#ifdef JS_JSC
//#include <JavaScriptCore/JSBasePrivate.h>
#endif
namespace laya
{
void AdjustAmountOfExternalAllocatedMemory(int p_nMemorySize)
{
#ifdef JS_V8
v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(p_nMemorySize);
#elif JS_JSC
//JSReportExtraMemoryCost(__TlsData::GetInstance()->GetCurContext(), p_nMemorySize);
#endif
}
JsValue getNativeObj(JSValueAsParam p_pJsObj, char* p_strName)
{
#ifdef JS_V8
if (p_pJsObj->IsObject()) {
v8::Local<v8::Object> pobj = v8::Local<v8::Object>::Cast(p_pJsObj);
JsValue nativeObj = pobj->Get(JSP_TO_JS(char*, p_strName));
if (!nativeObj.IsEmpty() && nativeObj->IsObject()) {
return nativeObj;
}
}
return p_pJsObj;
#elif JS_JSC
JSContextRef ctx = __TlsData::GetInstance()->GetCurContext();
if (JSValueIsObject(ctx, p_pJsObj)) {
JSObjectRef obj = JSValueToObject(ctx, p_pJsObj, nullptr);
if (obj != nullptr) {
JSStringRef name = JSStringCreateWithUTF8CString(p_strName);
JSValueRef ret = JSObjectGetProperty(ctx, obj, name, nullptr);
JSStringRelease(name);
if (!JSValueIsNull(ctx, ret) && !JSValueIsUndefined(ctx, ret)) {
return ret;
}
}
}
return p_pJsObj;
#endif
}
}
//-----------------------------END FILE--------------------------------
@@ -0,0 +1,76 @@
/**
@file JSInterface.h
@brief
@author wyw
@version 1.0
@date 2013_12_2
*/
#ifndef __JSInterface_H__
#define __JSInterface_H__
#include <JSObjBase.h>
#include <util/JCMemorySurvey.h>
#ifdef JS_JSC
#include "JSC/JSCBinder.h"
#include "JSC/JSCEnv.h"
#include "JSC/JSCArrayBuffer.h"
#elif JS_V8
#include <v8.h>
#include "V8/JSEnv.h"
#include "V8/JSArrayBuffer.h"
#include "V8/JsBinder.h"
#endif
namespace laya
{
#ifdef JS_JSC
struct JsFuncArgs {};
typedef JSValueRef JSValueAsParam;
typedef JSValueRef JsValue;
typedef JsObjHandleJSC JsObjHandle;
#define JSP_RESET_GLOBAL_FUNCTION JSCGlobal::getInstance()->reset()
#define JS_TO_CPP(tp,v) laya::__TransferToCpp<tp>::ToCpp(v)
#define JSP_TO_JS_BYTE_ARRAY(vl,sz) (laya::__JsByteArray::ToJsByteArray(vl,sz))
#define JSP_TO_JS(tp,v) (laya::__TransferToJs<tp>::ToJs(v))
#define JSP_TO_JS_NULL JSP_TO_JS(void,1)
#define JSP_TO_JS_UNDEFINE JSP_TO_JS(void,0)
#define JSP_THROW(str) (laya::__JsThrow::GetInstance()->RuntimeThrow(str))
#define JSP_RUN_SCRIPT(script) (laya::__JSRun::Run(script))
#define JSP_TO_JS_STR(str) (laya::__TransferToJs<const char*>::ToJs(str))
class JsObjBase : public JSObjBaseJSC {};
#define JS_TRY
#define JS_CATCH
#elif JS_V8
class JsObjBase :public JSObjBaseV8
{
};
#define JSValueAsParam JsValue
typedef JsObjHandle2 JsObjHandle;
#define JSP_THROW(str) __JsThrow:: Throw(str);
#define JSP_RUN_SCRIPT(script) __JSRun::Run(script);
#define JSP_TO_JS_NULL ((v8::Null(v8::Isolate::GetCurrent())))
#define JSP_TO_JS_UNDEFINE ((v8::Undefined(v8::Isolate::GetCurrent())))
#include "V8/JSCProxyTrnasfer.h"
#define JSP_TO_JS_BYTE_ARRAY(vl,sz) (__JsByteArray::ToJsByteArray(vl,sz))
#define JSP_TO_JS(tp,v) (__TransferToJs<tp>::ToJs(v))
#define JS_TO_CPP(tp,v) (__TransferToCpp<tp>::ToCpp(v))
#define JSP_TO_JS_STR(str) (v8::String::NewFromUtf8(v8::Isolate::GetCurrent(),str))
#define JS_TRY \
v8::Isolate* isolate = v8::Isolate::GetCurrent();\
v8::HandleScope handle_scope(isolate);\
v8::TryCatch try_catch(isolate);
#define JS_CATCH \
if (try_catch.HasCaught()){\
LOGE("JS onFrame error\n");\
__JSRun::ReportException(isolate, &try_catch);\
}
#endif
void AdjustAmountOfExternalAllocatedMemory(int p_nMemorySize);
JsValue getNativeObj(JSValueAsParam p_pJsObj, char* p_strName);
}
#endif //__JSInterface_H__
//-----------------------------END FILE--------------------------------
@@ -0,0 +1,264 @@
#ifdef JS_V8
#include "JSArrayBuffer.h"
#include <util/JCMemorySurvey.h>
#include <util/Log.h>
#include "../JSInterface.h"
#include "JSCProxyTrnasfer.h"
namespace laya {
//TODO 这里没有考虑多线程的问题,如果js要支持多线程的话,需要修改。
struct JsStrBuff {
char* _buff;
int _len;
static std::vector<JsStrBuff> jsstrbuffs;
static int curIdx;
JsStrBuff() {
_buff = NULL;
_len = 0;
}
static JsStrBuff& getAData() {
if (JsStrBuff::curIdx >= (int)JsStrBuff::jsstrbuffs.size()) {
JsStrBuff::jsstrbuffs.push_back(JsStrBuff());
JsStrBuff::curIdx++;
return JsStrBuff::jsstrbuffs.back();
}
else {
return JsStrBuff::jsstrbuffs[JsStrBuff::curIdx++];
}
}
};
std::vector<JsStrBuff> JsStrBuff::jsstrbuffs;
int JsStrBuff::curIdx = 0;
//
void resetJsStrBuf() {
JsStrBuff::curIdx = 0;
}
char* JsCharToC(Local<Value> p_vl) {
int len = 0;
Local<String> str = p_vl->ToString();
len = str->Utf8Length();
if (len <= 0)
return "";
JsStrBuff& curdata = JsStrBuff::getAData();
char*& tocharBuf = curdata._buff;
int& tocharBufLen = curdata._len;
//tocharBuf= new char[len + 1];
if (len > tocharBufLen) {
tocharBufLen = len;
if (tocharBuf != NULL)
delete[] tocharBuf;
tocharBuf = new char[len+1];
}
else {
//如果占用空间太大,也要重新分配
if (tocharBufLen > 1024 ) {
tocharBufLen = len;
if (tocharBuf != NULL)
delete[] tocharBuf;
tocharBuf = new char[len+1];
}
}
str->WriteUtf8(tocharBuf);
return tocharBuf;
}
}
namespace laya{
ArrayBufferAllocator::ArrayBufferAllocator() {
}
ArrayBufferAllocator::~ArrayBufferAllocator() {
}
void* ArrayBufferAllocator::Allocate(size_t length) {
char* pRet = new char[length];
memset(pRet,0,length);
return pRet;
}
void* ArrayBufferAllocator::AllocateUninitialized(size_t length){
char* pRet = new char[length];
return pRet;
};
void ArrayBufferAllocator::Free(void* data, size_t length)
{
if (data != NULL || length > 0)
{
delete[]((char*)data);
}
else
{
LOGI("ArrayBufferAllocator::Free data=%d length=%d",(intptr_t)data, length);
}
}
ArrayBufferAllocator* ArrayBufferAllocator::getInstance(){
return new ArrayBufferAllocator();
}
v8::Local<v8::ArrayBuffer> createJSAB(char* pData, int len) {
v8::Local<v8::ArrayBuffer> ab = v8::ArrayBuffer::New(v8::Isolate::GetCurrent(), len);
v8::ArrayBuffer::Contents contents = ab->GetContents();// ab->Externalize();
char* pPtr = (char*)contents.Data();
memcpy(pPtr, pData, len);
//Externalize 以后会减去内存占用,导致不能正确GC,所以再给加回来。不知道管理ArrayBuffer的正确方法是什么。
//v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(len);
return ab;
}
v8::Local<v8::ArrayBuffer> createJSABAligned(char* pData, int len) {
int asz = (len + 3) & 0xfffffffc;
v8::Local<v8::ArrayBuffer> ab = v8::ArrayBuffer::New(v8::Isolate::GetCurrent(), asz);
v8::ArrayBuffer::Contents contents = ab->GetContents();// ab->Externalize();
char* pPtr = (char*)contents.Data();
memcpy(pPtr, pData, len);
//ArrayBuffer 自己已经初始化为0了
//Externalize 以后会减去内存占用,导致不能正确GC,所以再给加回来。不知道管理ArrayBuffer的正确方法是什么。
//v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(asz);
return ab;
}
bool extractJSAB(JsValue jsval, char*& data, int& len) {
v8::Local<v8::ArrayBuffer> ab;
if (jsval->IsArrayBufferView()) {
v8::Local<v8::ArrayBufferView> abv = v8::Local<v8::ArrayBufferView>::Cast(jsval);
len = abv->ByteLength();
ab = abv->Buffer();
v8::ArrayBuffer::Contents contents = ab->GetContents();
//len = contents.ByteLength(); 这种情况下,用view的长度,因为可能多个view公用一个大buffer
data = (char*)contents.Data()+abv->ByteOffset();
}
else if (jsval->IsArrayBuffer()) {
ab = v8::Local<v8::ArrayBuffer>::Cast(jsval);
v8::ArrayBuffer::Contents contents = ab->GetContents();
len = contents.ByteLength();
data = (char*)contents.Data();
}
else {
data = NULL;
len = 0;
return false;
}
/*
if (ab->IsExternal()) {
v8::ArrayBuffer::Contents contents = ab->GetContents();
len = contents.ByteLength();
data = (char*)contents.Data();
}
else {
v8::ArrayBuffer::Contents contents = ab->Externalize();
len = contents.ByteLength();
v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(len);
data = (char*)contents.Data();
}
*/
return true;
}
void __JSRun::ReportException(v8::Isolate* isolate, v8::TryCatch* try_catch) {
v8::HandleScope handle_scope(isolate);
v8::String::Utf8Value exception(try_catch->Exception());
const char* exception_string = ToCString(exception);
v8::Handle<v8::Message> message = try_catch->Message();
static char errInfo[2048];
int curpos = 0;
if (message.IsEmpty()) {
// V8 didn't provide any extra information about this error; just
// print the exception.
int off = snprintf(errInfo, sizeof(errInfo), "%s\n", exception_string);
//通知全局错误处理脚本
std::string kBuf = "if(conch.onerror){conch.onerror('";
kBuf += UrlEncode(exception_string);
kBuf += "','undefined','undefined','undefined','";
kBuf += UrlEncode(exception_string);
kBuf += "');};";
__JSRun::Run(kBuf.c_str());
}
else {
auto ctx = isolate->GetCurrentContext();
v8::String::Utf8Value fnstr (message->GetScriptResourceName());
const char* filename_string = ToCString(fnstr);
v8::MaybeLocal<String> source_line_maybe = message->GetSourceLine(ctx);
v8::String::Utf8Value srclinestr(source_line_maybe.ToLocalChecked());
const char* sourceline_string = ToCString(srclinestr);
int linenum = message->GetLineNumber(ctx).FromJust();
int start = message->GetStartColumn(ctx).FromMaybe(0);
int end = message->GetEndColumn(ctx).FromMaybe(0);
v8::ScriptOrigin origin = message->GetScriptOrigin();
int lineoff = origin.ResourceLineOffset()->Value();
int startcol = origin.ResourceColumnOffset()->Value();
if (start > startcol) {
start -= startcol;
end -= startcol;
}
//错误行可能非常长,只取一部分
char errLineSrc[128];
if (strlen(sourceline_string) > 128) {
int startoff = start > 50 ? (start - 50) : 0;
start -= startoff;
end -= startoff;
if (end >= 128)end = 127;
memcpy(errLineSrc, sourceline_string+startoff, 128);
sourceline_string = errLineSrc;
}
curpos += snprintf(errInfo, sizeof(errInfo), "%s:%i:\n%s\n%s\n",
filename_string,
linenum,
exception_string,
sourceline_string);
//打印具体哪一行,哪一列
if (curpos < sizeof(errInfo)) {
int st = curpos;
int srclen = snprintf(errInfo + curpos, sizeof(errInfo) - curpos, "%s\n", sourceline_string);
curpos += srclen;
if (curpos < sizeof(errInfo)) {
for (int si = 0; si < srclen; si++) {
char& c = errInfo[st+si];
if (c != ' ' && c != '\t' && c != '\r')c = ' ';
if (si >= start && si <= end)c = '^';
}
}
}
curpos += snprintf(errInfo + curpos,sizeof(errInfo)-curpos, "\n");
v8::String::Utf8Value stack_trace(try_catch->StackTrace());
if (stack_trace.length() > 0) {
const char* stack_trace_string = ToCString(stack_trace);
if (curpos < sizeof(errInfo)) {
curpos += snprintf(errInfo + curpos,sizeof(errInfo)-curpos, "%s", stack_trace_string);
}
}
//通知全局错误处理脚本
std::string kBuf = "if(conch.onerror){conch.onerror('";
kBuf += UrlEncode(exception_string);
kBuf += "','";
kBuf += UrlEncode(filename_string);
kBuf += "','";
//kBuf += std::to_string(linenum);
std::ostringstream os;
os << linenum;
kBuf += os.str();
kBuf += "','";
kBuf += "undefined";
kBuf += "','";
kBuf += UrlEncode(errInfo);
kBuf += "');};";
__JSRun::Run(kBuf.c_str());
}
if (gbAlertException)
JSAlert(errInfo);
else {
LOGE("==JSERROR:\n%s", errInfo);
}
}
}
#endif
@@ -0,0 +1,38 @@
#ifndef _JS_ARRAYBUFFER_H_
#define _JS_ARRAYBUFFER_H_
#include <v8.h>
#include <vector>
/*
如果有c这边的ArrayBufferView引用这个ArrayBuffer的话,需要增加引用计数,不能直接删除
*/
namespace laya{
//这个要在v8线程外分配和释放,因为v8析构的时候会调用这个对象提供的 Free 接口
class ArrayBufferAllocator : public v8::ArrayBuffer::Allocator {
public:
ArrayBufferAllocator();
~ArrayBufferAllocator();
virtual void* Allocate(size_t length) ;
virtual void* AllocateUninitialized(size_t length);
virtual void Free(void* data, size_t length);
//这个函数没有意义,v8本身会都释放掉 Heap::FreeDeadArrayBuffers
//void FreeAllAlive();//释放所有的还没有释放的ArrayBuffer
static ArrayBufferAllocator* getInstance();
//int _testGetID(void* pdata);
//int getAliveBufferNum() {
// return m_vAliveBuffer.size();
//}
protected:
//std::vector<char*> m_vAliveBuffer;
};
v8::Local<v8::ArrayBuffer> createJSAB(char* pData, int len);
v8::Local<v8::ArrayBuffer> createJSABAligned(char* pData, int len);
bool extractJSAB(v8::Local<v8::Value> ab, char*& data, int& len);
}
#endif
@@ -0,0 +1,69 @@
//
// JSCProxyTLS.h
// jsc_test
//
// Created by 蒋 宇彤 on 13-11-25.
// Copyright (c) 2013年 蒋 宇彤. All rights reserved.
//
#ifndef jsc_test_JSCProxyTLS_h
#define jsc_test_JSCProxyTLS_h
#include <v8.h>
#include <string>
#include <util/JCCommonMethod.h>
#include <util/Log.h>
#include <sstream>
namespace laya{
extern void JSAlert(const char* p_sBuffer);
class __JsThrow {
public:
static void Throw( const char *p_pszInfo ) {
v8::Isolate::GetCurrent()->ThrowException(v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), (0==p_pszInfo)?"unknown error":p_pszInfo));
}
};
extern bool gbAlertException;
class __JSRun {
public:
// Extracts a C string from a V8 Utf8Value.
static const char* ToCString(const v8::String::Utf8Value& value) {
return *value ? *value : "<string conversion failed>";
}
static void ReportException(v8::Isolate* isolate, v8::TryCatch* try_catch);
static bool Run( const char *p_pszScript ) {
v8::Isolate* isolate = v8::Isolate::GetCurrent();
v8::HandleScope handle_scope(isolate);
v8::TryCatch try_catch(isolate);
v8::Handle<v8::String> source = v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), p_pszScript);
v8::Handle<v8::Script> script = v8::Script::Compile(source);
if( script.IsEmpty() ){
//打印编译错误信息
printf("---Compile script error---\n");
ReportException(isolate, &try_catch);
return false;
}
v8::Handle<v8::Value> res = script->Run();
if( !res.IsEmpty() && !res->IsUndefined() )
{
v8::String::Utf8Value ascii(res);
printf("run result: [%s]\n", *ascii);
}
if( try_catch.HasCaught()){
printf("---run script error---\n");
ReportException(isolate, &try_catch);
}
return true;
}
};
}
#endif
@@ -0,0 +1,402 @@
//
// JSCProxyTrnasfer.h
// jsc_test
//
// Created by 蒋 宇彤 on 13-11-25.
// Copyright (c) 2013年 蒋 宇彤. All rights reserved.
//
#ifndef jsc_test_JSCProxyTrnasfer_h
#define jsc_test_JSCProxyTrnasfer_h
#include <v8.h>
#include <string>
#include <vector>
#include "JSArrayBuffer.h"
//#include "JsBinder.h"
using namespace v8;
namespace laya{
//为了能快速返回js的字符串,现在转字符串的函数使用了通用buffer,
//为了能同时返回多个buffer指针,就用了一个vector,为了避免vector一直增加,内存泄露
//就用了这个函数。具体看代码。
void resetJsStrBuf();
template<class T>
Local<Object> createJsObjAttachCObj(T* cobj, bool weak);
template <typename T> class __TransferToCpp{public:
static T ToCpp( Local<Value> p_vl ){
// 这是很危险的
if( !p_vl.IsEmpty() && p_vl->IsObject() ){
return static_cast<T>((p_vl.As<Object>())->GetAlignedPointerFromInternalField(0));
}else{
return (T)0;
}
}
//问题:如果是对象的话,当请求 T或者T* 认为是相同的
static bool is(Local<Value> p_vl) {
if (!p_vl->IsObject())
return false;
Local<Object> obj = p_vl.As<Object>();
if (obj->InternalFieldCount() < 2)
return false;
void* pdt = obj->GetAlignedPointerFromInternalField(1);
if( pdt == &T::JSCLSINFO) {
return true;
}
return false;
}
};
//不知道怎么区分对象和对象指针,先硬写一个
template <typename T> class __TransferToCpp<T*> {
public:
static T* ToCpp(Local<Value> p_vl) {
// 这是很危险的
if (!p_vl.IsEmpty() && p_vl->IsObject()) {
Local<Object> obj = p_vl.As<Object>();
return static_cast<T*>(obj->GetAlignedPointerFromInternalField(0));
}
else {
return (T*)0;
}
}
//问题:如果是对象的话,当请求 T或者T* 认为是相同的
static bool is(Local<Value> p_vl) {
if (!p_vl->IsObject())
return false;
Local<Object> obj = p_vl.As<Object>();
void* pdt = obj->GetAlignedPointerFromInternalField(1);
if (pdt == &T::JSCLSINFO) {
return true;
}
return false;
}
};
template <> class __TransferToCpp<int32_t> {
public:
static int32_t ToCpp(Local<Value> p_vl) { return p_vl->Int32Value(); }
static bool is(Local<Value> p_vl) { return p_vl->IsInt32(); }
};
template <> class __TransferToCpp<int64_t> {
public:
static int64_t ToCpp(Local<Value> p_vl) { return p_vl->IntegerValue(); }
static bool is(Local<Value> p_vl) { return p_vl->IsNumber(); }
};
template <> class __TransferToCpp<uint32_t> {
public:
static uint32_t ToCpp(Local<Value> p_vl) { return p_vl->Uint32Value(); }
static bool is(Local<Value> p_vl) { return p_vl->IsUint32(); }
};
template <> class __TransferToCpp<uint64_t> {
public:
static uint64_t ToCpp(Local<Value> p_vl) { return (uint64_t)p_vl->IntegerValue(); }
static bool is(Local<Value> p_vl) { return p_vl->IsNumber(); }
};
// template <> class __TransferToCpp<int>{public:
// static int ToCpp( Local<Value> p_vl ){return p_vl->Int32Value();}
// static bool is(Local<Value> p_vl) { return p_vl->IsInt32(); }
//};
//template <> class __TransferToCpp<short> {public:
// static short ToCpp(Local<Value> p_vl) { return p_vl->Int32Value(); }
// static bool is(Local<Value> p_vl) { return p_vl->IsInt32(); }
//};
// template <> class __TransferToCpp<unsigned int> {public:
// static unsigned int ToCpp( Local<Value> p_vl ){return p_vl->Uint32Value();}
// static bool is(Local<Value> p_vl) { return p_vl->IsUint32(); }
//};
// template <> class __TransferToCpp<long>{public:
// static long ToCpp( Local<Value> p_vl ){return p_vl->Int32Value();}
// static bool is(Local<Value> p_vl) { return p_vl->IsInt32(); }
//};
// template <> class __TransferToCpp<unsigned long>{public:
// static unsigned long ToCpp( Local<Value> p_vl ){return p_vl->Uint32Value();}
// static bool is(Local<Value> p_vl) { return p_vl->IsUint32(); }
//};
template <> class __TransferToCpp<bool>{public:
static bool ToCpp( Local<Value> p_vl ){return p_vl->BooleanValue();}
static bool is(Local<Value> p_vl) { return p_vl->IsBoolean(); }
};
template <> class __TransferToCpp<float>{public:
static float ToCpp( Local<Value> p_vl ){return (float)p_vl->NumberValue();}
static bool is(Local<Value> p_vl) { return p_vl->IsNumber(); }
};
template <> class __TransferToCpp<double>{public:
static double ToCpp( Local<Value> p_vl ){return p_vl->NumberValue();}
static bool is(Local<Value> p_vl) { return p_vl->IsNumber(); }
};
// template <> class __TransferToCpp<long long>{public:
// static long long ToCpp( Local<Value> p_vl ){return p_vl->IntegerValue();}
// static bool is(Local<Value> p_vl) { return p_vl->IsNumber(); }
//};
// template <> class __TransferToCpp<unsigned long long>{public:
// static unsigned long long ToCpp( Local<Value> p_vl ){return (unsigned long long)p_vl->IntegerValue();}
// static bool is(Local<Value> p_vl) { return p_vl->IsNumber(); }
//};
template <> class __TransferToCpp<Local<Value>>{public:
static Local<Value> ToCpp(Local<Value> p_vl) { return p_vl; }
static bool is(Local<Value> p_vl) { return true; }
};
//注意:这个函数返回的字符串使用了一个通用buffer,所以注意复制。
//这个函数必须配合 resetJsStrBuf 函数使用。
//例如
// char* p1 = JsCharToC(args[0]);
// char* p2 = JsCharToC(args[1]);
// use(p1,p2);
// resetJsStrBuf();
char* JsCharToC(Local<Value> p_vl);
class transToCharPtr {
public:
static char *ToCpp1(Local<Value> p_vl) {
String::Utf8Value utf8str(p_vl->ToString());
//return *utf8str;
//下面有泄露
char *pRet = 0;
size_t len;
if (0 != *utf8str && 0 != (len = strlen(*utf8str))){
pRet = new char[len + 1];
memcpy(pRet, *utf8str, len + 1);
}
return pRet;
}
static std::string ToCppStd(Local<Value> p_vl) {
String::Utf8Value utf8str(p_vl->ToString());
return std::string(*utf8str);
}
};
template <> class __TransferToCpp<char *> {public:
//注意:这个函数返回的字符串使用了一个通用buffer,所以注意复制
static char* ToCpp(Local<Value> p_vl) { return JsCharToC(p_vl); }
static bool is(Local<Value> p_vl) { return p_vl->IsString(); }
static std::string ToCppStd(Local<Value> p_vl) { return transToCharPtr::ToCppStd(p_vl); }
};
template <> class __TransferToCpp<const char *> {public:
//注意:这个函数返回的字符串使用了一个通用buffer,所以注意复制
static const char* ToCpp(Local<Value> p_vl) { return (const char*)JsCharToC(p_vl); }
static bool is(Local<Value> p_vl) { return p_vl->IsString(); }
static std::string ToCppStd(Local<Value> p_vl) { return transToCharPtr::ToCppStd(p_vl); }
};
template <> class __TransferToCpp<unsigned char *> {public:
//注意:这个函数返回的字符串使用了一个通用buffer,所以注意复制
static unsigned char* ToCpp(Local<Value> p_vl) { return (unsigned char*)JsCharToC(p_vl); }
static bool is(Local<Value> p_vl) { return p_vl->IsString(); }
static std::string ToCppStd(Local<Value> p_vl) { return transToCharPtr::ToCppStd(p_vl); }
};
template <> class __TransferToCpp<const unsigned char *> {public:
//注意:这个函数返回的字符串使用了一个通用buffer,所以注意复制
static const unsigned char* ToCpp(Local<Value> p_vl) { return (const unsigned char*)JsCharToC(p_vl); }
static bool is(Local<Value> p_vl) { return p_vl->IsString(); }
static std::string ToCppStd(Local<Value> p_vl) { return transToCharPtr::ToCppStd(p_vl); }
};
//template<> class __TransferToCpp<laya::JSArrayBuffer*>{public:
// static bool is(Local<Value> p_vl) { return p_vl->IsArrayBuffer() || p_vl->IsArrayBufferView(); }
// static laya::JSArrayBuffer* ToCpp(Local<Value> p_vl) { return laya::JSArrayBuffer::fromeJSObj(p_vl); };
//};
template <typename T> class __TransferToJs{
public:static Handle<Value> ToJs(T* p_vl) {
return laya::createJsObjAttachCObj<T>(p_vl,true);
}
};
//为什么不直接把没有参数作为void?
template <> class __TransferToJs<void>
{public:static Handle<Value> ToJs( int p_vl )
{
if(0==p_vl)
return Undefined(Isolate::GetCurrent());
else
return Null(Isolate::GetCurrent());
}};
template <> class __TransferToJs<v8::Local<v8::Value>>{
public:static Handle<Value> ToJs(v8::Local<v8::Value> p_vl) { return p_vl; }
};
template <> class __TransferToJs<v8::Local<v8::Object> >
{
public:static Handle<Value> ToJs(v8::Local<v8::Object> p_vl) { return p_vl; }
};
template <> class __TransferToJs<bool>
{public:static Handle<Value> ToJs( bool p_vl ){return Boolean::New(Isolate::GetCurrent(),p_vl);}};
template <> class __TransferToJs<int>
{public:static Handle<Value> ToJs( int p_vl ){return Int32::New(Isolate::GetCurrent(), p_vl);}};
template <> class __TransferToJs<unsigned int>
{public:static Handle<Value> ToJs( unsigned int p_vl ){return Uint32::New(Isolate::GetCurrent(), p_vl);}};
template <> class __TransferToJs<long unsigned int>
{
public:static Handle<Value> ToJs(long unsigned int p_vl) { return Number::New(Isolate::GetCurrent(), p_vl); }
};
template <> class __TransferToJs<float>
{public:static Handle<Value> ToJs( float p_vl ){return Number::New(Isolate::GetCurrent(), p_vl);}};
template <> class __TransferToJs<double>
{public:static Handle<Value> ToJs( double p_vl ){return Number::New(Isolate::GetCurrent(), p_vl);}};
template <> class __TransferToJs<long long>
{
public:
static Handle<Value> ToJs( long long p_vl )
{
return Number::New(Isolate::GetCurrent(), (double)p_vl);
}
static Handle<Value> ToJsDate( long long p_vl )
{
return Date::New(Isolate::GetCurrent(), (double)p_vl );
}
};
template <> class __TransferToJs<long>
{
public:
static Handle<Value> ToJs( long p_vl )
{
return Number::New(Isolate::GetCurrent(), (double)p_vl);
}
static Handle<Value> ToJsDate( long p_vl )
{
return Date::New(Isolate::GetCurrent(), (double)p_vl );
}
};
template <> class __TransferToJs<unsigned long long>
{
public:
static Handle<Value> ToJs( unsigned long long p_vl )
{
return Number::New(Isolate::GetCurrent(), (double)p_vl);
}
static Handle<Value> ToJsDate( unsigned long long p_vl )
{
return Date::New(Isolate::GetCurrent(), (double)p_vl );
}
};
template <> class __TransferToJs<char *>
{public:static Handle<Value> ToJs( char *p_vl ){if(p_vl==0) p_vl=(char*)""; return String::NewFromUtf8(Isolate::GetCurrent(),p_vl);}};
template <> class __TransferToJs<const char *>
{public:static Handle<Value> ToJs( const char *p_vl ){if(p_vl==0) p_vl=(const char *)""; return String::NewFromUtf8(Isolate::GetCurrent(),p_vl);}};
template <> class __TransferToJs<unsigned char *>
{public:static Handle<Value> ToJs( const unsigned char*p_vl ){if(p_vl==0) p_vl=(const unsigned char*)""; return String::NewFromUtf8(Isolate::GetCurrent(),(const char *)p_vl);}};
template <> class __TransferToJs<const unsigned char *>
{public:static Handle<Value> ToJs( const unsigned char *p_vl ){if(p_vl==0) p_vl=(const unsigned char *)""; return String::NewFromUtf8(Isolate::GetCurrent(),(const char *)p_vl);}};
template <> class __TransferToJs<std::string>
{public:static Handle<Value> ToJs( std::string p_vl ){return String::NewFromUtf8(Isolate::GetCurrent(), p_vl.c_str());}};
template <> class __TransferToJs<std::string&> {
public:static Handle<Value> ToJs(std::string& p_vl) { return String::NewFromUtf8(Isolate::GetCurrent(), p_vl.c_str()); }
};
//template <> class __TransferToJs<laya::JSArrayBuffer*>
//{public:static Handle<Value> ToJs( laya::JSArrayBuffer* p_vl ){return p_vl->toLocal();}};
template <typename T> class __JsArray{
public:
static Handle<Value> ToJsArray(const std::vector<T*>& p_v1)
{
int size=p_v1.size();
if(0==size)
{
Handle<Array> __array = Array::New(Isolate::GetCurrent(), 0);
return __array;
}
else
{
Handle<Array> __array = Array::New(Isolate::GetCurrent(), size);
for(int i=0;i<size;i++)
{
//__array->Set(i, __JSCProxy_class<T>::GetInstance()->TransferObjPtrToJS(p_v1.at(i)));
__array->Set(i, __TransferToJs<T>::ToJs(p_v1.at(i)));
}
return __array;
}
}
static Handle<Value> ToJsArray(const std::vector<T>& p_v1)
{
int size = p_v1.size();
if (0 == size)
{
Handle<Array> __array = Array::New(Isolate::GetCurrent(), 0);
return __array;
}
else
{
Handle<Array> __array = Array::New(Isolate::GetCurrent(), size);
for (int i = 0; i<size; i++)
{
//__array->Set(i, __JSCProxy_class<T>::GetInstance()->TransferObjPtrToJS(p_v1.at(i)));
__array->Set(i, __TransferToJs<T>::ToJs(p_v1.at(i)));
}
return __array;
}
}
};
class __JsByteArray
{
public:
static Handle<Value> ToJsByteArray( const unsigned char *p_vl, int p_iSize )
{
if( 0 == p_vl || p_iSize <= 0 )
{
return Null(Isolate::GetCurrent());
}
else
{
Handle<Array> __array = Array::New(Isolate::GetCurrent(), p_iSize);
for(int i=0;i<p_iSize;++i)
{
__array->Set( i, Int32::New(Isolate::GetCurrent(), p_vl[i]) );
}
return __array;
}
}
};
template <typename T> class __TransferToJs<std::vector<T*> >
{
public:static Handle<Value> ToJs( const std::vector<T*>& p_vl )
{
return __JsArray<T>::ToJsArray(p_vl);
}
};
template <typename T> class __TransferToJs<std::vector<T> >
{
public:static Handle<Value> ToJs(const std::vector<T>& p_vl)
{
return __JsArray<T>::ToJsArray(p_vl);
}
};
}
#endif
@@ -0,0 +1,93 @@
//
// JSCProxyType.h
// jsc_test
//
// Created by 蒋 宇彤 on 13-12-1.
// Copyright (c) 2013年 蒋 宇彤. All rights reserved.
//
#ifndef jsc_test_JSCProxyType_h
#define jsc_test_JSCProxyType_h
#include <v8.h>
#include "JSCProxyTLS.h"
namespace laya{
typedef enum {
__VT_void = 0,
__VT_string,
__VT_bool,
__VT_int,
__VT_long,
__VT_float,
__VT_double,
__VT_longlong,
__VT_ArrayBuffer,
__VT_object,
} __ValueType;
template <class _Key> struct __InferType
{__ValueType iType;__InferType(){iType=__VT_object;}};
template<> struct __InferType<void>
{__ValueType iType;__InferType(){iType=__VT_void;}};
template<> struct __InferType<bool>
{__ValueType iType;__InferType(){iType=__VT_bool;}};
template<> struct __InferType<char *>
{__ValueType iType;__InferType(){iType=__VT_string;}};
template<> struct __InferType<const char *>
{__ValueType iType;__InferType(){iType=__VT_string;}};
template<> struct __InferType<unsigned char *>
{__ValueType iType;__InferType(){iType=__VT_string;}};
template<> struct __InferType<const unsigned char *>
{__ValueType iType;__InferType(){iType=__VT_string;}};
template<> struct __InferType<int>
{__ValueType iType;__InferType(){iType=__VT_int;}};
template<> struct __InferType<unsigned int>
{__ValueType iType;__InferType(){iType=__VT_int;}};
template<> struct __InferType<long>
{__ValueType iType;__InferType(){iType=__VT_long;}};
template<> struct __InferType<unsigned long>
{__ValueType iType;__InferType(){iType=__VT_long;}};
template<> struct __InferType<float>
{__ValueType iType;__InferType(){iType=__VT_float;}};
template<> struct __InferType<double>
{__ValueType iType;__InferType(){iType=__VT_double;}};
template<> struct __InferType<long long>
{__ValueType iType;__InferType(){iType=__VT_longlong;}};
template<> struct __InferType<unsigned long long>
{__ValueType iType;__InferType(){iType=__VT_longlong;}};
class __CheckClassType
{
public:
template <typename T>
static bool IsTypeOf( v8::Local<v8::Value> p_Obj )
{
if( p_Obj.IsEmpty() || !p_Obj->IsObject() )
return false;
else {
v8::Local<v8::Object> obj = p_Obj.As<v8::Object>();
void* pdt = v8::Local<v8::External>::Cast(obj->GetInternalField(1))->Value();
return pdt == &T::JSCLSINFO;
}
}
};
} // namespace __JSCProxy
#endif
@@ -0,0 +1,248 @@
/**
@file JSEnv.cpp
@brief
@author James
@version 1.0
@date 2018_8_23
*/
#ifdef JS_V8
#include "JSEnv.h"
#include <v8-profiler.h>
#include "../../v8debug/debug-agent.h"
#include "util/Log.h"
#include "JSCProxyTLS.h"
#ifdef WIN32
#include <windows.h>
#include <process.h>
#endif
//#define V8PROFILE
namespace laya
{
v8::Persistent<v8::Context> Javascript::m_DebugMessageContext;
const char* ToCString(const v8::String::Utf8Value& value)
{
return *value ? *value : "<string conversion failed>";
}
class LayaHandleScope :public v8::HandleScope
{
public:
LayaHandleScope(v8::Isolate* piso)
{
HandleScope::Initialize(piso);
}
~LayaHandleScope()
{
}
public:
void Initialize(v8::Isolate* isolate)
{
HandleScope::Initialize(isolate);
}
};
Javascript::Javascript()
{
m_pIsolate = NULL;
m_pPlatform = NULL;
m_pScope = NULL;
m_pHandleScope = NULL;
m_pV8Locker = NULL;
m_pABAlloc = NULL;
m_nListenPort = 0;
}
void Javascript::init(int nPort)
{
if (!m_pPlatform)
{
m_pPlatform = v8::platform::CreateDefaultPlatform();
v8::V8::InitializePlatform(m_pPlatform);
}
v8::V8::Initialize();
m_nListenPort = 0;
if(nPort > 0 && nPort <0xFFFF )
{
m_nListenPort = nPort;
}
}
void Javascript::uninit()
{
//不能在v8线程
return;
if (0 != m_pIsolate)
{
m_pIsolate->Dispose();
m_pIsolate = 0;
ArrayBufferAllocator* pABAlloc = ArrayBufferAllocator::getInstance();
//pABAlloc->FreeAllAlive();
delete pABAlloc;
}
}
void Javascript::initJSEngine()
{
v8::Isolate::CreateParams create_params;
m_pABAlloc = ArrayBufferAllocator::getInstance();
create_params.array_buffer_allocator = m_pABAlloc;
m_pIsolate = v8::Isolate::New(create_params);
static char* flags[] =
{
"--expose_gc",
"--allow-natives-syntax",//导出内部的%函数
//"--trace-gc-verbose",
//"--use-strict",
//"--harmony",
//"--print-bytecode", //
//"--print-bytecode-filter errf1"
//"--trace-ignition-codegen",
//"--debug-code",
//"--trace-opt",
//"--trace-deopt",
//"--prof",
//"--code-comments",
};
for (auto f : flags)
{
v8::V8::SetFlagsFromString(f, strlen(f));
}
#ifdef V8PROFILE
v8::V8::SetFlagsFromString("--prof", 6);
char* pSingleLogFile = "--no-logfile_per_isolate";
v8::V8::SetFlagsFromString(pSingleLogFile, strlen(pSingleLogFile));
#ifdef ANDROID
char* profFile = "--logfile /sdcard/lr2perf/v8.log";
#elif WIN32
char* profFile = "--logfile d:/temp/v8.log";
#endif
v8::V8::SetFlagsFromString(profFile, strlen(profFile));
#endif
//m_pLocker = new v8::Locker(m_pIsolate);
//这个{}是为了能让 Scope起作用
m_pScope = new v8::Isolate::Scope(m_pIsolate);
m_pHandleScope = (v8::HandleScope*)malloc(sizeof(v8::HandleScope));
new (m_pHandleScope) LayaHandleScope(m_pIsolate);
v8::Handle<v8::ObjectTemplate> pGlobalTemplate = v8::ObjectTemplate::New(m_pIsolate);
v8::Local<v8::Context> context = v8::Context::New(m_pIsolate, NULL, pGlobalTemplate, v8::Handle<v8::Value>());
context->Enter();
//v8::CpuProfiler* pCpuProf = m_pIsolate->GetCpuProfiler();
//pCpuProf->StartCpuProfiling(v8::String::New(""));
//pCpuProf->StopCpuProfiling(v8::String::New(""));
if (m_nListenPort > 0)
{
{
std::unique_lock<std::recursive_mutex> __guard(m_Lock);
if (m_DebugMessageContext.IsEmpty())
{
m_DebugMessageContext.Reset(m_pIsolate, v8::Local<v8::Context>::New(m_pIsolate, context));
}
}
}
}
void Javascript::uninitJSEngine()
{
//当js线程要结束的时候,关闭调试,否则调试器客户端在线程结束后再发送调试事件,会导致非法。
if (m_nListenPort > 0)
{
//v8::Debug::DisableAgent();
}
if (!m_DebugMessageContext.IsEmpty())
{
m_DebugMessageContext.Reset();
}
//应该调用退出,但是context在scope中,先不退出了,发现也没有内存泄漏
//context->Enter();
delete m_pHandleScope;
m_pHandleScope = NULL;
delete m_pScope;
m_pScope = NULL;
m_pIsolate->Dispose();
delete m_pABAlloc;
}
void Javascript::run(const char* sSource, std::function<void(void)> preRunFunc)
{
}
void Javascript::run(const char* sSource)
{
}
void Javascript::run(voidfun func, void* pdata)
{
v8::TryCatch try_catch(m_pIsolate);
func(pdata);
if (try_catch.HasCaught())
{
v8::String::Utf8Value exceptioninfo(try_catch.Exception());
printf("Exception info [%s]\n", *exceptioninfo);
}
}
//------------------------------------------------------------------------------
JSV8Worker::JSV8Worker()
{
}
JSV8Worker::~JSV8Worker()
{
}
void JSV8Worker::_defRunLoop()
{
#ifdef WIN32
{
DWORD thid = GetCurrentThreadId();
SetNameInternal(thid, m_strName.c_str());
//threadInfoLog("start thread:%s,%d", m_strName.c_str(), thid);
}
#elif ANDROID
{
//threadInfoLog("start thread:%s,%ld", m_strName.c_str(), gettidv1());
}
#endif
//开始事件
JCEventEmitter::evtPtr startEvt(new JCEventBase);
startEvt->m_nID = JCWorkerThread::Event_threadStart;
emit(startEvt);
JCWorkerThread::runObj task;
while (!m_bStop)
{
v8::TryCatch trycatch(v8::Isolate::GetCurrent());
if (!m_funcLoop)
{
//现在的waitdata返回false不再表示要退出。事件唤醒流程
if (m_ThreadTasks.WaitData(&task))
task();
}
else
{
//固定循环流程
runQueue();
if (!m_funcLoop())
{
break;
}
}
if (trycatch.HasCaught())
{
v8::Isolate* piso = v8::Isolate::GetCurrent();
if( piso )__JSRun::ReportException(piso, &trycatch);
}
}
//退出事件
JCEventEmitter::evtPtr stopEvt(new JCEventBase);
stopEvt->m_nID = JCWorkerThread::Event_threadStop;
emit(stopEvt);
}
void call_JSThread__defRunLoop(void* pdata)
{
JSV8Worker* pthis=(JSV8Worker*)pdata;
pthis->_defRunLoop();
}
void JSV8Worker::_runLoop()
{
m_pJS->initJSEngine();
m_pJS->run(call_JSThread__defRunLoop,this);
m_pJS->uninitJSEngine();
}
}
#endif
//------------------------------------------------------------------------------
//-----------------------------END FILE--------------------------------
@@ -0,0 +1,354 @@
/**
@file JSEnv.h
@brief
@author James
@version 1.0
@date 2018_8_23
*/
#ifndef __JSEnv_H__
#define __JSEnv_H__
#include <v8.h>
#include <libplatform/libplatform.h>
#include <thread>
#include <mutex>
#include <misc/JCWorkerThread.h>
#include <util/ListNode.h>
#include "JSArrayBuffer.h"
#include <util/Log.h>
#include "JSCProxyTLS.h"
namespace laya
{
void JSPrint( const char* p_sBuffer );
void JSAlert( const char* p_sBuffer );
void evalJS( const char* p_sSource );
const char* ToCString(const v8::String::Utf8Value& value);
class Javascript
{
public:
typedef std::recursive_mutex _MutexType;
typedef void(*voidfun)(void* data);
Javascript();
void init(int nPort);
//在init之后,并且在js线程的情况下,可以添加js导出
//执行一段脚本。并立即退出。
void run(const char* sSource );
//preRunFunc 是在执行脚本之前先执行的函数,例如可以做导出对象
void run(const char* sSource, std::function<void(void)> preRunFunc );
//执行一个函数。并立即退出
void run(voidfun func,void* pdata);
//不能在v8线程,在js退出后,可以进行js对象的清理
void uninit();
void initJSEngine();
void uninitJSEngine();
public:
static v8::Persistent<v8::Context> m_DebugMessageContext;
v8::Isolate* m_pIsolate;
v8::Platform* m_pPlatform;
v8::Isolate::Scope* m_pScope;
v8::HandleScope* m_pHandleScope;
v8::Locker* m_pV8Locker;
ArrayBufferAllocator* m_pABAlloc;
_MutexType m_Lock;
int m_nListenPort;
};
class JSThreadInterface
{
public:
JSThreadInterface()
{
}
virtual ~JSThreadInterface()
{
}
virtual void post(std::function<void(void)> func) = 0;
virtual void on(int nEvent, JCEventEmitter::EventHandler func, void* pInThread=0) = 0;
virtual void start() = 0;
virtual void stop() = 0;
virtual void initialize(int nPort) = 0;
virtual void uninitialize() = 0;
virtual void setLoopFunc(std::function<bool(void)> func) = 0;
virtual void pushDbgFunc(std::function<void(void)> task) = 0;
virtual void runDbgFuncs() = 0;
virtual void waitAndRunDbgFuncs() = 0;
virtual bool hasDbgFuncs() = 0;
virtual JCWorkerThread* getWorker() = 0;
virtual void run(Javascript::voidfun func,void* pData) = 0;
virtual void clearFunc() = 0;
};
class JSV8Worker : public JCWorkerThread
{
public:
JSV8Worker();
~JSV8Worker();
//因为要trycatch,所以只好再抄一份了
virtual void _defRunLoop();
virtual void _runLoop();
public:
Javascript* m_pJS;
};
//把Javascript对象放到一个单独的线程中执行。
class JSMulThread: public JSThreadInterface
{
public:
JSMulThread()
{
m_kWorker.setThreadName("JavaScript Main");
m_kWorker.m_pJS = &m_kJS;
}
~JSMulThread()
{
//uninitialize();
}
void post(std::function<void(void)> func)
{
m_kWorker.post(func);
}
void on(int nEvent, JCEventEmitter::EventHandler func, void* pInThread=0)
{
m_kWorker.on(nEvent, func, (JCWorkerThread*)pInThread);
}
void start()
{
m_kWorker.start();
}
void stop()
{
m_kWorker.stop();
}
void initialize(int nPort)
{
m_kJS.init(nPort);
}
void uninitialize()
{
m_kJS.uninit();
}
void setLoopFunc(std::function<bool(void)> func)
{
m_kWorker.setLoopFunc(func);
}
void pushDbgFunc(std::function<void(void)> task)
{
m_DbgFuncLock.lock();
m_DbgFunction.push_back(task);
m_DbgFuncLock.unlock();
}
void runDbgFuncs()
{
m_DbgFuncLock.lock();
for (std::function<void(void)>& task : m_DbgFunction)
{
task();
}
m_DbgFunction.clear();
m_DbgFuncLock.unlock();
}
void waitAndRunDbgFuncs()
{
m_DbgFuncLock.lock();
m_DbgFuncLock.unlock();
}
bool hasDbgFuncs()
{
bool bRet = false;
m_DbgFuncLock.lock();
bRet = m_DbgFunction.size() > 0;
m_DbgFuncLock.unlock();
return bRet;
}
JCWorkerThread* getWorker()
{
return &m_kWorker;
}
void run(Javascript::voidfun func, void* pData)
{
}
void clearFunc()
{
}
protected:
std::vector<std::function<void(void)>> m_DbgFunction; //调试函数
std::mutex m_DbgFuncLock;
JSV8Worker m_kWorker;
Javascript m_kJS;
};
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//把Javascript对象放到一个单独的线程中执行。
class JSSingleThread : public JSThreadInterface
{
public:
JSSingleThread()
{
}
~JSSingleThread()
{
//uninitialize();
}
void post(std::function<void(void)> func)
{
m_kQueueLock.lock();
m_vFuncQueue.push_back(func);
m_kQueueLock.unlock();
}
void on(int nEvent, JCEventEmitter::EventHandler func, void* pInThread = 0)
{
switch (nEvent)
{
case JCWorkerThread::Event_threadStart:
m_kStartFunc.func = func;
m_kStartFunc.bDel = false;
break;
case JCWorkerThread::Event_threadStop:
m_kStopFunc.func = func;
m_kStopFunc.bDel = false;
break;
default:
LOGE("JSSingleThread on() event type error");
break;
}
}
void start()
{
m_kStartFunc.func(NULL);
}
void stop()
{
m_kStopFunc.func(NULL);
}
void initialize(int nPort)
{
clearFunc();
m_kJS.init(nPort);
m_kJS.initJSEngine();
}
void uninitialize()
{
clearFunc();
m_kJS.uninit();
m_kJS.uninitJSEngine();
}
void setLoopFunc(std::function<bool(void)> func)
{
LOGE("JSSingleThread setLoopFunc error,You can't call this function on V8 Engine");
}
void pushDbgFunc(std::function<void(void)> task)
{
m_DbgFuncLock.lock();
m_DbgFunction.push_back(task);
m_DbgFuncLock.unlock();
}
void runDbgFuncs()
{
m_DbgFuncLock.lock();
for (std::function<void(void)>& task : m_DbgFunction)
{
task();
}
m_DbgFunction.clear();
m_DbgFuncLock.unlock();
}
void waitAndRunDbgFuncs()
{
m_DbgFuncLock.lock();
m_DbgFuncLock.unlock();
}
bool hasDbgFuncs()
{
bool bRet = false;
m_DbgFuncLock.lock();
bRet = m_DbgFunction.size() > 0;
m_DbgFuncLock.unlock();
return bRet;
}
JCWorkerThread* getWorker()
{
return NULL;
}
void run(Javascript::voidfun func, void* pData)
{
v8::TryCatch try_catch(m_kJS.m_pIsolate);
runFunQueue();
if (pData)func(pData);
if (try_catch.HasCaught())
{
__JSRun::ReportException(m_kJS.m_pIsolate, &try_catch);
}
}
void clearFunc()
{
m_kQueueLock.lock();
m_vFuncQueue.clear();
m_kQueueLock.unlock();
}
public:
void runFunQueue()
{
std::vector<std::function<void(void)>> vWorkQueue;
m_kQueueLock.lock();
std::swap(vWorkQueue, m_vFuncQueue);
m_kQueueLock.unlock();
for (int i = 0; i < (int)vWorkQueue.size(); i++)
{
vWorkQueue[i]();
}
}
protected:
std::vector<std::function<void(void)>> m_DbgFunction; //调试函数
std::mutex m_DbgFuncLock;
Javascript m_kJS;
JCEventEmitter::EvtHandlerPack m_kStartFunc;
JCEventEmitter::EvtHandlerPack m_kStopFunc;
std::vector<std::function<void(void)>> m_vFuncQueue; //需要在此线程执行的函数的队列
std::mutex m_kQueueLock;
};
};
//------------------------------------------------------------------------------
#endif //__JSEnv_H__
//-----------------------------END FILE--------------------------------
@@ -0,0 +1,169 @@
#ifdef JS_V8
#include "JsBinder.h"
#include "../JSInterface.h"
using namespace v8;
namespace laya {
thread_local JSClassMgr JSClassMgr::__Ins;
void imp_js2cfunc_common(const FunctionCallbackInfo<Value>& args) {
void* pExData = External::Cast(*args.Data())->Value();
Local<Object> pthis = args.This();
if (pthis->InternalFieldCount() > 1) {
JsObjClassInfo* id = (JsObjClassInfo*)Handle<External>::Cast(pthis->GetInternalField(1))->Value();
void *pObj = Handle<External>::Cast(pthis->GetInternalField(0))->Value();
int a = 0;
}
JSP_RUN_SCRIPT("printstack();");
throw - 1;//不能调到这里 //支持基本类型,或者Value
}
bool checkJSToCArgs(const FunctionCallbackInfo<Value>& args, int num) {
int len = args.Length();
if (len >= num)
return true;
static char buff[512];
/*算了,别alert了,log把
sprintf(buff, "alert('arguments number err: %d:%d');printstack();", num, len);
JSP_RUN_SCRIPT(buff);
throw - 1;//不能调到这里 //支持基本类型,或者Value
*/
sprintf(buff, "console.log('arguments number err: %d:%d');var e = new Error();console.log(e.stack);", num, len);
JSP_RUN_SCRIPT(buff);
return false;
}
Local<Function> createJSMethodRaw(FunctionCallback func, JsValue data) {
Isolate* pIso = Isolate::GetCurrent();
Local<FunctionTemplate> method = FunctionTemplate::New(pIso);
method->SetCallHandler(func, data);
return method->GetFunction();
}
JSObjBaseV8::JSObjBaseV8() {
mpRefArray = NULL;
mpCurJsArgs = NULL;
mpJsThis = NULL;
mnRefArrSize = 0;
mbWeakThis = true;
//放在构造里面,容易导致没有js环境而非法。还是往后放放吧。
mpJsIso = NULL;
//mpJsIso = Isolate::GetCurrent();
}
JSObjBaseV8::~JSObjBaseV8() {
if (!mbWeakThis) {
mpJsThis->Reset();
delete mpJsThis;
mpJsThis = NULL;
}
}
void JSObjBaseV8::destroyWeakCB(const WeakCallbackInfo<Persistent<Object> >& data) {
HandleScope __lHandleScope(Isolate::GetCurrent());
Persistent<Object> *pPersistentVal = data.GetParameter();
//Handle<Object> pNewIns = Local<Object>::New(Isolate::GetCurrent(), *pPersistentVal);
//T *ptr = (T *)Handle<External>::Cast(pNewIns->GetInternalField(0))->Value();
//delete ptr;
pPersistentVal->Reset();
delete pPersistentVal;
}
void JSObjBaseV8::destroyWeakRefArray(const WeakCallbackInfo<Persistent<Array> >& data) {
Persistent<Array>* pData = data.GetParameter();
//JSObjBaseV8* pObj = pData->pObj;
if (pData == NULL)
return;
//Isolate* piso = Isolate::GetCurrent();
//HandleScope __lHandleScope(piso);
/*
Local<Array> refArr = pData->Get(piso);
int sz = refArr->Length();
for (int i = 0; i < sz; i++) {
refArr->Delete(piso->GetCurrentContext(), i);
}
*/
pData->Reset();
delete pData;
}
void JSObjBaseV8::retainThis() {
//我觉得这个其实应该不用。
mRetainedThis.Reset(mpJsIso, mpJsThis->Get(mpJsIso));
}
void JSObjBaseV8::releaseThis() {
mRetainedThis.Reset();
}
void JSObjBaseV8::createJSObj() {
if (!mpJsIso)mpJsIso = Isolate::GetCurrent();
Local<Object> jsobj = Local<Object>::New(mpJsIso, Object::New(mpJsIso));
mpJsThis = new Persistent<Object>(mpJsIso, jsobj);
mbWeakThis = false;
createRefArray();
}
/*
void JSObjBaseV8::addRefHandle(JsObjHandle2* handle) {
handle->m_pObj = this;
handle->m_nID = mnRefArrSize++;
}
*/
//創建一個數組,用於保存引用的js對象。
void JSObjBaseV8::createRefArray() {
mpJsIso = Isolate::GetCurrent();
Local<Array> refarr = Array::New(mpJsIso, mnRefArrSize);
int le = refarr->Length();
Local<Object> jsthis = Local<Object>::New(mpJsIso, *mpJsThis);
//需要把它加到this的引用中,防止这个数组被删除掉。
jsthis->Set(Js_Str(mpJsIso, "__internal_refArray"), refarr);
//这个是为了访问方便。可能去掉更好。
mpRefArray = new Persistent<Array>(mpJsIso, refarr);
//由于自己有引用,所以不用再在回调中删掉了。
mpRefArray->SetWeak(mpRefArray, JSObjBaseV8::destroyWeakRefArray, v8::WeakCallbackType::kInternalFields);
}
void JSObjBaseV8::setRefObj(int idx, JsValue obj) {
if (!mpRefArray)
return;
if (mnRefArrSize <= idx)mnRefArrSize = idx + 1;
Local<Array> refArr = mpRefArray->Get(mpJsIso);
refArr->Set(idx, obj);
}
Local<Object> JSObjBaseV8::getRefObj(int idx) {
Local<Array> refArr = mpRefArray->Get(mpJsIso);
return refArr->Get(idx).As<Object>();
}
Persistent<Object>* JSObjBaseV8::weakHoldJsObj(Local<Object>& pobj) {
Persistent<Object>* pObj = new Persistent<Object>(mpJsIso, pobj);
pObj->SetWeak(pObj, destroyWeakCB, v8::WeakCallbackType::kInternalFields);
return pObj;
}
JsValue JSObjBaseV8::callJsFunc(JsFunction& func) {
int argc = 0;
Local<Value> argv[1];
return _callJsFunc(func, argc, argv);
}
bool JsObjHandle2::Empty() {
if (!m_pObj)
return true;
return m_pObj->getRefObj(m_nID).IsEmpty();
}
void JsObjHandle2::set(JsValue& v) {
if (m_pObj == NULL) {
LOGE("throw set jsvalue m_pObj==null ");
throw - 4;
}
m_pObj->setRefObj(m_nID, v);
}
}
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,8 @@
#ifndef __JSbtBindHelper_H__
#define __JSbtBindHelper_H__
#define JSbt_Bind_Global_Func(func, ...) \
JSP_ADD_GLOBAL_FUNCTION(func, func, __VA_ARGS__)
#endif // !__JSbtBindHelper_H__
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,296 @@
#ifndef __LayaBulletExport_H__
#define __LayaBulletExport_H__
#include "../../../JCScriptRuntime.h"
#include "../../JSInterface/JSInterface.h"
#include "btBulletDynamicsCommon.h"
#include "BulletCollision/Gimpact/btGImpactCollisionAlgorithm.h"
#include "BulletCollision/Gimpact/btGImpactShape.h"
#include "BulletCollision/CollisionDispatch/btGhostObject.h"
#include "BulletDynamics/Character/btKinematicCharacterController.h"
#define WASM_EXP JSLayaConchBullet::
#define __BTWASM_SYSCALL_NAME(name)
typedef intptr_t pointer_t;
namespace laya
{
inline void layaMotionStateGetWorldTransform(pointer_t rigidBodyID, pointer_t worldTrans)
{
JCScriptRuntime* pScriptRuntime = JCScriptRuntime::s_JSRT;
if (pScriptRuntime)
{
pScriptRuntime->m_bJSBulletGetWorldTransformHandle.Call(rigidBodyID, worldTrans);
}
}
inline void layaMotionStateSetWorldTransform(pointer_t rigidBodyID, const pointer_t worldTrans)
{
JCScriptRuntime* pScriptRuntime = JCScriptRuntime::s_JSRT;
if (pScriptRuntime)
{
pScriptRuntime->m_bJSBulletSetWorldTransformHandle.Call(rigidBodyID, worldTrans);
}
}
class LayaMotionState : public btMotionState
{
public:
pointer_t rigidBodyID;
virtual void getWorldTransform(btTransform &centerOfMassWorldTrans)
{
layaMotionStateGetWorldTransform(rigidBodyID, (pointer_t)&centerOfMassWorldTrans);
}
virtual void setWorldTransform(const btTransform &centerOfMassWorldTrans)
{
layaMotionStateSetWorldTransform(rigidBodyID, (pointer_t)&centerOfMassWorldTrans);
}
};
class JSLayaConchBullet : public JsObjBase, public JSObjNode
{
private:
static JSLayaConchBullet* ms_pInstance;
public:
static JsObjClassInfo JSCLSINFO;
static JSLayaConchBullet* GetInstance();
static void exportJS();
JSLayaConchBullet();
~JSLayaConchBullet();
void btGImpactCollisionAlgorithm_RegisterAlgorithm(pointer_t dispatcher);
pointer_t btVector3_create(btScalar x, btScalar y, btScalar z);
void btVector3_setValue(pointer_t ptr, btScalar x, btScalar y, btScalar z);
btScalar btVector3_x(pointer_t ptr);
btScalar btVector3_y(pointer_t ptr);
btScalar btVector3_z(pointer_t ptr);
pointer_t btQuaternion_create(btScalar x, btScalar y, btScalar z, btScalar w);
void btQuaternion_setValue(pointer_t ptr, btScalar x, btScalar y, btScalar z, btScalar w);
btScalar btQuaternion_x(pointer_t ptr);
btScalar btQuaternion_y(pointer_t ptr);
btScalar btQuaternion_z(pointer_t ptr);
btScalar btQuaternion_w(pointer_t ptr);
pointer_t btTransform_create();
void btTransform_setOrigin(pointer_t ptr, pointer_t origin);
void btTransform_setRotation(pointer_t ptr, pointer_t q);
pointer_t btTransform_getOrigin(pointer_t ptr);
pointer_t btTransform_getRotation(pointer_t ptr);
void btTransform_setIdentity(pointer_t ptr);
void btMotionState_destroy(pointer_t ptr);
pointer_t layaMotionState_create();
void layaMotionState_set_rigidBodyID(pointer_t ptr, int rigidBodyID);
pointer_t btCollisionObject_create();
void btCollisionObject_setContactProcessingThreshold(pointer_t ptr, btScalar contactProcessingThreshold);
void btCollisionObject_setActivationState(pointer_t ptr, int newState);
void btCollisionObject_forceActivationState(pointer_t ptr, int newState);
void btCollisionObject_activate(pointer_t ptr, bool forceActivation);
bool btCollisionObject_isActive(pointer_t ptr);
void btCollisionObject_setRestitution(pointer_t ptr, btScalar rest);
void btCollisionObject_setFriction(pointer_t ptr, btScalar frict);
void btCollisionObject_setRollingFriction(pointer_t ptr, btScalar frict);
int btCollisionObject_getCollisionFlags(pointer_t ptr);
void btCollisionObject_setCollisionFlags(pointer_t ptr, int flags);
pointer_t btCollisionObject_getWorldTransform(pointer_t ptr);
void btCollisionObject_setCollisionShape(pointer_t ptr, pointer_t collisionShape);
btScalar btCollisionObject_getCcdMotionThreshold(pointer_t ptr);
void btCollisionObject_setCcdMotionThreshold(pointer_t ptr, btScalar ccdMotionThreshold);
btScalar btCollisionObject_getCcdSweptSphereRadius(pointer_t ptr);
void btCollisionObject_setCcdSweptSphereRadius(pointer_t ptr, btScalar radius);
int btCollisionObject_getUserIndex(pointer_t ptr);
void btCollisionObject_setUserIndex(pointer_t ptr, int index);
int btCollisionObject_getActivationState(pointer_t ptr);
void btCollisionObject_setInterpolationAngularVelocity(pointer_t ptr, pointer_t angvel);
void btCollisionObject_setInterpolationLinearVelocity(pointer_t ptr, pointer_t linvel);
void btCollisionObject_destroy(pointer_t ptr);
void RayResultCallback_set_m_flags(pointer_t ptr, int flags);
bool RayResultCallback_hasHit(pointer_t ptr);
void RayResultCallback_set_m_collisionFilterGroup(pointer_t ptr, int group);
void RayResultCallback_set_m_collisionFilterMask(pointer_t ptr, int mask);
btScalar RayResultCallback_get_m_closestHitFraction(pointer_t ptr);
void RayResultCallback_set_m_closestHitFraction(pointer_t ptr, btScalar fraction);
pointer_t RayResultCallback_get_m_collisionObject(pointer_t ptr);
void RayResultCallback_set_m_collisionObject(pointer_t ptr, pointer_t collisionObject);
pointer_t ClosestRayResultCallback_create(pointer_t rayFromWorld, pointer_t rayToWorld);
pointer_t ClosestRayResultCallback_get_m_rayFromWorld(pointer_t ptr);
void ClosestRayResultCallback_set_m_rayFromWorld(pointer_t ptr, pointer_t rayFromWorld);
pointer_t ClosestRayResultCallback_get_m_rayToWorld(pointer_t ptr);
void ClosestRayResultCallback_set_m_rayToWorld(pointer_t ptr, pointer_t rayToWorld);
pointer_t ClosestRayResultCallback_get_m_hitNormalWorld(pointer_t ptr);
pointer_t ClosestRayResultCallback_get_m_hitPointWorld(pointer_t ptr);
int tBtCollisionObjectArray_size(pointer_t ptr);
pointer_t tBtCollisionObjectArray_at(pointer_t ptr, int n);
void tBtCollisionObjectArray_clear(pointer_t ptr);
pointer_t tVector3Array_at(pointer_t ptr, int n);
void tVector3Array_clear(pointer_t ptr);
btScalar tScalarArray_at(pointer_t ptr, int n);
void tScalarArray_clear(pointer_t ptr);
pointer_t AllHitsRayResultCallback_create(pointer_t rayFromWorld, pointer_t rayToWorld);
pointer_t AllHitsRayResultCallback_get_m_rayFromWorld(pointer_t ptr);
void AllHitsRayResultCallback_set_m_rayFromWorld(pointer_t ptr, pointer_t rayFromWorld);
pointer_t AllHitsRayResultCallback_get_m_rayToWorld(pointer_t ptr);
void AllHitsRayResultCallback_set_m_rayToWorld(pointer_t ptr, pointer_t rayToWorld);
pointer_t AllHitsRayResultCallback_get_m_hitPointWorld(pointer_t ptr);
pointer_t AllHitsRayResultCallback_get_m_hitNormalWorld(pointer_t ptr);
pointer_t AllHitsRayResultCallback_get_m_collisionObjects(pointer_t ptr);
pointer_t AllHitsRayResultCallback_get_m_hitFractions(pointer_t ptr);
pointer_t btManifoldPoint_get_m_positionWorldOnA(pointer_t ptr);
pointer_t btManifoldPoint_get_m_positionWorldOnB(pointer_t ptr);
pointer_t btManifoldPoint_get_m_normalWorldOnB(pointer_t ptr);
btScalar btManifoldPoint_getDistance(pointer_t ptr);
bool ConvexResultCallback_hasHit(pointer_t ptr);
void ConvexResultCallback_set_m_collisionFilterGroup(pointer_t ptr, int group);
void ConvexResultCallback_set_m_collisionFilterMask(pointer_t ptr, int mask);
btScalar ConvexResultCallback_get_m_closestHitFraction(pointer_t ptr);
void ConvexResultCallback_set_m_closestHitFraction(pointer_t ptr, btScalar fraction);
pointer_t ClosestConvexResultCallback_create(pointer_t convexFromWorld, pointer_t convexToWorld);
pointer_t ClosestConvexResultCallback_get_m_hitNormalWorld(pointer_t ptr);
pointer_t ClosestConvexResultCallback_get_m_hitPointWorld(pointer_t ptr);
pointer_t ClosestConvexResultCallback_get_m_hitCollisionObject(pointer_t ptr);
void ClosestConvexResultCallback_set_m_hitCollisionObject(pointer_t ptr, pointer_t hitCollisionObject);
pointer_t AllConvexResultCallback_create(pointer_t convexFromWorld, pointer_t convexToWorld);
pointer_t AllConvexResultCallback_get_m_hitNormalWorld(pointer_t ptr);
pointer_t AllConvexResultCallback_get_m_hitPointWorld(pointer_t ptr);
pointer_t AllConvexResultCallback_get_m_hitFractions(pointer_t ptr);
pointer_t AllConvexResultCallback_get_m_collisionObjects(pointer_t ptr);
pointer_t btCollisionShape_getLocalScaling(pointer_t ptr);
void btCollisionShape_setLocalScaling(pointer_t ptr, pointer_t scaling);
void btCollisionShape_calculateLocalInertia(pointer_t ptr, btScalar mass, pointer_t inertia);
void btCollisionShape_destroy(pointer_t ptr);
pointer_t btBoxShape_create(pointer_t boxHalfExtents);
pointer_t btCapsuleShape_create(btScalar radius, btScalar height);
pointer_t btCapsuleShapeX_create(btScalar radius, btScalar height);
pointer_t btCapsuleShapeZ_create(btScalar radius, btScalar height);
pointer_t btCylinderShape_create(pointer_t halfExtents);
pointer_t btCylinderShapeX_create(pointer_t halfExtents);
pointer_t btCylinderShapeZ_create(pointer_t halfExtents);
pointer_t btSphereShape_create(btScalar radius);
pointer_t btConeShape_create(btScalar radius, btScalar height);
pointer_t btConeShapeX_create(btScalar radius, btScalar height);
pointer_t btConeShapeZ_create(btScalar radius, btScalar height);
pointer_t btStaticPlaneShape_create(pointer_t planeNormal, btScalar planeConstant);
void btGImpactShapeInterface_updateBound(pointer_t ptr);
pointer_t btGImpactMeshShape_create(pointer_t meshInterface);
pointer_t btCompoundShape_create();
void btCompoundShape_addChildShape(pointer_t ptr, pointer_t localTransform, pointer_t shape);
void btCompoundShape_removeChildShapeByIndex(pointer_t ptr, int childShapeIndex);
pointer_t btCompoundShape_getChildShape(pointer_t ptr, int index);
void btCompoundShape_updateChildTransform(pointer_t ptr, int index, pointer_t newChildTransform, bool shouldRecalculateLocalAabb);
void btStridingMeshInterface_destroy(pointer_t ptr);
pointer_t btTriangleMesh_create();
void btTriangleMesh_addTriangle(pointer_t ptr, pointer_t vertex1, pointer_t vertex2, pointer_t vertex3, bool removeDuplicateVertices);
pointer_t btDefaultCollisionConfiguration_create();
void btDefaultCollisionConfiguration_destroy(pointer_t ptr);
pointer_t btPersistentManifold_getBody0(pointer_t ptr);
pointer_t btPersistentManifold_getBody1(pointer_t ptr);
int btPersistentManifold_getNumContacts(pointer_t ptr);
pointer_t btPersistentManifold_getContactPoint(pointer_t ptr, int index);
int btDispatcher_getNumManifolds(pointer_t ptr);
pointer_t btDispatcher_getManifoldByIndexInternal(pointer_t ptr, int index);
pointer_t btCollisionDispatcher_create(pointer_t collisionConfiguration);
void btCollisionDispatcher_destroy(pointer_t ptr);
void btOverlappingPairCache_setInternalGhostPairCallback(pointer_t ptr, pointer_t ghostPairCallback);
pointer_t btDbvtBroadphase_create();
pointer_t btDbvtBroadphase_getOverlappingPairCache(pointer_t ptr);
void btDbvtBroadphase_destroy(pointer_t ptr);
pointer_t btRigidBodyConstructionInfo_create(btScalar mass, pointer_t motionState, pointer_t collisionShape, pointer_t localInertia);
void btRigidBodyConstructionInfo_destroy(pointer_t ptr);
pointer_t btRigidBody_create(pointer_t constructionInfo);
void btRigidBody_setCenterOfMassTransform(pointer_t ptr, pointer_t xform);
void btRigidBody_setSleepingThresholds(pointer_t ptr, btScalar linear, btScalar angular);
btScalar btRigidBody_getLinearSleepingThreshold(pointer_t ptr);
btScalar btRigidBody_getAngularSleepingThreshold(pointer_t ptr);
void btRigidBody_setDamping(pointer_t ptr, btScalar lin_damping, btScalar ang_damping);
void btRigidBody_setMassProps(pointer_t ptr, btScalar mass, pointer_t inertia);
void btRigidBody_setLinearFactor(pointer_t ptr, pointer_t linearFactor);
void btRigidBody_applyTorque(pointer_t ptr, pointer_t torque);
void btRigidBody_applyForce(pointer_t ptr, pointer_t force, pointer_t rel_pos);
void btRigidBody_applyCentralForce(pointer_t ptr, pointer_t force);
void btRigidBody_applyTorqueImpulse(pointer_t ptr, pointer_t torque);
void btRigidBody_applyImpulse(pointer_t ptr, pointer_t impulse, pointer_t rel_pos);
void btRigidBody_applyCentralImpulse(pointer_t ptr, pointer_t impulse);
void btRigidBody_updateInertiaTensor(pointer_t ptr);
pointer_t btRigidBody_getLinearVelocity(pointer_t ptr);
pointer_t btRigidBody_getAngularVelocity(pointer_t ptr);
void btRigidBody_setLinearVelocity(pointer_t ptr, pointer_t lin_vel);
void btRigidBody_setAngularVelocity(pointer_t ptr, pointer_t ang_vel);
void btRigidBody_setAngularFactor(pointer_t ptr, pointer_t angularFactor);
pointer_t btRigidBody_getGravity(pointer_t ptr);
void btRigidBody_setGravity(pointer_t ptr, pointer_t acceleration);
void btKinematicCharacterController_setUp(pointer_t ptr, pointer_t up);
void btKinematicCharacterController_setStepHeight(pointer_t ptr, btScalar h);
void btCollisionObject_setInterpolationWorldTransform(pointer_t ptr, pointer_t worldTrans);
void btCollisionObject_setWorldTransform(pointer_t ptr, pointer_t worldTrans);
pointer_t btRigidBody_getTotalForce(pointer_t ptr);
pointer_t btRigidBody_getTotalTorque(pointer_t ptr);
int btRigidBody_getFlags(pointer_t ptr);
void btRigidBody_setFlags(pointer_t ptr, int flags);
void btRigidBody_clearForces(pointer_t ptr);
pointer_t btSequentialImpulseConstraintSolver_create();
bool btCollisionWorld_get_m_useContinuous(pointer_t ptr);
void btCollisionWorld_set_m_useContinuous(pointer_t ptr, bool useContinuous);
void btCollisionWorld_rayTest(pointer_t ptr, pointer_t rayFromWorld, pointer_t rayToWorld, pointer_t resultCallback);
pointer_t btCollisionWorld_getDispatchInfo(pointer_t ptr);
void btCollisionWorld_addCollisionObject(pointer_t ptr, pointer_t collisionObject, int collisionFilterGroup, int collisionFilterMask);
void btCollisionWorld_removeCollisionObject(pointer_t ptr, pointer_t collisionObject);
void btCollisionWorld_convexSweepTest(pointer_t ptr, pointer_t castShape, pointer_t from, pointer_t to, pointer_t resultCallback, float allowedCcdPenetration);
void btCollisionWorld_destroy(pointer_t ptr);
void btDynamicsWorld_addAction(pointer_t ptr, pointer_t action);
void btDynamicsWorld_removeAction(pointer_t ptr, pointer_t action);
pointer_t btDynamicsWorld_getSolverInfo(pointer_t ptr);
pointer_t btDiscreteDynamicsWorld_create(pointer_t dispatcher, pointer_t pairCache, pointer_t constraintSolver, pointer_t collisionConfiguration);
void btDiscreteDynamicsWorld_setGravity(pointer_t ptr, pointer_t gravity);
pointer_t btDiscreteDynamicsWorld_getGravity(pointer_t ptr);
void btDiscreteDynamicsWorld_addRigidBody(pointer_t ptr, pointer_t body, int group, int mask);
void btDiscreteDynamicsWorld_removeRigidBody(pointer_t ptr, pointer_t body);
void btDiscreteDynamicsWorld_stepSimulation(pointer_t ptr, btScalar timeStep, int maxSubSteps, btScalar fixedTimeStep);
void btDiscreteDynamicsWorld_clearForces(pointer_t ptr);
void btDiscreteDynamicsWorld_setApplySpeculativeContactRestitution(pointer_t ptr, bool enable);
bool btDiscreteDynamicsWorld_getApplySpeculativeContactRestitution(pointer_t ptr);
pointer_t btKinematicCharacterController_create(pointer_t ghostObject, pointer_t convexShape, btScalar stepHeight, pointer_t up);
void btKinematicCharacterController_setWalkDirection(pointer_t ptr, pointer_t walkDirection);
void btKinematicCharacterController_setFallSpeed(pointer_t ptr, btScalar fallSpeed);
void btKinematicCharacterController_setJumpSpeed(pointer_t ptr, btScalar jumpSpeed);
void btKinematicCharacterController_setMaxSlope(pointer_t ptr, btScalar slopeRadians);
bool btKinematicCharacterController_onGround(pointer_t ptr);
void btKinematicCharacterController_jump(pointer_t ptr, pointer_t v);
void btKinematicCharacterController_setGravity(pointer_t ptr, pointer_t gravity);
void btKinematicCharacterController_destroy(pointer_t ptr);
pointer_t btPairCachingGhostObject_create();
pointer_t btGhostPairCallback_create();
void btTransform_equal(pointer_t ptr, pointer_t other);
void btTypedConstraint_setEnabled(pointer_t constraintptr, bool enabled);
void btCollisionWorld_addConstraint(pointer_t ptr, pointer_t constraintptr, bool disableCollisionsBetweenLinkedBodies);
void btCollisionWorld_removeConstraint(pointer_t ptr, pointer_t constraintptr);
pointer_t btJointFeedback_create();
void btJointFeedback_destroy(pointer_t jointFeedbackptr);
void btTypedConstraint_setJointFeedback(pointer_t constraintptr, pointer_t jointFeedbackptr);
pointer_t btTypedConstraint_getJointFeedback(pointer_t constraintptr);
void btTypedConstraint_enableFeedback(pointer_t constraintptr, bool needsFeedback);
void btTypedConstraint_setParam(pointer_t constraintptr, int axis1, int constraintParams, btScalar value);
void btTypedConstraint_setOverrideNumSolverIterations(pointer_t constraintptr, int overideNumIterations);
void btTypedConstraint_destroy(pointer_t constraintptr);
pointer_t btJointFeedback_getAppliedForceBodyA(pointer_t jointFeedbackptr);
pointer_t btJointFeedback_getAppliedForceBodyB(pointer_t jointFeedbackptr);
pointer_t btJointFeedback_getAppliedTorqueBodyA(pointer_t jointFeedbackptr);
pointer_t btJointFeedback_getAppliedTorqueBodyB(pointer_t jointFeedbackptr);
pointer_t btFixedConstraint_create(pointer_t rigidBodyA, pointer_t frameInAptr, pointer_t rigidBodyB, pointer_t frameInBptr);
pointer_t btGeneric6DofSpring2Constraint_create(pointer_t rigidBodyAptr, pointer_t frameInAptr, pointer_t rigidBodyBptr, pointer_t frameInBptr, int rotOrder = 0);
void btGeneric6DofSpring2Constraint_setAxis(pointer_t g6ds2Constraintptr, pointer_t axis1, pointer_t axis2);
void btGeneric6DofSpring2Constraint_setLimit(pointer_t g6ds2Constraintptr, int axis, btScalar lo, btScalar hi);
void btGeneric6DofSpring2Constraint_enableSpring(pointer_t g6ds2Constraintptr, int index, bool enableSpring);
void btGeneric6DofSpring2Constraint_setBounce(pointer_t g6ds2Constraintptr, int index, btScalar bounce);
void btGeneric6DofSpring2Constraint_setStiffness(pointer_t g6ds2Constraintptr, int index, btScalar stiffness, bool limitIfNeeded = true);
void btGeneric6DofSpring2Constraint_setDamping(pointer_t g6ds2Constraintptr, int index, btScalar damping, bool limitIfNeeded = true);
void btGeneric6DofSpring2Constraint_setEquilibriumPoint(pointer_t g6ds2Constraintptr, int index, btScalar val);
void btGeneric6DofSpring2Constraint_enableMotor(pointer_t g6ds2Constraintptr, int index, bool onOff);
void btGeneric6DofSpring2Constraint_setServo(pointer_t g6ds2Constraintptr, int index, bool onOff);
void btGeneric6DofSpring2Constraint_setTargetVelocity(pointer_t g6ds2Constraintptr, int index, btScalar velocity);
void btGeneric6DofSpring2Constraint_setServoTarget(pointer_t g6ds2Constraintptr, int index, btScalar target);
void btGeneric6DofSpring2Constraint_setMaxMotorForce(pointer_t g6ds2Constraintptr, int index, btScalar force);
void btGeneric6DofSpring2Constraint_setFrames(pointer_t g6ds2Constraintptr, pointer_t frameAptr, pointer_t frameBptr);
};
}
#endif
@@ -0,0 +1,260 @@
#include "LayaBulletExport.h"
namespace laya
{
ADDJSCLSINFO(JSLayaConchBullet, JSObjNode);
JSLayaConchBullet* JSLayaConchBullet::ms_pInstance = NULL;
//------------------------------------------------------------------------------
JSLayaConchBullet* JSLayaConchBullet::GetInstance()
{
if (ms_pInstance == NULL)
{
ms_pInstance = new JSLayaConchBullet();
}
return ms_pInstance;
}
JSLayaConchBullet::JSLayaConchBullet()
{
}
JSLayaConchBullet::~JSLayaConchBullet()
{
ms_pInstance = NULL;
}
void JSLayaConchBullet::exportJS()
{
JSP_GLOBAL_CLASS("layaConchBullet", JSLayaConchBullet);
JSP_ADD_METHOD("btGImpactCollisionAlgorithm_RegisterAlgorithm", JSLayaConchBullet::btGImpactCollisionAlgorithm_RegisterAlgorithm);
JSP_ADD_METHOD("btVector3_create", JSLayaConchBullet::btVector3_create);
JSP_ADD_METHOD("btVector3_setValue", JSLayaConchBullet::btVector3_setValue);
JSP_ADD_METHOD("btVector3_x", JSLayaConchBullet::btVector3_x);
JSP_ADD_METHOD("btVector3_y", JSLayaConchBullet::btVector3_y);
JSP_ADD_METHOD("btVector3_z", JSLayaConchBullet::btVector3_z);
JSP_ADD_METHOD("btQuaternion_create", JSLayaConchBullet::btQuaternion_create);
JSP_ADD_METHOD("btQuaternion_setValue", JSLayaConchBullet::btQuaternion_setValue);
JSP_ADD_METHOD("btQuaternion_x", JSLayaConchBullet::btQuaternion_x);
JSP_ADD_METHOD("btQuaternion_y", JSLayaConchBullet::btQuaternion_y);
JSP_ADD_METHOD("btQuaternion_z", JSLayaConchBullet::btQuaternion_z);
JSP_ADD_METHOD("btQuaternion_w", JSLayaConchBullet::btQuaternion_w);
JSP_ADD_METHOD("btTransform_create", JSLayaConchBullet::btTransform_create);
JSP_ADD_METHOD("btTransform_setOrigin", JSLayaConchBullet::btTransform_setOrigin);
JSP_ADD_METHOD("btTransform_setRotation", JSLayaConchBullet::btTransform_setRotation);
JSP_ADD_METHOD("btTransform_getOrigin", JSLayaConchBullet::btTransform_getOrigin);
JSP_ADD_METHOD("btTransform_getRotation", JSLayaConchBullet::btTransform_getRotation);
JSP_ADD_METHOD("btTransform_setIdentity", JSLayaConchBullet::btTransform_setIdentity);
JSP_ADD_METHOD("btTransform_equal", JSLayaConchBullet::btTransform_equal);
JSP_ADD_METHOD("btMotionState_destroy", JSLayaConchBullet::btMotionState_destroy);
JSP_ADD_METHOD("layaMotionState_create", JSLayaConchBullet::layaMotionState_create);
JSP_ADD_METHOD("layaMotionState_set_rigidBodyID", JSLayaConchBullet::layaMotionState_set_rigidBodyID);
JSP_ADD_METHOD("btCollisionObject_create", JSLayaConchBullet::btCollisionObject_create);
JSP_ADD_METHOD("btCollisionObject_setContactProcessingThreshold", JSLayaConchBullet::btCollisionObject_setContactProcessingThreshold);
JSP_ADD_METHOD("btCollisionObject_setActivationState", JSLayaConchBullet::btCollisionObject_setActivationState);
JSP_ADD_METHOD("btCollisionObject_forceActivationState", JSLayaConchBullet::btCollisionObject_forceActivationState);
JSP_ADD_METHOD("btCollisionObject_activate", JSLayaConchBullet::btCollisionObject_activate);
JSP_ADD_METHOD("btCollisionObject_isActive", JSLayaConchBullet::btCollisionObject_isActive);
JSP_ADD_METHOD("btCollisionObject_setRestitution", JSLayaConchBullet::btCollisionObject_setRestitution);
JSP_ADD_METHOD("btCollisionObject_setFriction", JSLayaConchBullet::btCollisionObject_setFriction);
JSP_ADD_METHOD("btCollisionObject_setRollingFriction", JSLayaConchBullet::btCollisionObject_setRollingFriction);
JSP_ADD_METHOD("btCollisionObject_getCollisionFlags", JSLayaConchBullet::btCollisionObject_getCollisionFlags);
JSP_ADD_METHOD("btCollisionObject_setCollisionFlags", JSLayaConchBullet::btCollisionObject_setCollisionFlags);
JSP_ADD_METHOD("btCollisionObject_getWorldTransform", JSLayaConchBullet::btCollisionObject_getWorldTransform);
JSP_ADD_METHOD("btCollisionObject_setCollisionShape", JSLayaConchBullet::btCollisionObject_setCollisionShape);
JSP_ADD_METHOD("btCollisionObject_getCcdMotionThreshold", JSLayaConchBullet::btCollisionObject_getCcdMotionThreshold);
JSP_ADD_METHOD("btCollisionObject_setCcdMotionThreshold", JSLayaConchBullet::btCollisionObject_setCcdMotionThreshold);
JSP_ADD_METHOD("btCollisionObject_getCcdSweptSphereRadius", JSLayaConchBullet::btCollisionObject_getCcdSweptSphereRadius);
JSP_ADD_METHOD("btCollisionObject_setCcdSweptSphereRadius", JSLayaConchBullet::btCollisionObject_setCcdSweptSphereRadius);
JSP_ADD_METHOD("btCollisionObject_getUserIndex", JSLayaConchBullet::btCollisionObject_getUserIndex);
JSP_ADD_METHOD("btCollisionObject_setUserIndex", JSLayaConchBullet::btCollisionObject_setUserIndex);
JSP_ADD_METHOD("btCollisionObject_getActivationState", JSLayaConchBullet::btCollisionObject_getActivationState);
JSP_ADD_METHOD("btCollisionObject_setInterpolationAngularVelocity", JSLayaConchBullet::btCollisionObject_setInterpolationAngularVelocity);
JSP_ADD_METHOD("btCollisionObject_setInterpolationLinearVelocity", JSLayaConchBullet::btCollisionObject_setInterpolationLinearVelocity);
JSP_ADD_METHOD("btCollisionObject_destroy", JSLayaConchBullet::btCollisionObject_destroy);
JSP_ADD_METHOD("RayResultCallback_set_m_flags", JSLayaConchBullet::RayResultCallback_set_m_flags);
JSP_ADD_METHOD("RayResultCallback_hasHit", JSLayaConchBullet::RayResultCallback_hasHit);
JSP_ADD_METHOD("RayResultCallback_set_m_collisionFilterGroup", JSLayaConchBullet::RayResultCallback_set_m_collisionFilterGroup);
JSP_ADD_METHOD("RayResultCallback_set_m_collisionFilterMask", JSLayaConchBullet::RayResultCallback_set_m_collisionFilterMask);
JSP_ADD_METHOD("RayResultCallback_get_m_closestHitFraction", JSLayaConchBullet::RayResultCallback_get_m_closestHitFraction);
JSP_ADD_METHOD("RayResultCallback_set_m_closestHitFraction", JSLayaConchBullet::RayResultCallback_set_m_closestHitFraction);
JSP_ADD_METHOD("RayResultCallback_get_m_collisionObject", JSLayaConchBullet::RayResultCallback_get_m_collisionObject);
JSP_ADD_METHOD("RayResultCallback_set_m_collisionObject", JSLayaConchBullet::RayResultCallback_set_m_collisionObject);
JSP_ADD_METHOD("ClosestRayResultCallback_create", JSLayaConchBullet::ClosestRayResultCallback_create);
JSP_ADD_METHOD("ClosestRayResultCallback_get_m_rayFromWorld", JSLayaConchBullet::ClosestRayResultCallback_get_m_rayFromWorld);
JSP_ADD_METHOD("ClosestRayResultCallback_set_m_rayFromWorld", JSLayaConchBullet::ClosestRayResultCallback_set_m_rayFromWorld);
JSP_ADD_METHOD("ClosestRayResultCallback_get_m_rayToWorld", JSLayaConchBullet::ClosestRayResultCallback_get_m_rayToWorld);
JSP_ADD_METHOD("ClosestRayResultCallback_set_m_rayToWorld", JSLayaConchBullet::ClosestRayResultCallback_set_m_rayToWorld);
JSP_ADD_METHOD("ClosestRayResultCallback_get_m_hitNormalWorld", JSLayaConchBullet::ClosestRayResultCallback_get_m_hitNormalWorld);
JSP_ADD_METHOD("ClosestRayResultCallback_get_m_hitPointWorld", JSLayaConchBullet::ClosestRayResultCallback_get_m_hitPointWorld);
JSP_ADD_METHOD("tBtCollisionObjectArray_size", JSLayaConchBullet::tBtCollisionObjectArray_size);
JSP_ADD_METHOD("tBtCollisionObjectArray_at", JSLayaConchBullet::tBtCollisionObjectArray_at);
JSP_ADD_METHOD("tBtCollisionObjectArray_clear", JSLayaConchBullet::tBtCollisionObjectArray_clear);
JSP_ADD_METHOD("tVector3Array_at", JSLayaConchBullet::tVector3Array_at);
JSP_ADD_METHOD("tVector3Array_clear", JSLayaConchBullet::tVector3Array_clear);
JSP_ADD_METHOD("tScalarArray_at", JSLayaConchBullet::tScalarArray_at);
JSP_ADD_METHOD("tScalarArray_clear", JSLayaConchBullet::tScalarArray_clear);
JSP_ADD_METHOD("AllHitsRayResultCallback_create", JSLayaConchBullet::AllHitsRayResultCallback_create);
JSP_ADD_METHOD("AllHitsRayResultCallback_get_m_rayFromWorld", JSLayaConchBullet::AllHitsRayResultCallback_get_m_rayFromWorld);
JSP_ADD_METHOD("AllHitsRayResultCallback_set_m_rayFromWorld", JSLayaConchBullet::AllHitsRayResultCallback_set_m_rayFromWorld);
JSP_ADD_METHOD("AllHitsRayResultCallback_get_m_rayToWorld", JSLayaConchBullet::AllHitsRayResultCallback_get_m_rayToWorld);
JSP_ADD_METHOD("AllHitsRayResultCallback_set_m_rayToWorld", JSLayaConchBullet::AllHitsRayResultCallback_set_m_rayToWorld);
JSP_ADD_METHOD("AllHitsRayResultCallback_get_m_hitPointWorld", JSLayaConchBullet::AllHitsRayResultCallback_get_m_hitPointWorld);
JSP_ADD_METHOD("AllHitsRayResultCallback_get_m_hitNormalWorld", JSLayaConchBullet::AllHitsRayResultCallback_get_m_hitNormalWorld);
JSP_ADD_METHOD("AllHitsRayResultCallback_get_m_collisionObjects", JSLayaConchBullet::AllHitsRayResultCallback_get_m_collisionObjects);
JSP_ADD_METHOD("AllHitsRayResultCallback_get_m_hitFractions", JSLayaConchBullet::AllHitsRayResultCallback_get_m_hitFractions);
JSP_ADD_METHOD("btManifoldPoint_get_m_positionWorldOnA", JSLayaConchBullet::btManifoldPoint_get_m_positionWorldOnA);
JSP_ADD_METHOD("btManifoldPoint_get_m_positionWorldOnB", JSLayaConchBullet::btManifoldPoint_get_m_positionWorldOnB);
JSP_ADD_METHOD("btManifoldPoint_get_m_normalWorldOnB", JSLayaConchBullet::btManifoldPoint_get_m_normalWorldOnB);
JSP_ADD_METHOD("btManifoldPoint_getDistance", JSLayaConchBullet::btManifoldPoint_getDistance);
JSP_ADD_METHOD("ConvexResultCallback_hasHit", JSLayaConchBullet::ConvexResultCallback_hasHit);
JSP_ADD_METHOD("ConvexResultCallback_set_m_collisionFilterGroup", JSLayaConchBullet::ConvexResultCallback_set_m_collisionFilterGroup);
JSP_ADD_METHOD("ConvexResultCallback_set_m_collisionFilterMask", JSLayaConchBullet::ConvexResultCallback_set_m_collisionFilterMask);
JSP_ADD_METHOD("ConvexResultCallback_get_m_closestHitFraction", JSLayaConchBullet::ConvexResultCallback_get_m_closestHitFraction);
JSP_ADD_METHOD("ConvexResultCallback_set_m_closestHitFraction", JSLayaConchBullet::ConvexResultCallback_set_m_closestHitFraction);
JSP_ADD_METHOD("ClosestConvexResultCallback_create", JSLayaConchBullet::ClosestConvexResultCallback_create);
JSP_ADD_METHOD("ClosestConvexResultCallback_get_m_hitNormalWorld", JSLayaConchBullet::ClosestConvexResultCallback_get_m_hitNormalWorld);
JSP_ADD_METHOD("ClosestConvexResultCallback_get_m_hitPointWorld", JSLayaConchBullet::ClosestConvexResultCallback_get_m_hitPointWorld);
JSP_ADD_METHOD("ClosestConvexResultCallback_get_m_hitCollisionObject", JSLayaConchBullet::ClosestConvexResultCallback_get_m_hitCollisionObject);
JSP_ADD_METHOD("ClosestConvexResultCallback_set_m_hitCollisionObject", JSLayaConchBullet::ClosestConvexResultCallback_set_m_hitCollisionObject);
JSP_ADD_METHOD("AllConvexResultCallback_create", JSLayaConchBullet::AllConvexResultCallback_create);
JSP_ADD_METHOD("AllConvexResultCallback_get_m_hitNormalWorld", JSLayaConchBullet::AllConvexResultCallback_get_m_hitNormalWorld);
JSP_ADD_METHOD("AllConvexResultCallback_get_m_hitPointWorld", JSLayaConchBullet::AllConvexResultCallback_get_m_hitPointWorld);
JSP_ADD_METHOD("AllConvexResultCallback_get_m_hitFractions", JSLayaConchBullet::AllConvexResultCallback_get_m_hitFractions);
JSP_ADD_METHOD("AllConvexResultCallback_get_m_collisionObjects", JSLayaConchBullet::AllConvexResultCallback_get_m_collisionObjects);
JSP_ADD_METHOD("btCollisionShape_getLocalScaling", JSLayaConchBullet::btCollisionShape_getLocalScaling);
JSP_ADD_METHOD("btCollisionShape_setLocalScaling", JSLayaConchBullet::btCollisionShape_setLocalScaling);
JSP_ADD_METHOD("btCollisionShape_calculateLocalInertia", JSLayaConchBullet::btCollisionShape_calculateLocalInertia);
JSP_ADD_METHOD("btCollisionShape_destroy", JSLayaConchBullet::btCollisionShape_destroy);
JSP_ADD_METHOD("btBoxShape_create", JSLayaConchBullet::btBoxShape_create);
JSP_ADD_METHOD("btCapsuleShape_create", JSLayaConchBullet::btCapsuleShape_create);
JSP_ADD_METHOD("btCapsuleShapeX_create", JSLayaConchBullet::btCapsuleShapeX_create);
JSP_ADD_METHOD("btCapsuleShapeZ_create", JSLayaConchBullet::btCapsuleShapeZ_create);
JSP_ADD_METHOD("btCylinderShape_create", JSLayaConchBullet::btCylinderShape_create);
JSP_ADD_METHOD("btCylinderShapeX_create", JSLayaConchBullet::btCylinderShapeX_create);
JSP_ADD_METHOD("btCylinderShapeZ_create", JSLayaConchBullet::btCylinderShapeZ_create);
JSP_ADD_METHOD("btSphereShape_create", JSLayaConchBullet::btSphereShape_create);
JSP_ADD_METHOD("btConeShape_create", JSLayaConchBullet::btConeShape_create);
JSP_ADD_METHOD("btConeShapeX_create", JSLayaConchBullet::btConeShapeX_create);
JSP_ADD_METHOD("btConeShapeZ_create", JSLayaConchBullet::btConeShapeZ_create);
JSP_ADD_METHOD("btStaticPlaneShape_create", JSLayaConchBullet::btStaticPlaneShape_create);
JSP_ADD_METHOD("btGImpactShapeInterface_updateBound", JSLayaConchBullet::btGImpactShapeInterface_updateBound);
JSP_ADD_METHOD("btGImpactMeshShape_create", JSLayaConchBullet::btGImpactMeshShape_create);
JSP_ADD_METHOD("btCompoundShape_create", JSLayaConchBullet::btCompoundShape_create);
JSP_ADD_METHOD("btCompoundShape_addChildShape", JSLayaConchBullet::btCompoundShape_addChildShape);
JSP_ADD_METHOD("btCompoundShape_removeChildShapeByIndex", JSLayaConchBullet::btCompoundShape_removeChildShapeByIndex);
JSP_ADD_METHOD("btCompoundShape_getChildShape", JSLayaConchBullet::btCompoundShape_getChildShape);
JSP_ADD_METHOD("btCompoundShape_updateChildTransform", JSLayaConchBullet::btCompoundShape_updateChildTransform);
JSP_ADD_METHOD("btStridingMeshInterface_destroy", JSLayaConchBullet::btStridingMeshInterface_destroy);
JSP_ADD_METHOD("btTriangleMesh_create", JSLayaConchBullet::btTriangleMesh_create);
JSP_ADD_METHOD("btTriangleMesh_addTriangle", JSLayaConchBullet::btTriangleMesh_addTriangle);
JSP_ADD_METHOD("btDefaultCollisionConfiguration_create", JSLayaConchBullet::btDefaultCollisionConfiguration_create);
JSP_ADD_METHOD("btDefaultCollisionConfiguration_destroy", JSLayaConchBullet::btDefaultCollisionConfiguration_destroy);
JSP_ADD_METHOD("btPersistentManifold_getBody0", JSLayaConchBullet::btPersistentManifold_getBody0);
JSP_ADD_METHOD("btPersistentManifold_getBody1", JSLayaConchBullet::btPersistentManifold_getBody1);
JSP_ADD_METHOD("btPersistentManifold_getNumContacts", JSLayaConchBullet::btPersistentManifold_getNumContacts);
JSP_ADD_METHOD("btPersistentManifold_getContactPoint", JSLayaConchBullet::btPersistentManifold_getContactPoint);
JSP_ADD_METHOD("btDispatcher_getNumManifolds", JSLayaConchBullet::btDispatcher_getNumManifolds);
JSP_ADD_METHOD("btDispatcher_getManifoldByIndexInternal", JSLayaConchBullet::btDispatcher_getManifoldByIndexInternal);
JSP_ADD_METHOD("btCollisionDispatcher_create", JSLayaConchBullet::btCollisionDispatcher_create);
JSP_ADD_METHOD("btCollisionDispatcher_destroy", JSLayaConchBullet::btCollisionDispatcher_destroy);
JSP_ADD_METHOD("btOverlappingPairCache_setInternalGhostPairCallback", JSLayaConchBullet::btOverlappingPairCache_setInternalGhostPairCallback);
JSP_ADD_METHOD("btDbvtBroadphase_create", JSLayaConchBullet::btDbvtBroadphase_create);
JSP_ADD_METHOD("btDbvtBroadphase_getOverlappingPairCache", JSLayaConchBullet::btDbvtBroadphase_getOverlappingPairCache);
JSP_ADD_METHOD("btDbvtBroadphase_destroy", JSLayaConchBullet::btDbvtBroadphase_destroy);
JSP_ADD_METHOD("btRigidBodyConstructionInfo_create", JSLayaConchBullet::btRigidBodyConstructionInfo_create);
JSP_ADD_METHOD("btRigidBodyConstructionInfo_destroy", JSLayaConchBullet::btRigidBodyConstructionInfo_destroy);
JSP_ADD_METHOD("btRigidBody_create", JSLayaConchBullet::btRigidBody_create);
JSP_ADD_METHOD("btRigidBody_setCenterOfMassTransform", JSLayaConchBullet::btRigidBody_setCenterOfMassTransform);
JSP_ADD_METHOD("btRigidBody_setSleepingThresholds", JSLayaConchBullet::btRigidBody_setSleepingThresholds);
JSP_ADD_METHOD("btRigidBody_getLinearSleepingThreshold", JSLayaConchBullet::btRigidBody_getLinearSleepingThreshold);
JSP_ADD_METHOD("btRigidBody_getAngularSleepingThreshold", JSLayaConchBullet::btRigidBody_getAngularSleepingThreshold);
JSP_ADD_METHOD("btRigidBody_setDamping", JSLayaConchBullet::btRigidBody_setDamping);
JSP_ADD_METHOD("btRigidBody_setMassProps", JSLayaConchBullet::btRigidBody_setMassProps);
JSP_ADD_METHOD("btRigidBody_setLinearFactor", JSLayaConchBullet::btRigidBody_setLinearFactor);
JSP_ADD_METHOD("btRigidBody_applyTorque", JSLayaConchBullet::btRigidBody_applyTorque);
JSP_ADD_METHOD("btRigidBody_applyForce", JSLayaConchBullet::btRigidBody_applyForce);
JSP_ADD_METHOD("btRigidBody_applyCentralForce", JSLayaConchBullet::btRigidBody_applyCentralForce);
JSP_ADD_METHOD("btRigidBody_applyTorqueImpulse", JSLayaConchBullet::btRigidBody_applyTorqueImpulse);
JSP_ADD_METHOD("btRigidBody_applyImpulse", JSLayaConchBullet::btRigidBody_applyImpulse);
JSP_ADD_METHOD("btRigidBody_applyCentralImpulse", JSLayaConchBullet::btRigidBody_applyCentralImpulse);
JSP_ADD_METHOD("btRigidBody_updateInertiaTensor", JSLayaConchBullet::btRigidBody_updateInertiaTensor);
JSP_ADD_METHOD("btRigidBody_getLinearVelocity", JSLayaConchBullet::btRigidBody_getLinearVelocity);
JSP_ADD_METHOD("btRigidBody_getAngularVelocity", JSLayaConchBullet::btRigidBody_getAngularVelocity);
JSP_ADD_METHOD("btRigidBody_setLinearVelocity", JSLayaConchBullet::btRigidBody_setLinearVelocity);
JSP_ADD_METHOD("btRigidBody_setAngularVelocity", JSLayaConchBullet::btRigidBody_setAngularVelocity);
JSP_ADD_METHOD("btRigidBody_setAngularFactor", JSLayaConchBullet::btRigidBody_setAngularFactor);
JSP_ADD_METHOD("btRigidBody_getGravity", JSLayaConchBullet::btRigidBody_getGravity);
JSP_ADD_METHOD("btRigidBody_setGravity", JSLayaConchBullet::btRigidBody_setGravity);
JSP_ADD_METHOD("btRigidBody_getTotalForce", JSLayaConchBullet::btRigidBody_getTotalForce);
JSP_ADD_METHOD("btRigidBody_getTotalTorque", JSLayaConchBullet::btRigidBody_getTotalTorque);
JSP_ADD_METHOD("btRigidBody_getFlags", JSLayaConchBullet::btRigidBody_getFlags);
JSP_ADD_METHOD("btRigidBody_setFlags", JSLayaConchBullet::btRigidBody_setFlags);
JSP_ADD_METHOD("btRigidBody_clearForces", JSLayaConchBullet::btRigidBody_clearForces);
JSP_ADD_METHOD("btSequentialImpulseConstraintSolver_create", JSLayaConchBullet::btSequentialImpulseConstraintSolver_create);
JSP_ADD_METHOD("btCollisionWorld_get_m_useContinuous", JSLayaConchBullet::btCollisionWorld_get_m_useContinuous);
JSP_ADD_METHOD("btCollisionWorld_set_m_useContinuous", JSLayaConchBullet::btCollisionWorld_set_m_useContinuous);
JSP_ADD_METHOD("btCollisionWorld_rayTest", JSLayaConchBullet::btCollisionWorld_rayTest);
JSP_ADD_METHOD("btCollisionWorld_getDispatchInfo", JSLayaConchBullet::btCollisionWorld_getDispatchInfo);
JSP_ADD_METHOD("btCollisionWorld_addCollisionObject", JSLayaConchBullet::btCollisionWorld_addCollisionObject);
JSP_ADD_METHOD("btCollisionWorld_removeCollisionObject", JSLayaConchBullet::btCollisionWorld_removeCollisionObject);
JSP_ADD_METHOD("btCollisionWorld_convexSweepTest", JSLayaConchBullet::btCollisionWorld_convexSweepTest);
JSP_ADD_METHOD("btCollisionWorld_destroy", JSLayaConchBullet::btCollisionWorld_destroy);
JSP_ADD_METHOD("btDynamicsWorld_addAction", JSLayaConchBullet::btDynamicsWorld_addAction);
JSP_ADD_METHOD("btDynamicsWorld_removeAction", JSLayaConchBullet::btDynamicsWorld_removeAction);
JSP_ADD_METHOD("btDynamicsWorld_getSolverInfo", JSLayaConchBullet::btDynamicsWorld_getSolverInfo);
JSP_ADD_METHOD("btDiscreteDynamicsWorld_create", JSLayaConchBullet::btDiscreteDynamicsWorld_create);
JSP_ADD_METHOD("btDiscreteDynamicsWorld_setGravity", JSLayaConchBullet::btDiscreteDynamicsWorld_setGravity);
JSP_ADD_METHOD("btDiscreteDynamicsWorld_getGravity", JSLayaConchBullet::btDiscreteDynamicsWorld_getGravity);
JSP_ADD_METHOD("btDiscreteDynamicsWorld_addRigidBody", JSLayaConchBullet::btDiscreteDynamicsWorld_addRigidBody);
JSP_ADD_METHOD("btDiscreteDynamicsWorld_removeRigidBody", JSLayaConchBullet::btDiscreteDynamicsWorld_removeRigidBody);
JSP_ADD_METHOD("btDiscreteDynamicsWorld_stepSimulation", JSLayaConchBullet::btDiscreteDynamicsWorld_stepSimulation);
JSP_ADD_METHOD("btDiscreteDynamicsWorld_clearForces", JSLayaConchBullet::btDiscreteDynamicsWorld_clearForces);
JSP_ADD_METHOD("btDiscreteDynamicsWorld_setApplySpeculativeContactRestitution", JSLayaConchBullet::btDiscreteDynamicsWorld_setApplySpeculativeContactRestitution);
JSP_ADD_METHOD("btDiscreteDynamicsWorld_getApplySpeculativeContactRestitution", JSLayaConchBullet::btDiscreteDynamicsWorld_getApplySpeculativeContactRestitution);
JSP_ADD_METHOD("btKinematicCharacterController_create", JSLayaConchBullet::btKinematicCharacterController_create);
JSP_ADD_METHOD("btKinematicCharacterController_setWalkDirection", JSLayaConchBullet::btKinematicCharacterController_setWalkDirection);
JSP_ADD_METHOD("btKinematicCharacterController_setFallSpeed", JSLayaConchBullet::btKinematicCharacterController_setFallSpeed);
JSP_ADD_METHOD("btKinematicCharacterController_setJumpSpeed", JSLayaConchBullet::btKinematicCharacterController_setJumpSpeed);
JSP_ADD_METHOD("btKinematicCharacterController_setMaxSlope", JSLayaConchBullet::btKinematicCharacterController_setMaxSlope);
JSP_ADD_METHOD("btKinematicCharacterController_onGround", JSLayaConchBullet::btKinematicCharacterController_onGround);
JSP_ADD_METHOD("btKinematicCharacterController_jump", JSLayaConchBullet::btKinematicCharacterController_jump);
JSP_ADD_METHOD("btKinematicCharacterController_setGravity", JSLayaConchBullet::btKinematicCharacterController_setGravity);
JSP_ADD_METHOD("btKinematicCharacterController_destroy", JSLayaConchBullet::btKinematicCharacterController_destroy);
JSP_ADD_METHOD("btPairCachingGhostObject_create", JSLayaConchBullet::btPairCachingGhostObject_create);
JSP_ADD_METHOD("btGhostPairCallback_create", JSLayaConchBullet::btGhostPairCallback_create);
JSP_ADD_METHOD("btKinematicCharacterController_setUp", JSLayaConchBullet::btKinematicCharacterController_setUp);
JSP_ADD_METHOD("btKinematicCharacterController_setStepHeight", JSLayaConchBullet::btKinematicCharacterController_setStepHeight);
JSP_ADD_METHOD("btCollisionObject_setInterpolationWorldTransform", JSLayaConchBullet::btCollisionObject_setInterpolationWorldTransform);
JSP_ADD_METHOD("btCollisionObject_setWorldTransform", JSLayaConchBullet::btCollisionObject_setWorldTransform);
JSP_ADD_METHOD("btTypedConstraint_setEnabled", JSLayaConchBullet::btTypedConstraint_setEnabled);
JSP_ADD_METHOD("btCollisionWorld_addConstraint", JSLayaConchBullet::btCollisionWorld_addConstraint);
JSP_ADD_METHOD("btCollisionWorld_removeConstraint", JSLayaConchBullet::btCollisionWorld_removeConstraint);
JSP_ADD_METHOD("btJointFeedback_create", JSLayaConchBullet::btJointFeedback_create);
JSP_ADD_METHOD("btJointFeedback_destroy", JSLayaConchBullet::btJointFeedback_destroy);
JSP_ADD_METHOD("btTypedConstraint_setJointFeedback", JSLayaConchBullet::btTypedConstraint_setJointFeedback);
JSP_ADD_METHOD("btTypedConstraint_getJointFeedback", JSLayaConchBullet::btTypedConstraint_getJointFeedback);
JSP_ADD_METHOD("btTypedConstraint_enableFeedback", JSLayaConchBullet::btTypedConstraint_enableFeedback);
JSP_ADD_METHOD("btTypedConstraint_setParam", JSLayaConchBullet::btTypedConstraint_setParam);
JSP_ADD_METHOD("btTypedConstraint_setOverrideNumSolverIterations", JSLayaConchBullet::btTypedConstraint_setOverrideNumSolverIterations);
JSP_ADD_METHOD("btTypedConstraint_destroy", JSLayaConchBullet::btTypedConstraint_destroy);
JSP_ADD_METHOD("btJointFeedback_getAppliedForceBodyA", JSLayaConchBullet::btJointFeedback_getAppliedForceBodyA);
JSP_ADD_METHOD("btJointFeedback_getAppliedForceBodyB", JSLayaConchBullet::btJointFeedback_getAppliedForceBodyB);
JSP_ADD_METHOD("btJointFeedback_getAppliedTorqueBodyA", JSLayaConchBullet::btJointFeedback_getAppliedTorqueBodyA);
JSP_ADD_METHOD("btJointFeedback_getAppliedTorqueBodyB", JSLayaConchBullet::btJointFeedback_getAppliedTorqueBodyB);
JSP_ADD_METHOD("btFixedConstraint_create", JSLayaConchBullet::btFixedConstraint_create);
JSP_ADD_METHOD("btGeneric6DofSpring2Constraint_create", JSLayaConchBullet::btGeneric6DofSpring2Constraint_create);
JSP_ADD_METHOD("btGeneric6DofSpring2Constraint_setAxis", JSLayaConchBullet::btGeneric6DofSpring2Constraint_setAxis);
JSP_ADD_METHOD("btGeneric6DofSpring2Constraint_setLimit", JSLayaConchBullet::btGeneric6DofSpring2Constraint_setLimit);
JSP_ADD_METHOD("btGeneric6DofSpring2Constraint_enableSpring", JSLayaConchBullet::btGeneric6DofSpring2Constraint_enableSpring);
JSP_ADD_METHOD("btGeneric6DofSpring2Constraint_setBounce", JSLayaConchBullet::btGeneric6DofSpring2Constraint_setBounce);
JSP_ADD_METHOD("btGeneric6DofSpring2Constraint_setStiffness", JSLayaConchBullet::btGeneric6DofSpring2Constraint_setStiffness);
JSP_ADD_METHOD("btGeneric6DofSpring2Constraint_setDamping", JSLayaConchBullet::btGeneric6DofSpring2Constraint_setDamping);
JSP_ADD_METHOD("btGeneric6DofSpring2Constraint_setEquilibriumPoint", JSLayaConchBullet::btGeneric6DofSpring2Constraint_setEquilibriumPoint);
JSP_ADD_METHOD("btGeneric6DofSpring2Constraint_enableMotor", JSLayaConchBullet::btGeneric6DofSpring2Constraint_enableMotor);
JSP_ADD_METHOD("btGeneric6DofSpring2Constraint_setServo", JSLayaConchBullet::btGeneric6DofSpring2Constraint_setServo);
JSP_ADD_METHOD("btGeneric6DofSpring2Constraint_setTargetVelocity", JSLayaConchBullet::btGeneric6DofSpring2Constraint_setTargetVelocity);
JSP_ADD_METHOD("btGeneric6DofSpring2Constraint_setServoTarget", JSLayaConchBullet::btGeneric6DofSpring2Constraint_setServoTarget);
JSP_ADD_METHOD("btGeneric6DofSpring2Constraint_setMaxMotorForce", JSLayaConchBullet::btGeneric6DofSpring2Constraint_setMaxMotorForce);
JSP_ADD_METHOD("btGeneric6DofSpring2Constraint_setFrames", JSLayaConchBullet::btGeneric6DofSpring2Constraint_setFrames);
JSP_INSTALL_GLOBAL_CLASS("layaConchBullet", JSLayaConchBullet, JSLayaConchBullet::GetInstance());
}
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,416 @@
#include "WinEditBox.h"
#include "../../source/conch/WindowsEnv/winWindows.h"
#include "util/Log.h"
extern HWND g_hWnd;
static HMENU IDL_EditBox = (HMENU) 100;
static void CheckError()
{
DWORD error = GetLastError();
if (error)
{
LOGE("[Error][Edit] Error no: %d", error);
}
}
static LRESULT CALLBACK EditWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
laya::WinEditBox* editBox = (laya::WinEditBox*) GetWindowLong(hWnd, GWL_USERDATA);
if (!editBox)
return true;
switch (message)
{
//case WM_SETFOCUS:
//{
// laya::WinControl* winCtrl = laya::WinCtrlEvtManager::Get(hWnd);
// if (winCtrl)
// {
// winCtrl->OnSetFocus();
// }
// break;
//}
//case WM_KILLFOCUS:
//{
// DestroyCaret();
// break;
//}
case WM_KEYDOWN:
case WM_KEYUP:
{
SendMessage(g_hWnd, message, wParam, lParam);
break;
}
case WM_NCCALCSIZE:
{
bool ret = editBox->OnNCCalcSize(wParam, lParam);
if (!ret)
{
return CallWindowProc(editBox->GetDefaultWndProc(), hWnd, message, wParam, lParam);
}
break;
}
case WM_NCPAINT:
{
bool ret = editBox->OnNCPaint(wParam, lParam);
if (!ret)
{
return CallWindowProc(editBox->GetDefaultWndProc(), hWnd, message, wParam, lParam);
}
break;
}
case WM_PAINT:
{
editBox->OnPaint();
break;
}
default:
return CallWindowProc(editBox->GetDefaultWndProc(), hWnd, message, wParam, lParam);
}
return true;
}
namespace laya {
/// style
void WinEditBox::Style::SetLeft(int val)
{
left = val;
UpdateSizeOrDirty();
}
void WinEditBox::Style::SetTop(int val)
{
top = val;
UpdateSizeOrDirty();
}
void WinEditBox::Style::SetWidth(int val)
{
width = val;
UpdateSizeOrDirty();
}
void WinEditBox::Style::SetHeight(int val)
{
height = val;
UpdateSizeOrDirty();
}
void WinEditBox::Style::SetFontSize(int val)
{
fontSize = val + 2;
if (m_owner->IsFocus())
{
m_owner->UpdateFont();
m_owner->ForceUpdateWindow();
}
else
{
isDirty = true;
}
}
void WinEditBox::Style::SetBgColor(COLORREF val)
{
bgColor = val;
UpdatePaintOrDirty();
}
void WinEditBox::Style::SetFontColor(COLORREF val)
{
fontColor = val;
UpdatePaintOrDirty();
}
void WinEditBox::Style::UpdatePaintOrDirty()
{
if (m_owner->IsFocus())
{
m_owner->ForceUpdateWindow();
}
else
{
isDirty = true;
}
}
void WinEditBox::Style::UpdateSizeOrDirty()
{
if (m_owner->IsFocus())
{
m_owner->UpdateSize();
m_owner->ForceUpdateWindow();
}
else
{
isDirty = true;
}
}
/// WinEditBox
WinEditBox::WinEditBox() :
m_hSingleEditWnd(0),
m_hMultiEditWnd(0),
m_isFocus(false),
m_isMultiLine(false),
m_isInitialized(false),
m_refCount(0),
m_defaultWndProc(NULL)
{
m_style = new Style(this);
m_font = CreateFont(m_style->fontSize, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_SWISS, TEXT("Arial"));
// Send Message for creating
SendMessage(g_hWnd, WMU_CREATE_CTRL, NULL, (LPARAM)this);
}
WinEditBox::~WinEditBox()
{
WinCtrlEvtManager::Remove(m_hSingleEditWnd);
WinCtrlEvtManager::Remove(m_hMultiEditWnd);
SetWindowLong(m_hSingleEditWnd, GWL_USERDATA, (LONG)0);
SetWindowLong(m_hMultiEditWnd, GWL_USERDATA, (LONG)0);
delete m_style;
m_style = nullptr;
DestroyWindow(m_hSingleEditWnd);
DestroyWindow(m_hMultiEditWnd);
}
void WinEditBox::Init()
{
if (!m_isInitialized)
{
m_isInitialized = true;
m_hSingleEditWnd = CreateWindow(WC_EDIT, TEXT(""), WS_CHILD | ES_AUTOHSCROLL, m_style->left, m_style->top, m_style->width, m_style->height, g_hWnd, IDL_EditBox, (HINSTANCE)GetWindowLong(g_hWnd, GWL_HINSTANCE), NULL);
m_hMultiEditWnd = CreateWindow(WC_EDIT, TEXT(""), WS_CHILD | ES_MULTILINE | ES_WANTRETURN, m_style->left, m_style->top, m_style->width, m_style->height, g_hWnd, IDL_EditBox, (HINSTANCE)GetWindowLong(g_hWnd, GWL_HINSTANCE), NULL);
CheckError();
if (m_isMultiLine)
{
m_defaultWndProc = (WNDPROC)SetWindowLong(m_hMultiEditWnd, GWL_WNDPROC, (LONG)EditWndProc);
}
else
{
m_defaultWndProc = (WNDPROC)SetWindowLong(m_hSingleEditWnd, GWL_WNDPROC, (LONG)EditWndProc);
}
SetWindowLong(m_hSingleEditWnd, GWL_USERDATA, (LONG)this);
SetWindowLong(m_hMultiEditWnd, GWL_USERDATA, (LONG)this);
WinCtrlEvtManager::Add(m_hSingleEditWnd, this);
WinCtrlEvtManager::Add(m_hMultiEditWnd, this);
}
}
void WinEditBox::UpdateSize()
{
::SetWindowPos(GetCurHWND(), NULL, m_style->left, m_style->top, m_style->width, m_style->height, NULL);
}
void WinEditBox::UpdateFont()
{
m_font = CreateFont(m_style->fontSize, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_SWISS, TEXT("Arial"));
SendMessage(GetCurHWND(), WM_SETFONT, (WPARAM)m_font, true);
}
void WinEditBox::SetFocus(bool isFocus)
{
if (m_isFocus == isFocus)
{
return;
}
m_isFocus = isFocus;
if (!GetCurHWND())
m_isFocus = false;
if (m_style->isDirty)
{
UpdateSize();
UpdateFont();
m_style->isDirty = false;
}
if (m_isFocus)
{
SetText(m_text.c_str());
}
if (m_isFocus)
{
::SetFocus(GetCurHWND());
ShowWindow(GetCurHWND(), true);
}
else
{
::SetFocus(NULL);
ShowWindow(GetCurHWND(), SW_HIDE);
}
ForceUpdateWindow();
}
void WinEditBox::SetMutiLine(bool val)
{
if (m_isMultiLine == val)
return;
SetWindowLong(GetCurHWND(), GWL_WNDPROC, (LONG)m_defaultWndProc);
m_isMultiLine = val;
m_defaultWndProc = (WNDPROC) SetWindowLong(GetCurHWND(), GWL_WNDPROC, (LONG)EditWndProc);
if (m_isFocus)
{
ShowWindow(m_hSingleEditWnd, !m_isMultiLine);
ShowWindow(m_hMultiEditWnd, m_isMultiLine);
}
ForceUpdateWindow();
}
void WinEditBox::ForceUpdateWindow()
{
RECT r;
GetClientRect(GetCurHWND(), &r);
InvalidateRect(GetCurHWND(), &r, true);
::UpdateWindow(GetCurHWND());
}
void WinEditBox::RenderClient()
{
PAINTSTRUCT paint;
HDC hdc = BeginPaint(GetCurHWND(), &paint);
SetBkColor(hdc, m_style->bgColor);
SetTextColor(hdc, m_style->fontColor);
SelectObject(hdc, m_font);
FillRect(hdc, &m_ncRect, CreateSolidBrush(m_style->bgColor));
DrawText(hdc, m_text.c_str(), -1, &m_ncRect, DT_LEFT | DT_TOP);
EndPaint(GetCurHWND(), &paint);
}
void WinEditBox::GetTextFromWindow()
{
int length = GetWindowTextLength(GetCurHWND());
m_text.resize(length + 1);
GetWindowText(GetCurHWND(), &(*m_text.begin()), length + 1);
}
const char* WinEditBox::GetText()
{
if (m_isFocus)
{
GetTextFromWindow();
}
return m_text.c_str();
}
void WinEditBox::SetText(const char* text)
{
m_text = text;
SetWindowText(GetCurHWND(), m_text.c_str());
if (m_isFocus)
{
ForceUpdateWindow();
}
}
void WinEditBox::OnPaint()
{
GetClientRect(GetCurHWND(), &m_ncRect);
RenderClient();
}
void WinEditBox::OnCtrlColor(HDC hdc)
{
if (!m_isMultiLine)
{
SetWindowPos(GetCurHWND(), NULL, 0, 0, 0, 0, SWP_NOOWNERZORDER | SWP_NOSIZE | SWP_NOMOVE | SWP_FRAMECHANGED);
}
SetBkColor(hdc, m_style->bgColor);
SetTextColor(hdc, m_style->fontColor);
}
bool WinEditBox::OnNCCalcSize(WPARAM wParam, LPARAM lParam)
{
if (m_isMultiLine)
return false;
bool isValid = (bool)wParam;
if (isValid)
{
RECT r;
GetClientRect(GetCurHWND(), &r);
LPNCCALCSIZE_PARAMS lpParams = (LPNCCALCSIZE_PARAMS)lParam;
lpParams->rgrc[0].top += (r.bottom - r.top) / 2;
}
return true;
}
bool WinEditBox::OnNCPaint(WPARAM wParam, LPARAM lParam)
{
if (m_isMultiLine)
return false;
RenderClient();
return true;
}
void WinEditBox::OnSetFocus()
{
//PAINTSTRUCT paint;
//RECT r;
//CopyRect(&r, &m_ncRect);
////HideCaret(m_hWnd);
//HDC hdc = BeginPaint(GetCurHWND(), &paint);
//DrawText(hdc, m_text.c_str(), -1, &r, DT_LEFT | DT_TOP | DT_CALCRECT);
//EndPaint(GetCurHWND(), &paint);
//HideCaret(GetCurHWND());
//CreateCaret(GetCurHWND(), NULL, 1, m_style->fontSize);
//SetCaretPos(r.right, r.top);
//ShowCaret(GetCurHWND());
}
void WinEditBox::Retain()
{
m_refCount++;
}
bool WinEditBox::Release()
{
m_refCount--;
if (m_refCount <= 0)
{
delete this;
return true;
}
return false;
}
};
@@ -0,0 +1,120 @@
#pragma once
#include <Windows.h>
#include <CommCtrl.h>
#include "../../source/conch/WindowsEnv/WinCtrl.h"
#include <string>
namespace laya {
class WinEditBox final : public WinControl{
public:
class Style {
public:
Style(WinEditBox* owner) : m_owner(owner)
{
bgColor = 0xffffff;
fontColor = 0x0;
left = -1000;
top = -1000;
width = 0;
height = 0;
fontSize = 10;
isDirty = false;
}
void SetLeft(int val);
void SetTop(int val);
void SetWidth(int val);
void SetHeight(int val);
void SetFontSize(int val);
void SetBgColor(COLORREF val);
void SetFontColor(COLORREF val);
private:
void UpdatePaintOrDirty();
void UpdateSizeOrDirty();
private:
friend class WinEditBox;
COLORREF bgColor;
COLORREF fontColor;
int left;
int top;
int width;
int height;
int fontSize;
bool isDirty;
WinEditBox* m_owner;
};
public:
WinEditBox();
virtual void Init() override;
virtual ControlType GetType() override { return CT_Edit; }
WNDPROC GetDefaultWndProc() const { return m_defaultWndProc; }
Style& GetStyle() { return *m_style; }
bool IsFocus() const { return m_isFocus; }
void SetFocus(bool isFocus);
void SetText(const char* text);
const char* GetText();
void SetMutiLine(bool val);
void ForceUpdateWindow();
// event
virtual void OnPaint() override;
virtual void OnCtrlColor(HDC hdc) override;
virtual void OnSetFocus() override;
bool OnNCCalcSize(WPARAM wParam, LPARAM lParam);
bool OnNCPaint(WPARAM wParam, LPARAM lParam);
// ref count
void Retain();
bool Release();
private:
void UpdateSize();
void UpdateFont();
void RenderClient();
void GetTextFromWindow();
HWND GetCurHWND() { return m_isMultiLine ? m_hMultiEditWnd : m_hSingleEditWnd;
}
private:
WinEditBox(const WinEditBox& other) = delete;
void operator=(const WinEditBox& other) = delete;
~WinEditBox();
private:
bool m_isInitialized;
bool m_isFocus;
std::string m_text;
bool m_isMultiLine;
Style* m_style;
HWND m_hSingleEditWnd;
HWND m_hMultiEditWnd;
HFONT m_font;
WNDPROC m_defaultWndProc;
RECT m_ncRect;
int m_refCount;
};
};
@@ -0,0 +1,387 @@
/**
@file JSAndroidEditBox.cpp
@brief
@author hugao
@version 1.0
@date 2016_5_19
*/
//包含头文件
#ifdef ANDROID
#include <jni.h>
#endif
#include "JSAndroidEditBox.h"
#include "../JSInterface/JSInterface.h"
#include "../../JCScriptRuntime.h"
#include "util/Log.h"
#ifdef ANDROID
#include "../../CToJavaBridge.h"
#endif
#include "util/JCColor.h"
namespace laya
{
ADDJSCLSINFO(JSAndroidEditBox, JSObjNode );
//------------------------------------------------------------------------------
JSAndroidEditBox::JSAndroidEditBox()
{
m_nLeft = 0;
m_nTop = 0;
m_nWidth = 0;
m_nHeight = 0;
m_fOpacity = 1;
m_sStyle = "";
m_sValue = "";
m_sType = "type";
m_nFontSize = 12;
m_nScaleX = 1;
m_nScaleY = 1;
m_bForbidEdit = false;
m_CallbackRef.reset(new int(1));
AdjustAmountOfExternalAllocatedMemory( 256 );
JCMemorySurvey::GetInstance()->newClass( "AndroidEditBox",256,this );
}
//------------------------------------------------------------------------------
JSAndroidEditBox::~JSAndroidEditBox()
{
JCMemorySurvey::GetInstance()->releaseClass( "AndroidEditBox",this );
}
//------------------------------------------------------------------------------
void JSAndroidEditBox::addEventListener(const char* p_sName, JSValueAsParam p_pFunction )
{
if(strcmp( p_sName,"input" ) == 0)
{
m_pJSFunctionOnInput.set(0,this,p_pFunction);
}
else if(strcmp( p_sName,"keydown" ) == 0)
{
//m_pJSFunctionOnKeydown=p_pFunction;
}
}
//------------------------------------------------------------------------------
int JSAndroidEditBox::set_Left( int p_nLeft )
{
m_nLeft = p_nLeft;
CToJavaBridge::JavaRet kRet;
CToJavaBridge::GetInstance()->callMethod(CToJavaBridge::JavaClass.c_str(), "setEditBoxPosX", p_nLeft, kRet);
return m_nLeft;
}
//------------------------------------------------------------------------------
int JSAndroidEditBox::get_Left()
{
return m_nLeft;
}
//------------------------------------------------------------------------------
int JSAndroidEditBox::set_Top( int p_nTop )
{
m_nTop = p_nTop;
CToJavaBridge::JavaRet kRet;
CToJavaBridge::GetInstance()->callMethod(CToJavaBridge::JavaClass.c_str(), "setEditBoxPosY", p_nTop, kRet);
return m_nTop;
}
//------------------------------------------------------------------------------
int JSAndroidEditBox::get_Top()
{
return m_nTop;
}
//------------------------------------------------------------------------------
int JSAndroidEditBox::set_Width( int p_nWidth )
{
m_nWidth = p_nWidth;
CToJavaBridge::JavaRet kRet;
CToJavaBridge::GetInstance()->callMethod(CToJavaBridge::JavaClass.c_str(), "setEditBoxWidth", (int)(p_nWidth * m_nScaleX), kRet);
return m_nWidth;
}
//------------------------------------------------------------------------------
int JSAndroidEditBox::get_Width()
{
return m_nWidth;
}
//-------------------------------------------false-----------------------------------
int JSAndroidEditBox::set_Height( int p_nHeight )
{
m_nHeight = p_nHeight;
CToJavaBridge::JavaRet kRet;
CToJavaBridge::GetInstance()->callMethod(CToJavaBridge::JavaClass.c_str(),"setEditBoxHeight",(int)(p_nHeight*m_nScaleY),kRet);
return m_nHeight;
}
//------------------------------------------------------------------------------
int JSAndroidEditBox::get_Height()
{
return m_nHeight;
}
//------------------------------------------------------------------------------
float JSAndroidEditBox::set_Opacity( float p_Opacity )
{
m_fOpacity = p_Opacity;
return m_fOpacity;
}
//------------------------------------------------------------------------------
float JSAndroidEditBox::get_Opacity()
{
return m_fOpacity;
}
//------------------------------------------------------------------------------
const char* JSAndroidEditBox::set_Value( const char* p_sValue )
{
LOGI("JSAndroidEditBox::set_Value=%s",p_sValue );
m_sValue = ( p_sValue != NULL ) ? p_sValue : "";
CToJavaBridge::JavaRet kRet;
CToJavaBridge::GetInstance()->callMethod(CToJavaBridge::JavaClass.c_str(), "setEditBoxValue", p_sValue, kRet);
return m_sValue.c_str();
}
//------------------------------------------------------------------------------
const char* JSAndroidEditBox::get_Value()
{
std::vector<intptr_t> params;
CToJavaBridge::JavaRet kRet;
if(CToJavaBridge::GetInstance()->callMethod(CToJavaBridge::JavaClass.c_str(), "getEditBoxValue", kRet))
{
m_sValue=CToJavaBridge::GetInstance()->getJavaString( kRet.pJNI,kRet.strRet);
LOGI("JSAndroidEditBox::get_Value=%s",m_sValue.c_str() );
}
return m_sValue.c_str();
}
//------------------------------------------------------------------------------
void JSAndroidEditBox::set_Style( const char* p_sStyle )
{
if(p_sStyle==NULL)
m_sStyle="";
else
m_sStyle = p_sStyle;
CToJavaBridge::JavaRet kRet;
CToJavaBridge::GetInstance()->callMethod(CToJavaBridge::JavaClass.c_str(), "setEditBoxStyle", m_sStyle.c_str(),kRet);
}
//------------------------------------------------------------------------------
const char* JSAndroidEditBox::get_Style()
{
return m_sStyle.c_str();
}
//------------------------------------------------------------------------------
bool JSAndroidEditBox::set_Visible( bool p_bVisible )
{
m_bVisible = p_bVisible;
CToJavaBridge::JavaRet kRet;
CToJavaBridge::GetInstance()->callMethod(CToJavaBridge::JavaClass.c_str(), "setEditBoxVisible", p_bVisible, kRet);
return m_bVisible;
}
//------------------------------------------------------------------------------
bool JSAndroidEditBox::get_Visible()
{
return m_bVisible;
}
//------------------------------------------------------------------------------
void JSAndroidEditBox::setLeft( int p_nLeft )
{
set_Left( p_nLeft );
}
//------------------------------------------------------------------------------
void JSAndroidEditBox::setTop( int p_nTop )
{
set_Top( p_nTop );
}
//------------------------------------------------------------------------------
void JSAndroidEditBox::setWidth( int p_nWidth )
{
set_Width( p_nWidth );
}
//------------------------------------------------------------------------------
void JSAndroidEditBox::setHeight( int p_nHeight )
{
set_Height( p_nHeight );
}
//------------------------------------------------------------------------------
void JSAndroidEditBox::setOpacity( float p_Opacity )
{
set_Opacity( p_Opacity );
}
//------------------------------------------------------------------------------
void JSAndroidEditBox::setValue( const char* p_sValue )
{
if(p_sValue==NULL)
set_Value("");
else
set_Value( p_sValue );
}
//------------------------------------------------------------------------------
const char* JSAndroidEditBox::getValue()
{
return get_Value();
}
//------------------------------------------------------------------------------
void JSAndroidEditBox::setStyle( const char* p_sStyle )
{
set_Style( p_sStyle );
}
//------------------------------------------------------------------------------
void JSAndroidEditBox::setVisible( bool p_bVisible )
{
set_Visible( p_bVisible );
}
//------------------------------------------------------------------------------
void JSAndroidEditBox::focus()
{
JCScriptRuntime::s_JSRT->m_pCurEditBox=this;
CToJavaBridge::JavaRet kRet;
CToJavaBridge::GetInstance()->callMethod( CToJavaBridge::JavaClass.c_str(), "setEditBoxFocus", kRet);
}
//------------------------------------------------------------------------------
void JSAndroidEditBox::blur()
{
CToJavaBridge::JavaRet kRet;
CToJavaBridge::GetInstance()->callMethod( CToJavaBridge::JavaClass.c_str(), "setEditBoxBlur", kRet);
JCScriptRuntime::s_JSRT->m_pCurEditBox = NULL;
}
//------------------------------------------------------------------------------
void JSAndroidEditBox::setColor( const char* p_sColor )
{
int nColor = JCColor::getColorUintFromString( p_sColor );
CToJavaBridge::JavaRet kRet;
CToJavaBridge::GetInstance()->callMethod(CToJavaBridge::JavaClass.c_str(), "setEditBoxColor", nColor, kRet);
}
//------------------------------------------------------------------------------
void JSAndroidEditBox::setFontSize( int p_nFontSize )
{
m_nFontSize = p_nFontSize;
CToJavaBridge::JavaRet kRet;
CToJavaBridge::GetInstance()->callMethod(CToJavaBridge::JavaClass.c_str(), "setEditBoxFontSize", (int)(p_nFontSize * m_nScaleY), kRet);
}
//------------------------------------------------------------------------------
void JSAndroidEditBox::setPos( int x,int y )
{
m_nLeft = x;
m_nTop = y;
CToJavaBridge::JavaRet kRet;
CToJavaBridge::GetInstance()->callMethod( CToJavaBridge::JavaClass.c_str(), "setEditBoxPos", x,y, kRet);
}
//------------------------------------------------------------------------------
void JSAndroidEditBox::setSize( int w,int h )
{
m_nWidth = w;
m_nHeight = h;
CToJavaBridge::JavaRet kRet;
CToJavaBridge::GetInstance()->callMethod( CToJavaBridge::JavaClass.c_str(), "setEditBoxSize", (int)(w * m_nScaleX), (int)(h * m_nScaleY), kRet);
}
//------------------------------------------------------------------------------
void JSAndroidEditBox::setCursorPosition( int pos )
{
CToJavaBridge::JavaRet kRet;
CToJavaBridge::GetInstance()->callMethod( CToJavaBridge::JavaClass.c_str(), "setEditBoxCursorPosition", pos, kRet);
}
//------------------------------------------------------------------------------
void JSAndroidEditBox::setScale( float p_nSx,float p_nSy )
{
m_nScaleX = p_nSx;
m_nScaleY = p_nSy;
setFontSize( m_nFontSize );
setSize( m_nWidth,m_nHeight );
}
//------------------------------------------------------------------------------
void JSAndroidEditBox::setMaxLength( int p_nMaxLength )
{
m_nMaxLength = p_nMaxLength;
CToJavaBridge::JavaRet kRet;
CToJavaBridge::GetInstance()->callMethod(CToJavaBridge::JavaClass.c_str(), "setEditBoxMaxLength", p_nMaxLength, kRet);
}
//------------------------------------------------------------------------------
void JSAndroidEditBox::setType( const char* p_sType )
{
m_sType = p_sType;
bool bPassword = false;
if( m_sType == "password" )
{
bPassword = true;
}
CToJavaBridge::JavaRet kRet;
CToJavaBridge::GetInstance()->callMethod( CToJavaBridge::JavaClass.c_str(), "setEditBoxPassword", bPassword, kRet);
}
//------------------------------------------------------------------------------
void JSAndroidEditBox::setRegular( const char* p_sRegular )
{
m_sRegular = p_sRegular;
CToJavaBridge::JavaRet kRet;
CToJavaBridge::GetInstance()->callMethod( CToJavaBridge::JavaClass.c_str(), "setEditBoxRegular", p_sRegular, kRet);
}
//------------------------------------------------------------------------------
void JSAndroidEditBox::setFont( const char* p_sFont )
{
}
//------------------------------------------------------------------------------
void JSAndroidEditBox::setNumberOnly( bool p_bNumberOnly )
{
CToJavaBridge::JavaRet kRet;
CToJavaBridge::GetInstance()->callMethod(CToJavaBridge::JavaClass.c_str(), "setEditBoxNumberOnly", p_bNumberOnly, kRet);
}
//------------------------------------------------------------------------------
void JSAndroidEditBox::onInputCallJSFunction(std::weak_ptr<int> callbackref)
{
if( !callbackref.lock())
return;
m_pJSFunctionOnInput.Call();
}
//------------------------------------------------------------------------------
void JSAndroidEditBox::onInput()
{
std::weak_ptr<int> cbref(m_CallbackRef);
std::function<void(void)> pFunction = std::bind(&JSAndroidEditBox::onInputCallJSFunction,this, cbref);
JCScriptRuntime::s_JSRT->m_pScriptThread->post( pFunction );
}
void JSAndroidEditBox::setMultiAble(bool p_bMultiAble)
{
CToJavaBridge::JavaRet kRet;
CToJavaBridge::GetInstance()->callMethod(CToJavaBridge::JavaClass.c_str(),"setMultiAble",p_bMultiAble,kRet);
}
void JSAndroidEditBox::setForbidEdit( bool bForbidEdit )
{
m_bForbidEdit = bForbidEdit;
CToJavaBridge::JavaRet kRet;
CToJavaBridge::GetInstance()->callMethod(CToJavaBridge::JavaClass.c_str(), "setForbidEdit", bForbidEdit, kRet);
}
bool JSAndroidEditBox::getForbidEdit()
{
return m_bForbidEdit;
}
void JSAndroidEditBox::exportJS()
{
JSP_CLASS("ConchInput", JSAndroidEditBox);
JSP_ADD_PROPERTY(left, JSAndroidEditBox, get_Left, set_Left);//2
JSP_ADD_PROPERTY(top, JSAndroidEditBox, get_Top, set_Top);//2
JSP_ADD_PROPERTY(width, JSAndroidEditBox, get_Width, set_Width);//2
JSP_ADD_PROPERTY(height, JSAndroidEditBox, get_Height, set_Height);//2
JSP_ADD_PROPERTY(opacity, JSAndroidEditBox, get_Opacity, set_Opacity);//2
JSP_ADD_PROPERTY(style, JSAndroidEditBox, get_Style, set_Style);
JSP_ADD_PROPERTY(value, JSAndroidEditBox, get_Value, set_Value);//2
JSP_ADD_PROPERTY(visible, JSAndroidEditBox, get_Visible, set_Visible);//2
JSP_ADD_METHOD("addEventListener", JSAndroidEditBox::addEventListener);
JSP_ADD_METHOD("setLeft", JSAndroidEditBox::setLeft);
JSP_ADD_METHOD("setTop", JSAndroidEditBox::setTop);
JSP_ADD_METHOD("setWidth", JSAndroidEditBox::setWidth);
JSP_ADD_METHOD("setHeight", JSAndroidEditBox::setHeight);
JSP_ADD_METHOD("setOpacity", JSAndroidEditBox::setOpacity);
JSP_ADD_METHOD("setValue", JSAndroidEditBox::setValue);
JSP_ADD_METHOD("getValue", JSAndroidEditBox::getValue);
JSP_ADD_METHOD("setStyle", JSAndroidEditBox::setStyle);
JSP_ADD_METHOD("setVisible", JSAndroidEditBox::setVisible);
JSP_ADD_METHOD("focus", JSAndroidEditBox::focus);
JSP_ADD_METHOD("blur", JSAndroidEditBox::blur);
JSP_ADD_METHOD("setColor", JSAndroidEditBox::setColor);
JSP_ADD_METHOD("setFontSize", JSAndroidEditBox::setFontSize);
JSP_ADD_METHOD("setPos", JSAndroidEditBox::setPos);
JSP_ADD_METHOD("setSize", JSAndroidEditBox::setSize);
JSP_ADD_METHOD("setCursorPosition", JSAndroidEditBox::setCursorPosition);
JSP_ADD_METHOD("setScale", JSAndroidEditBox::setScale);
JSP_ADD_METHOD("setMaxLength", JSAndroidEditBox::setMaxLength);
JSP_ADD_METHOD("setType", JSAndroidEditBox::setType);
JSP_ADD_METHOD("setNumberOnly", JSAndroidEditBox::setNumberOnly);
JSP_ADD_METHOD("setRegular", JSAndroidEditBox::setRegular);
JSP_ADD_METHOD("setFont", JSAndroidEditBox::setFont);
JSP_ADD_METHOD("setMultiAble", JSAndroidEditBox::setMultiAble);
JSP_ADD_METHOD("setForbidEdit",JSAndroidEditBox::setForbidEdit);
JSP_ADD_METHOD("getForbidEdit",JSAndroidEditBox::getForbidEdit);
JSP_INSTALL_CLASS("ConchInput", JSAndroidEditBox);
}
}
//------------------------------------------------------------------------------
//-----------------------------END FILE--------------------------------
@@ -0,0 +1,158 @@
/**
@file JSAndroidEditBox.h
@brief
@author hugao
@version 1.0
@date 2016_5_19
*/
#ifndef __JSAndroidEditBox_H__
#define __JSAndroidEditBox_H__
//包含头文件
//------------------------------------------------------------------------------
#include <stdio.h>
#include <string>
#include "../JSInterface/JSInterface.h"
/**
* @brief
*/
namespace laya
{
class JSAndroidEditBox:public JsObjBase, public JSObjNode
{
public:
static JsObjClassInfo JSCLSINFO;
void JSConstructor(JsFuncArgs& args) {};
static void exportJS();
JSAndroidEditBox();
~JSAndroidEditBox();
public:
int set_Left( int p_nLeft );
int get_Left();
int set_Top( int p_nTop );
int get_Top();
int set_Width( int p_nWidth );
int get_Width();
int set_Height( int p_nHeight );
int get_Height();
float set_Opacity( float p_Opacity );
float get_Opacity();
const char* set_Value( const char* p_sValue );
const char* get_Value();
void set_Style( const char* p_sStyle );
const char* get_Style();
bool set_Visible( bool p_bVisible );
bool get_Visible();
public:
void setColor( const char* p_sColor );
void setFontSize( int p_nFontSize );
void setPos( int x,int y );
void setSize( int w,int h );
void setCursorPosition( int pos );
void setLeft( int p_nLeft );
void setTop( int p_nTop );
void setWidth( int p_nWidth );
void setHeight( int p_nHeight );
void setOpacity( float p_Opacity );
void setValue( const char* p_sValue );
const char* getValue();
void setStyle( const char* p_sStyle );
void setVisible( bool p_bVisible );
void setFont( const char* p_sFont );
void focus();
void blur();
void setForbidEdit( bool bForbidEdit );
bool getForbidEdit();
public:
void setScale( float p_nSx,float p_nSy );
void setMaxLength( int p_nMaxLength );
void setType( const char* p_sType );
void setRegular( const char* p_sRegular );
void setNumberOnly( bool p_bNumberOnly );
void addEventListener(const char* p_sName, JSValueAsParam p_pFunction );
void setMultiAble(bool p_bMultiAble);
void onInputCallJSFunction(std::weak_ptr<int> callbackref);
void onInput();
public:
int m_nLeft;
int m_nTop;
int m_nWidth;
int m_nHeight;
bool m_bVisible;
float m_fOpacity;
int m_nMaxLength;
int m_nFontSize;
float m_nScaleX;
float m_nScaleY;
std::string m_sType;
std::string m_sStyle;
std::string m_sValue;
std::string m_sRegular;
bool m_bForbidEdit;
private:
std::shared_ptr<int> m_CallbackRef;
JsObjHandle m_pJSFunctionOnInput;//JS的回调 //4
};
}
//------------------------------------------------------------------------------
#endif //__JSAndroidEditBox_H__
//-----------------------------END FILE--------------------------------
@@ -0,0 +1,478 @@
/**
@file JSAppCache.cpp
@brief
@author James
@version 1.0
@date 2017_11_28
*/
#include "JSAppCache.h"
#include "downloadCache/JCServerFileCache.h"
#include "fileSystem/JCFileSystem.h"
#include "resource/JCFileResManager.h"
#include "util/Log.h"
#include "JSFile.h"
#include "../../JCScriptRuntime.h"
#include "util/JCSimpleCRC.h"
#include "downloadCache/JCFileSource.h"
extern std::string gRedistPath;
#ifdef _DEBUG
#define VERIFY(a,msg) {if(!(a)){LOGE(msg); throw -1;};}
#else
#define VERIFY(a,msg)
#endif
namespace laya
{
char* GlobalTransUrl(void* pData, const char* pUrl)
{
JsAppCache* pCache = (JsAppCache*)pData;
if (pCache)
{
return pCache->getTransedUrl(pUrl);
}
return nullptr;
}
ADDJSCLSINFO(JsAppCache, JSObjNode);
JsAppCache::JsAppCache()
{
//大概估算内部变量
AdjustAmountOfExternalAllocatedMemory( 1024 );
m_bEnableCache=true;
m_pSvFileCache = new JCServerFileCache();
m_pSvFileCache->m_pFuncTransUrl = GlobalTransUrl;
m_pSvFileCache->m_pFuncTransUrlData = this;
m_pSvFileCache->setCachePath((gRedistPath + "/appCache").c_str());
if (JCScriptRuntime::s_JSRT->m_pFileResMgr)
{
JCFileResManager* pFileResManager = JCScriptRuntime::s_JSRT->m_pFileResMgr;
//TODO 这段代码有点恶心,日后再整理
//为了刷新的时候,再次设置fileCache,所以要把原来的删除掉
if (pFileResManager->m_pFileCache)
{
delete pFileResManager->m_pFileCache;
pFileResManager->m_pFileCache = NULL;
}
pFileResManager->setFileCache(m_pSvFileCache);
}
}
JsAppCache::JsAppCache(const char* p_pszURL)
{
//大概估算内部变量
AdjustAmountOfExternalAllocatedMemory( 1024 );
m_bEnableCache=true;
m_strURL = p_pszURL;
m_pSvFileCache = new JCServerFileCache();
m_pSvFileCache->m_pFuncTransUrl = GlobalTransUrl;
m_pSvFileCache->m_pFuncTransUrlData = this;
m_pSvFileCache->setCachePath((gRedistPath + "/appCache").c_str());
if (JCScriptRuntime::s_JSRT->m_pFileResMgr)
{
JCFileResManager* pFileResManager = JCScriptRuntime::s_JSRT->m_pFileResMgr;
//TODO 这段代码有点恶心,日后再整理
//为了刷新的时候,再次设置fileCache,所以要把原来的删除掉
if (pFileResManager->m_pFileCache)
{
delete pFileResManager->m_pFileCache;
pFileResManager->m_pFileCache = NULL;
}
pFileResManager->setFileCache(m_pSvFileCache);
}
m_pSvFileCache->switchToApp(p_pszURL);
AdjustAmountOfExternalAllocatedMemory( 12+13+128);
JCMemorySurvey::GetInstance()->newClass( "AppCache",12+13+128,this );
}
JsAppCache::~JsAppCache()
{
JCMemorySurvey::GetInstance()->releaseClass( "AppCache",this );
//TODO 这段代码有点恶心,日后再整理
//删除这个svFileCache不能在这删除,因为渲染线程还在运行,所以放到渲染线程删除FileResManager的时候删除了
//但是这个JCAppCache有多个,就会有内存泄露
/*
if (m_pSvFileCache != NULL)
{
delete m_pSvFileCache;
}
*/
m_pSvFileCache = NULL;
}
unsigned int JsAppCache::getCacheSize()
{
return 0;
}
std::string JsAppCache::getCachePath()
{
return m_pSvFileCache->getAppPath();
}
bool JsAppCache::getEnableCache()
{
return m_bEnableCache;
}
void JsAppCache::setEnableCache(bool b )
{
m_bEnableCache = b;
}
void onCheckOKRunInJs(JsAppCache* pobj)
{
pobj->m_funcCheckOK.Call();
}
void onCheckErrorRunInJs(JsAppCache* pobj, const char* pError)
{
pobj->m_funcCheckError.Call();
}
void onCheckOK(JsAppCache* pobj)
{
std::function<void()> pFunction = std::bind(onCheckOKRunInJs,pobj);
//JSConch::GetInstance()->postFuncToJSThread(pFunction);
}
void onCheckError(JsAppCache* pobj)
{
std::function<void()> pFunction = std::bind(onCheckErrorRunInJs,pobj,"");
//JSConch::GetInstance()->postFuncToJSThread(pFunction);
}
void JsAppCache::update( const char* p_pszDccURL, unsigned int p_ulCheckSum, JSValueAsParam p_pFuncCheckOK, JSValueAsParam p_pFuncCheckError )
{
/*
JCDownloadManager* pDown = JCDownloadManager::GetInstance();
if( pDown )
{
m_funcCheckOK = *p_pFuncCheckOK;
m_funcCheckError = *p_pFuncCheckError;
if( !m_bEnableCache )
{
onCheckOK(this);
}
else
{
pDown->m_onWebCheckOK = std::bind( onCheckOK, this );
pDown->m_onWebCheckError = std::bind( onCheckError, this );
pDown->checkWeb(p_pszDccURL, m_strURL.c_str(), p_ulCheckSum );
}
}
*/
}
bool JsAppCache::updateFileForJs(int p_nFileID, unsigned int p_nCheckSum,JSValueAsParam p_pBuffer, bool p_bExtVersion)
{
char* pABPtr = NULL;
int nABLen = 0;
bool isab = extractJSAB(p_pBuffer, pABPtr, nABLen);
if (pABPtr && nABLen > 0)
{
return updateFile(p_nFileID, p_nCheckSum, pABPtr, nABLen, p_bExtVersion);
}
else
{
return false;
}
}
bool JsAppCache::updateFile(int p_nFileID, unsigned int p_ulChkSum,const char* p_pBuffer, int len, bool p_bExtVersion)
{
if (p_pBuffer == NULL || len <= 0)
return false;
if (p_ulChkSum == 0)
{
p_ulChkSum = JCCachedFileSys::getChkSum((char*)p_pBuffer, len);
}
/*
unsigned int localid=0;
if (strstr(p_pszUrl, "http://"))
{
localid = m_pSvFileCache->hashURLFull(p_pszUrl);
}
else
{
localid = m_pSvFileCache->hashURLR(p_pszUrl);
}
*/
if (p_bExtVersion)
{
m_pSvFileCache->updateAFile(p_nFileID, (char*)p_pBuffer, len, p_ulChkSum,
true, 0, false);
return true;
}
else
{
unsigned int chk = 0;
if (m_pSvFileCache->getFileInfo(p_nFileID, chk))
{
if (p_ulChkSum != chk)
{
LOGE("updateFileErr:S:%x R:%x", chk, p_ulChkSum);
return false;
}
m_pSvFileCache->updateAFile(p_nFileID, (char*)p_pBuffer, len, p_ulChkSum,false, 0, false);
return true;
}
LOGE("updateFile error, not in table:%x", p_nFileID);
}
return false;
}
std::string JsAppCache::url2Local(const char* p_pszURL )
{
return "";
}
void JsAppCache::setResourceID(const char* p_pszResource, const char* p_pszVal)
{
return m_pSvFileCache->setResourceID(p_pszResource, p_pszVal);
}
std::string JsAppCache::getResourceID(const char* p_pszResource )
{
return m_pSvFileCache->getResourceID(p_pszResource);
}
void JsAppCache::saveFileTable(const char* p_pszFileContent)
{
m_pSvFileCache->saveFileTable(p_pszFileContent);
}
void JsAppCache::setFileTable(const char* p_pszFileContent)
{
m_pSvFileCache->setFileTables(p_pszFileContent);
}
void JsAppCache::setUrlTransTable(const char* p_pszFileContent,int split)
{
m_pSvFileCache->setUrlTransTable(p_pszFileContent,(char)split);
}
void JsAppCache::setTransUrlToCachedUrl(JSValueAsParam pObj)
{
m_funcTransUrl.set(transUrlFun, this, pObj);
}
char* JsAppCache::getTransedUrl(const char* pUrl)
{
if (!m_funcTransUrl.Empty())
{
m_funcTransUrl.Call(pUrl);
return __TransferToCpp<char*>::ToCpp(m_funcTransUrl.m_pReturn);
}
return nullptr;
}
std::string JsAppCache::loadCachedURL( const char* p_pszUrl )
{
JCFileResManager* pfsMgr = JCScriptRuntime::s_JSRT->m_pFileResMgr;
laya::JCFileRes* res = pfsMgr->getRes(p_pszUrl);
JCBuffer buff;
std::string strOut="";
if( res->loadFromCache(buff,false) && buff.m_pPtr)
{
if (buff.m_nLen >= 3 && ((*(int*)(buff.m_pPtr)) & 0x00ffffff) == 0xbfbbef)
{
strOut.append(buff.m_pPtr+3, buff.m_nLen-3);
}
else
{
strOut.append(buff.m_pPtr, buff.m_nLen);
}
}
else
{
LOGE("JsAppCache::loadCachedURL Error, no cache data.");
}
//LOGE("loadCachedURL:%s,%s", p_pszUrl, strOut.c_str());
return strOut;
}
bool JsAppCache::isFileTableValid()
{
std::string file = m_pSvFileCache->getAppPath()+"/"+"filetable.txt";
JCBuffer buf;
if(!readFileSync(file.c_str(),buf))
return false;
if(buf.m_nLen<=0)
return false;
return true;
}
extern unsigned char* AllocSharedBuffer(int sz, void* pUserData);
bool JsAppCache::isUrlNeedDownload(const char* p_pszFile) {
JCCachedFileSys::fileShell fs;
time_t tm;
unsigned int chksumInFS = 0;
unsigned int id = m_pSvFileCache->getFileID(p_pszFile);
std::string pathstr;
std::string file = m_pSvFileCache->m_FileSys.fileToPath(id, pathstr, false);
// 读取本地缓存中保存的校验值
if (!m_pSvFileCache->loadShell(file.c_str(), fs, tm)) {
JCFileSource* pAssets = m_pSvFileCache->getAssets();
std::string obbPath = m_pSvFileCache->m_FileSys.fileToStr(id, true);
if (pAssets && pAssets->isFileExist(obbPath.c_str())) {
JCSharedBuffer p_BufRet;
int sz;
if (pAssets->loadFileContent(obbPath.c_str(), AllocSharedBuffer, (void*)&p_BufRet, sz)) {
//生成校验码
JCSimpleCRC crc;
crc.process_bytes(p_BufRet.m_pBuffer.get(), sz);
chksumInFS = crc.checksum();
}
else {
return true;
}
}
else {
// 读取缓存失败,要重新下载
return true;
}
}
else {
chksumInFS = fs.chkSum;
}
// 获得dcc表中保存的校验值
unsigned int chksumInDcc;
if (m_pSvFileCache->getFileInfo(id, chksumInDcc)) {
// 两个校验值不相等就需要下载
return chksumInDcc != chksumInFS;
}
else {
// dcc中没有,需要下载
return true;
}
}
//返回的是一个array,元素类型为 {path:string,url:string}
JsValue JsAppCache::getAppList()
{
std::vector <std::string> paths;
std::string path = m_pSvFileCache->getAppPath();
//要去掉 sessionFiles
fs::path full_path(path.c_str());
full_path.remove_filename();
if (fs::exists(full_path))
{
fs::directory_iterator item_begin(full_path);
fs::directory_iterator item_end;
for (; item_begin != item_end; item_begin++)
{
if (fs::is_directory(*item_begin))
{
auto urlid = (*item_begin).path() / "sourceid" / "appurl";
fs::path apppath = (*item_begin).path().filename();
paths.push_back(apppath.generic_string()); //先是实际路径,然后是对应的url,如果没有,对应的url就是""
std::string url = "";
if (fs::exists(urlid))
{
JCBuffer buf;
if (readFileSync(urlid.generic_string().c_str(), buf, JCBuffer::utf8)) {
url = buf.m_pPtr;
paths.push_back(url);
}
}
if(url.length()<=0)
{
paths.push_back("");
}
}
else
{
//文件怎么处理
}
}
}
#ifdef JS_V8
//现在提供的转换不太方便转vector<string>,所以先自己写一个
int size = (int)paths.size();
v8::Isolate* piso = mpJsIso;
if (0 == size){
v8::Handle<v8::Array> array = v8::Array::New(piso, 0);
return array;
}
else {
Handle<Array> array = Array::New(piso, size);
v8::HandleScope sc(mpJsIso);
for (int i = 0; i < size/2; i++) {
v8::Local<Object> retobj = v8::Object::New(mpJsIso);
std::string& path = paths[i * 2];
std::string& url = paths[i * 2 + 1];
retobj->Set(Js_Str(mpJsIso, "path"), Js_Str(mpJsIso,(const char*)path.c_str()));
if (url.length() > 0)
retobj->Set(Js_Str(mpJsIso, "url"), Js_Str(mpJsIso, (const char*)url.c_str()));
else
retobj->Set(Js_Str(mpJsIso, "url"), v8::Null(mpJsIso));
//array->Set(i, __TransferToJs<const char*>::ToJs(paths[i].c_str()));
array->Set(i, retobj);
}
return array;
}
#elif JS_JSC
int size = (int)paths.size();
JSContextRef ctx = __TlsData::GetInstance()->GetCurContext();
if (0 == size){
JSObjectRef array = JSObjectMakeArray(ctx, 0, nullptr, nullptr);
return array;
}
else {
size = size/2;
std::vector<JSValueRef> arguments;
arguments.reserve(size);
for (int i = 0; i < size; i++){
JSObjectRef retobj = JSObjectMake(ctx, nullptr, nullptr);
std::string& path = paths[i * 2];
std::string& url = paths[i * 2 + 1];
JSStringRef jsstrKeyPath = JSStringCreateWithUTF8CString("path");
JSStringRef jsstrKeyUrl = JSStringCreateWithUTF8CString("url");
JSStringRef jsstrValuePath = JSStringCreateWithUTF8CString((const char*)path.c_str());
JSStringRef jsstrValueUrl = JSStringCreateWithUTF8CString((const char*)url.c_str());
JSObjectSetProperty(ctx, retobj, jsstrKeyPath, JSValueMakeString(ctx,jsstrValuePath), kJSPropertyAttributeNone, nullptr);
if (url.length() > 0)
JSObjectSetProperty(ctx, retobj, jsstrKeyUrl, JSValueMakeString(ctx,jsstrValueUrl), kJSPropertyAttributeNone, nullptr);
else
JSObjectSetProperty(ctx, retobj, jsstrKeyUrl, JSValueMakeNull(ctx), kJSPropertyAttributeNone, nullptr);
arguments[i] = retobj;
}
JSObjectRef array= JSObjectMakeArray(ctx, size,&arguments[0], nullptr);
return array;
}
#endif
}
int64_t JsAppCache::getAppSize(const char* appurl)
{
return 0;
}
void JsAppCache::delCurAppCache()
{
m_pSvFileCache->clearAllCachedFile();
}
bool JsAppCache::delAppCache(const char* appurl)
{
m_pSvFileCache->clearAllCachedFile();
return false;
}
void JsAppCache::delAllCache()
{
}
int JsAppCache::hashString(const char* str)
{
return JCCachedFileSys::hashRaw(str);
}
void JsAppCache::exportJS()
{
JSP_CLASS("AppCache", JsAppCache);
JSP_ADD_PROPERTY_RO(cacheSize, JsAppCache, getCacheSize);
JSP_ADD_METHOD("update", JsAppCache::update)
JSP_ADD_METHOD("url2Local", JsAppCache::url2Local);
JSP_ADD_PROPERTY(enableCache, JsAppCache, getEnableCache, setEnableCache);
JSP_ADD_METHOD("getResourceID", JsAppCache::getResourceID);
JSP_ADD_METHOD("setResourceID", JsAppCache::setResourceID);
JSP_ADD_METHOD("saveFileTable", JsAppCache::saveFileTable);
JSP_ADD_METHOD("setFileTable", JsAppCache::setFileTable);
JSP_ADD_METHOD("setUrlTransTable", JsAppCache::setUrlTransTable);
JSP_ADD_METHOD("transUrlToCachedUrl", JsAppCache::setTransUrlToCachedUrl);
JSP_ADD_METHOD("loadCachedURL", JsAppCache::loadCachedURL);
JSP_ADD_METHOD("getCachePath", JsAppCache::getCachePath);
JSP_ADD_METHOD("isFileTableValid", JsAppCache::isFileTableValid); //为了打补丁用的
JSP_ADD_METHOD("getAppList", JsAppCache::getAppList);
JSP_ADD_METHOD("getAppSize", JsAppCache::getAppSize);
JSP_ADD_METHOD("delAppCache", JsAppCache::delAppCache);
JSP_ADD_METHOD("delCurAppCache", JsAppCache::delCurAppCache);
JSP_ADD_METHOD("delAllCache", JsAppCache::delAllCache);
JSP_ADD_METHOD("updateFile", JsAppCache::updateFileForJs);
JSP_ADD_METHOD("hashstr", JsAppCache::hashString);
JSP_ADD_METHOD("isUrlNeedDownload", JsAppCache::isUrlNeedDownload);
JSP_REG_CONSTRUCTOR(JsAppCache, const char *);
JSP_INSTALL_CLASS("AppCache", JsAppCache);
}
}
//------------------------------------------------------------------------------
//-----------------------------END FILE--------------------------------
@@ -0,0 +1,127 @@
/**
@file JSAppCache.h
@brief
@author James
@version 1.0
@date 2016_5_17
*/
#ifndef __JSAppCache_H__
#define __JSAppCache_H__
//包含头文件
//------------------------------------------------------------------------------
#include "../JSInterface/JSInterface.h"
#include <string>
namespace laya
{
class JCServerFileCache;
class JsAppCache :public JsObjBase, public JSObjNode
{
public:
enum
{
transUrlFun
};
static JsObjClassInfo JSCLSINFO;
explicit JsAppCache();
explicit JsAppCache(const char* p_pszURL);
~JsAppCache();
unsigned int getCacheSize();
std::string getCachePath();
bool getEnableCache();
void setEnableCache(bool b );
//这个已经不用了
void update( const char* p_pszDccURL, unsigned int p_ulCheckSum, JSValueAsParam p_pFuncCheckOK, JSValueAsParam p_pFuncCheckError );
/** @brief
* 更新一个文件,
* @param p_nFileID 是文件id,用id的方法可以给外部提供更大的灵活性。
* @param p_ulChkSum 校验码,如果为零则自己计算
* @param p_pBuffer是文件数据
* @param p_bExtVersion true 则表示p_ulChkSum是版本号
* @return
* 返回为ture表示更新成功,否则表示与校验码不符。
*/
bool updateFile(int p_nFileID, unsigned int p_ulChkSum, const char* p_pBuffer, int len, bool p_bExtVersion);
/** @brief
* 更新一个文件,
* @param p_nFileID 是文件id,用id的方法可以给外部提供更大的灵活性。
* @param p_ulChkSum 校验码,如果为零则自己计算
* @param p_pBuffer是文件数据
* @param p_bExtVersion true 则表示p_ulChkSum是版本号
* @return
* 返回为ture表示更新成功,否则表示与校验码不符。
*/
bool updateFileForJs(int p_nFileID, unsigned int p_nCheckSum, JSValueAsParam p_pBuffer, bool p_bExtVersion);
//把url转换成本地文件路径
std::string url2Local(const char* p_pszURL );
//得到某个资源的id
//通常是对应sourceid目录下的一个文件的内容。可能是表示校验码,或者简单的版本号。
std::string getResourceID(const char* p_pszResource );
void setResourceID(const char* p_pszResource, const char* p_pszVal);
void saveFileTable(const char* p_pszFileContent);
void setFileTable(const char* p_pszFileContent);
void setUrlTransTable(const char* p_pszFileContent, int split);
bool isFileTableValid();
bool isUrlNeedDownload(const char* p_pszFile);
//获得所有缓存的app列表。返回的是一个js的数组
JsValue getAppList();
//得到某个app的缓存的大小
int64_t getAppSize(const char* appurl);
//删除指定app的缓存
bool delAppCache(const char* appurl);
void delCurAppCache();
//删除所有的缓存
void delAllCache();
int hashString(const char* str);
//临时
std::string loadCachedURL( const char* p_pszUrl );
void setTransUrlToCachedUrl(JSValueAsParam pObj);
char* getTransedUrl(const char* pUrl);
static void exportJS();
public:
JsObjHandle m_funcCheckOK;
JsObjHandle m_funcCheckError;
protected:
bool m_bEnableCache;
std::string m_strURL;
JCServerFileCache* m_pSvFileCache;
JsObjHandle m_funcTransUrl;//用来转换url的
};
}
//------------------------------------------------------------------------------
#endif //__JSAppCache_H__
//-----------------------------END FILE--------------------------------
@@ -0,0 +1,481 @@
/**
@file JSAudio.cpp
@brief
@author James
@version 1.0
@date 2014_11_26
*/
//包含头文件
#include "JSAudio.h"
#include "../JSInterface/JSInterface.h"
#include <util/Log.h>
#include <util/JCCommonMethod.h>
#include <downloadMgr/JCDownloadMgr.h>
#include <util/JCMemorySurvey.h>
#include <downloadCache/JCServerFileCache.h>
#include <fileSystem/JCFileSystem.h>
#include <resource/JCFileResManager.h>
#include <util/JCLayaUrl.h>
#include <util/JCCommonMethod.h>
#include "JSFile.h"
#include "../../JCScriptRuntime.h"
#include <util/JCIThreadCmdMgr.h>
#include <functional>
#include "../../Audio/JCAudioManager.h"
namespace laya
{
ADDJSCLSINFO(JSAudio, JSObjNode);
//为了确保mp3只被写入文件一次
std::map<std::string,std::string> ms_vSaveMp3File;
//------------------------------------------------------------------------------
JSAudio::JSAudio()
{
m_nCurrentTime = 0;
m_bNeedHandlePlay = false;
m_nType = -1;
m_bAutoPlay = false;
m_bLoop = false;
m_bMuted = false;
m_nVolume = 1;
m_sSrc = "";
m_sLocalFileName = "";
m_bIsOgg = false;
m_bDownloaded = false;
m_pOpenALInfo = NULL;
AdjustAmountOfExternalAllocatedMemory( 534 );
JCMemorySurvey::GetInstance()->newClass( "audio",534,this );
m_CallbackRef.reset(new int(1));
}
//------------------------------------------------------------------------------
JSAudio::~JSAudio()
{
JCMemorySurvey::GetInstance()->releaseClass( "audio",this );
JCAudioManager::GetInstance()->delWav(this);
JCAudioManager::GetInstance()->delMp3Obj(this);
}
//------------------------------------------------------------------------------
void JSAudio::addEventListener( const char* p_sName, JSValueAsParam p_pFunction )
{
if( strcmp( p_sName,"ended" ) == 0 )
{
m_pJSFunctionAudioEnd.set(0,this,p_pFunction);
}
else if(strcmp(p_sName,"canplaythrough")==0)
{
m_pJSFunctionCanPlay.set(1,this,p_pFunction);
}
else if (strcmp(p_sName, "error") == 0)
{
m_pJSFunctionError.set(2, this, p_pFunction);
}
else
{
LOGW("JSAudio::addEventListener(%s)尚未支持",p_sName );
}
}
//------------------------------------------------------------------------------
void JSAudio::setAutoPlay( bool p_bAutoPlay )
{
m_bAutoPlay = p_bAutoPlay;
}
//------------------------------------------------------------------------------
bool JSAudio::getAutoPlay()
{
return m_bAutoPlay;
}
//------------------------------------------------------------------------------
void JSAudio::setLoop( bool p_bLoop )
{
m_bLoop = p_bLoop;
}
//------------------------------------------------------------------------------
bool JSAudio::getLoop()
{
return m_bLoop;
}
//------------------------------------------------------------------------------
void JSAudio::setMuted( bool p_bMuted )
{
m_bMuted = p_bMuted;
if( m_nType == 0 )
{
JCAudioManager::GetInstance()->setMp3Mute( m_bMuted );
}
else if( m_nType == 1 )
{
if (m_pOpenALInfo && m_pOpenALInfo->m_pAudio == this)
{
JCAudioManager::GetInstance()->setWavVolume(m_pOpenALInfo, m_bMuted ? 0 : m_nVolume);
}
}
}
//------------------------------------------------------------------------------
bool JSAudio::getMuted()
{
return m_bMuted;
}
//------------------------------------------------------------------------------
void JSAudio::setSrc( const char* p_sSrc )
{
//如果和原来播放的一样,直接播放就行了
std::string sSrc = p_sSrc;
if( m_sSrc == sSrc )
{
std::weak_ptr<int> cbref(m_CallbackRef);
auto pFunction = std::bind(&JSAudio::onCanplayCallJSFunction,this, cbref);
JCScriptRuntime::s_JSRT->m_pPoster->postToJS( pFunction );
if( m_bAutoPlay == true )
{
//直接播放
play();
}
return;
}
//这段是第一次播放此音乐,先下载走正规流程
m_sSrc = sSrc;
//为了android
m_sSrc.at(0) = m_sSrc.at(0);
//这段代码是查找,是否在缓存中已经有此音乐了,直接找到播放
JCWaveInfo* pWavInfo = JCAudioManager::GetInstance()->FindWaveInfo( p_sSrc );
if( pWavInfo != NULL )
{
m_nType = 1;
m_bDownloaded = true;
std::weak_ptr<int> cbref(m_CallbackRef);
std::function<void(void)> pFunction = std::bind(&JSAudio::onCanplayCallJSFunction,this, cbref);
JCScriptRuntime::s_JSRT->m_pPoster->postToJS( pFunction );
if( m_bAutoPlay == true )
{
play();
}
return;
}
//去掉?后面的,因为可能增加版本号
std::string sTemp = m_sSrc;
int p3 = sTemp.rfind('?');
//去下载文件
char* sT = (char*)(sTemp.c_str());
if( p3 != -1 )
{
sT[p3]=0;
}
char* sExtName = (char*)( getExtName( LayaStrlwr( sT ) ) );
if( strcmp( sExtName,"mp3") == 0 )
{
m_nType = 0;
}
else if( strcmp( sExtName,"wav") == 0 )
{
m_nType = 1;
m_bIsOgg = false;
}
else if( strcmp( sExtName,"ogg") == 0 )
{
m_nType = 1;
m_bIsOgg = true;
}
else
{
m_nType = -1;
LOGW("JSAudio::setSrc extname != mp3 && extname != wav && exname != ogg");
return;
}
if(m_nType==0)
{
//必须确保 如果是mp3必须每次都new JSAudio这个类,否则会出问题
//临时用的这种办法,现在不好,因为有二次写文件的事情。。
//TODO以后得修改
std::map<std::string,std::string>::iterator iter = ms_vSaveMp3File.find( m_sSrc );
if( iter == ms_vSaveMp3File.end() )
{
laya::JCFileRes* res = JCScriptRuntime::s_JSRT->m_pFileResMgr->getRes(m_sSrc);
std::weak_ptr<int> cbref(m_CallbackRef);
res->setOnReadyCB( std::bind(&JSAudio::onDownloaded,this, std::placeholders::_1,cbref));
res->setOnErrorCB(std::bind(&JSAudio::onDownloadErr, this, std::placeholders::_1, std::placeholders::_2, cbref));
}
else
{
m_sLocalFileName = iter->second;
if(fs::exists(m_sLocalFileName.c_str()))
{
m_bDownloaded = true;
std::weak_ptr<int> cbref(m_CallbackRef);
auto pFunction = std::bind(&JSAudio::onCanplayCallJSFunction,this, cbref);
JCScriptRuntime::s_JSRT->m_pPoster->postToJS( pFunction );
if( m_nType == 0 )
{
if( m_bAutoPlay || m_bNeedHandlePlay == true )
{
m_bNeedHandlePlay = false;
play();
}
}
}
else
{
LOGW("JSAudio::setSrc music 当前文件不存在,%s",m_sLocalFileName.c_str());
ms_vSaveMp3File.erase(iter);
laya::JCFileRes* res = JCScriptRuntime::s_JSRT->m_pFileResMgr->getRes(m_sSrc);
std::weak_ptr<int> cbref(m_CallbackRef);
res->setOnReadyCB( std::bind(&JSAudio::onDownloaded,this, std::placeholders::_1,cbref));
res->setOnErrorCB(std::bind(&JSAudio::onDownloadErr, this, std::placeholders::_1, std::placeholders::_2, cbref));
}
}
}
else
{
laya::JCFileRes* res = JCScriptRuntime::s_JSRT->m_pFileResMgr->getRes(m_sSrc);
std::weak_ptr<int> cbref(m_CallbackRef);
res->setOnReadyCB( std::bind(&JSAudio::onDownloaded,this, std::placeholders::_1,cbref));
res->setOnErrorCB( std::bind(&JSAudio::onDownloadErr,this,std::placeholders::_1,std::placeholders::_2,cbref));
}
}
//------------------------------------------------------------------------------
bool JSAudio::onDownloadErr(void* p_pRes, int p_nErrCode,std::weak_ptr<int> callbackref)
{
if (!callbackref.lock())return false;
auto pFunction = std::bind(&JSAudio::onErrorCallJSFunction, this, p_nErrCode,callbackref);
JCScriptRuntime::s_JSRT->m_pPoster->postToJS(pFunction);
return true;
}
bool JSAudio::onDownloaded(void* p_pRes, std::weak_ptr<int> callbackref)
{
if( !callbackref.lock() )return false;
laya::JCResStateDispatcher* pRes = (laya::JCResStateDispatcher*)p_pRes;
laya::JCFileRes* pFileRes = (laya::JCFileRes*)pRes;
if( pFileRes->m_pBuffer.get()==NULL || pFileRes->m_nLength==0 )
{
return false;
}
JCBuffer p_buf;
p_buf.m_pPtr=pFileRes->m_pBuffer.get();
p_buf.m_nLen = pFileRes->m_nLength;
m_bDownloaded = true;
// std::weak_ptr<int> cbref(m_CallbackRef);
//std::function<void(void)> pFunction = std::bind(&JSAudio::onCanplayCallJSFunction,this, callbackref);
auto pFunction = std::bind(&JSAudio::onCanplayCallJSFunction, this, callbackref);
JCScriptRuntime::s_JSRT->m_pPoster->postToJS( pFunction );
if( m_nType == 0 )
{
//必须确保 如果是mp3必须每次都new JSAudio这个类,否则会出问题
//临时用的这种办法,现在不好,因为有二次写文件的事情。。
//TODO以后得修改
std::map<std::string,std::string>::iterator iter = ms_vSaveMp3File.find( m_sSrc );
if( iter != ms_vSaveMp3File.end() )
{
m_sLocalFileName = iter->second;
}
else
{
int p1 = m_sSrc.rfind('/');
int p2 = m_sSrc.rfind('\\');
int pos = std::max<int>(p1,p2);
std::string audiofile = m_sSrc.substr(pos+1,m_sSrc.length());
//去掉?后面的,因为可能增加版本号
int p3 = audiofile.rfind('?');
char* sT = (char*)(audiofile.c_str());
if( p3 != -1 )
{
sT[p3]=0;
}
unsigned int hash = JCCachedFileSys::hashRaw(m_sSrc.c_str());
char tmpBuf[32];
sprintf(tmpBuf, "%x_", hash);
m_sLocalFileName =JCScriptRuntime::s_JSRT->m_pFileResMgr->m_pFileCache->getAppPath()+"/"+ tmpBuf +audiofile;
writeFileSync(m_sLocalFileName.c_str(),p_buf);
ms_vSaveMp3File[m_sSrc] = m_sLocalFileName;
}
}
if( m_nType == 0 )
{
if( m_bAutoPlay || m_bNeedHandlePlay == true )
{
m_bNeedHandlePlay = false;
play();
}
}
else if( m_nType == 1 )
{
JCAudioManager::GetInstance()->AddWaveInfo( m_sSrc,p_buf,(int)(p_buf.m_nLen),this,m_bIsOgg );
if( m_bAutoPlay || m_bNeedHandlePlay == true )
{
m_bNeedHandlePlay = false;
play();
}
}
return true;
}
//------------------------------------------------------------------------------
const char* JSAudio::getSrc()
{
return m_sSrc.c_str();
}
//------------------------------------------------------------------------------
void JSAudio::setVolume( float p_nVolume )
{
if (p_nVolume > 1)p_nVolume = 1;
if (p_nVolume < 0)p_nVolume = 0;
m_nVolume = p_nVolume;
if( m_nType == 0 )
{
JCAudioManager::GetInstance()->setMp3Volume( m_nVolume );
}
else if( m_nType == 1 )
{
if (m_pOpenALInfo && m_pOpenALInfo->m_pAudio == this)
{
JCAudioManager::GetInstance()->setWavVolume(m_pOpenALInfo,m_nVolume);
}
}
}
//------------------------------------------------------------------------------
float JSAudio::getVolume()
{
return m_nVolume;
}
//------------------------------------------------------------------------------
void JSAudio::play()
{
//if (m_bMuted)return;
if( m_bDownloaded == false )
{
m_bNeedHandlePlay = true;
return;
}
if( m_nType == 0 )
{
JCAudioManager::GetInstance()->stopMp3();
if( m_sLocalFileName.length() > 0 )
{
JCAudioManager::GetInstance()->playMp3( m_sLocalFileName.c_str(),m_bLoop?-1:0,(int)m_nCurrentTime,this );
}
else
{
JCAudioManager::GetInstance()->playMp3( m_sSrc.c_str(),m_bLoop?-1:0,(int)m_nCurrentTime,this );
}
}
else if( m_nType == 1 )
{
m_pOpenALInfo = JCAudioManager::GetInstance()->playWav( this,m_sSrc, m_bIsOgg);
if (m_pOpenALInfo)
{
JCAudioManager::GetInstance()->setWavVolume(m_pOpenALInfo, m_nVolume);
}
}
}
//------------------------------------------------------------------------------
void JSAudio::pause()
{
if( m_nType == 0 )
{
m_nCurrentTime = JCAudioManager::GetInstance()->getCurrentTime();
JCAudioManager::GetInstance()->pauseMp3();
}
else
{
if (m_pOpenALInfo && m_pOpenALInfo->m_pAudio == this)
{
JCAudioManager::GetInstance()->stopWav(m_pOpenALInfo);
m_pOpenALInfo = NULL;
}
}
}
//------------------------------------------------------------------------------
void JSAudio::stop()
{
if( m_nType == 0 )
{
JCAudioManager::GetInstance()->stopMp3();
}
else
{
if (m_pOpenALInfo && m_pOpenALInfo->m_pAudio == this)
{
JCAudioManager::GetInstance()->stopWav(m_pOpenALInfo);
m_pOpenALInfo = NULL;
}
}
}
void JSAudio::setCurrentTime(double nCurrentTime)
{
m_nCurrentTime = nCurrentTime;
if( m_nType == 0 )
{
//JCAudioManager::GetInstance()->setCurrentTime(nCurrentTime);
}
else
{
}
}
double JSAudio::getCurrentTime()
{
if( m_nType == 0 )
{
return JCAudioManager::GetInstance()->getCurrentTime();
}
else
{
return 0.0f;
}
}
double JSAudio::getDuration()
{
if( m_nType == 0 )
{
return JCAudioManager::GetInstance()->getDuration();
}
else
{
return 0.0f;
}
}
//------------------------------------------------------------------------------
void JSAudio::onPlayEnd()
{
std::weak_ptr<int> cbref(m_CallbackRef);
auto pFunction = std::bind(&JSAudio::onPlayEndCallJSFunction,this, cbref);
JCScriptRuntime::s_JSRT->m_pPoster->postToJS( pFunction );
}
//------------------------------------------------------------------------------
void JSAudio::onPlayEndCallJSFunction( std::weak_ptr<int> callbackref)
{
if( !callbackref.lock())return;
m_pJSFunctionAudioEnd.Call();
}
//------------------------------------------------------------------------------
void JSAudio::onCanplayCallJSFunction( std::weak_ptr<int> callbackref)
{
if( !callbackref.lock())
return;
m_pJSFunctionCanPlay.Call();
}
void JSAudio::onErrorCallJSFunction(int p_nErrorCode,std::weak_ptr<int> callbackref)
{
if (!callbackref.lock())return;
m_pJSFunctionError.Call(p_nErrorCode);
}
void JSAudio::exportJS()
{
JSP_CLASS("ConchAudio",JSAudio);
JSP_ADD_PROPERTY(autoplay, JSAudio, getAutoPlay, setAutoPlay);
JSP_ADD_PROPERTY(loop, JSAudio, getLoop, setLoop);
JSP_ADD_PROPERTY(muted, JSAudio, getMuted, setMuted);
JSP_ADD_PROPERTY(src, JSAudio, getSrc, setSrc);
JSP_ADD_PROPERTY(volume, JSAudio, getVolume, setVolume);
JSP_ADD_PROPERTY(currentTime, JSAudio, getCurrentTime, setCurrentTime);
JSP_ADD_METHOD("setLoop", JSAudio::setLoop);
JSP_ADD_METHOD("play", JSAudio::play);
JSP_ADD_METHOD("pause", JSAudio::pause);
JSP_ADD_METHOD("stop", JSAudio::stop);
JSP_ADD_METHOD("addEventListener", JSAudio::addEventListener);
JSP_ADD_PROPERTY_RO(duration, JSAudio, getDuration)
JSP_INSTALL_CLASS("ConchAudio", JSAudio);
}
}
//------------------------------------------------------------------------------
//-----------------------------END FILE--------------------------------
@@ -0,0 +1,128 @@
/**
@file JSAudio.h
@brief
@author James
@version 1.0
@date 2014_11_26
*/
#ifndef __JSAudio_H__
#define __JSAudio_H__
//包含头文件
#include <stdio.h>
#include "../JSInterface/JSInterface.h"
#include "resource/Audio/JCAudioInterface.h"
#include "buffer/JCBuffer.h"
/**
* @brief
*/
namespace laya
{
class OpenALSourceInfo;
class JSAudio : public JsObjBase, public JSObjNode,JCAudioInterface
{
public:
static JsObjClassInfo JSCLSINFO;
static void exportJS();
JSAudio();
~JSAudio();
public:
void setAutoPlay( bool p_bAutoPlay );
bool getAutoPlay();
void setLoop( bool p_bLoop );
bool getLoop();
void setMuted( bool p_bMuted );
bool getMuted();
void setSrc( const char* p_sSrc );
const char* getSrc();
void setVolume( float p_nVolume );
float getVolume();
void setCurrentTime(double nCurrentTime);
double getCurrentTime();
double getDuration();
public:
void addEventListener( const char* p_sName, JSValueAsParam p_pFunction );
void play();
void pause();
void stop();
//下载线程的回调
bool onDownloaded( void* p_pRes, std::weak_ptr<int> callbackref );
bool onDownloadErr(void* p_pRes, int p_nErrCode, std::weak_ptr<int> callbackref);
public:
void onPlayEnd();
void onCanplayCallJSFunction(std::weak_ptr<int> callbackref);
void onPlayEndCallJSFunction(std::weak_ptr<int> callbackref);
void onErrorCallJSFunction(int p_nErrCode,std::weak_ptr<int> callbackref);
public:
bool m_bDownloaded; //是否下载完成
int m_nType; //类型 -1为无效值, 0为mp3 1为wav
bool m_bIsOgg; //是否为ogg
bool m_bAutoPlay; //是否自动播放
bool m_bLoop; //是否循环
bool m_bMuted; //是否静音
float m_nCurrentTime; //播放到的时间
std::string m_sSrc; //src
float m_nVolume; //音量
std::string m_sLocalFileName;
std::shared_ptr<int> m_CallbackRef;
public:
JsObjHandle m_pJSFunctionAudioEnd; //JS的回调
JsObjHandle m_pJSFunctionCanPlay; //JS的回调
JsObjHandle m_pJSFunctionError; //JS的回调
OpenALSourceInfo* m_pOpenALInfo; //openAL的指针
private:
bool m_bNeedHandlePlay;
};
}
#endif //__JSAudio_H__
//-----------------------------END FILE--------------------------------
@@ -0,0 +1,103 @@
/**
@file JSCallbackFuncObj.cpp
@brief
@author James
@version 1.0
@date 2018_6_21
*/
#include "JSCallbackFuncObj.h"
#include "../../JCScriptRuntime.h"
namespace laya
{
ADDJSCLSINFO(JSCallbackFuncObj, JSObjNode);
//------------------------------------------------------------------------------
JSCallbackFuncObj::JSCallbackFuncObj()
{
m_nID = 0;
}
//------------------------------------------------------------------------------
JSCallbackFuncObj::JSCallbackFuncObj(int nID)
{
m_nID = nID;
JCScriptRuntime::s_JSRT->m_pCallbackFuncManager->setRes(m_nID, this);
}
//------------------------------------------------------------------------------
JSCallbackFuncObj::~JSCallbackFuncObj()
{
for (std::vector<JsObjHandle*>::iterator iter = m_vFunc.begin(); iter != m_vFunc.end(); iter++)
{
JsObjHandle* pFunc = *iter;
if (pFunc)
{
delete pFunc;
pFunc = NULL;
}
}
m_vFunc.clear();
JCScriptRuntime::s_JSRT->m_pCallbackFuncManager->removeRes(m_nID);
}
void JSCallbackFuncObj::addCallbackFunc(int nID, JSValueAsParam pFunction)
{
JsObjHandle* pFunc = new JsObjHandle();
pFunc->set(nID, this, pFunction);
//push到vector中
int nSize = (int)m_vFunc.size();
if (nID == nSize)
{
m_vFunc.push_back(pFunc);
}
else if (nID < nSize)
{
if (m_vFunc[nID] == NULL)
{
m_vFunc[nID] = pFunc;
}
else
{
LOGE("JSCallbackFuncObj::addCallbackFunc error m_vFunc[%d] != NULL", nID);
delete m_vFunc[nID];
m_vFunc[nID] = pFunc;
}
}
else
{
int nOldSize = m_vFunc.size();
m_vFunc.resize(nID + 1);
m_vFunc[nID] = pFunc;
}
}
void JSCallbackFuncObj::callJS(int nID)
{
if (m_vFunc[nID])
{
m_vFunc[nID]->Call();
}
else
{
LOGI("JSCallbackFuncObj::callJS error id=%d",nID);
}
}
void JSCallbackFuncObj::testCall(int nID)
{
if (!m_vFunc[nID]->Empty())
{
m_vFunc[nID]->Call();
}
}
//------------------------------------------------------------------------------
void JSCallbackFuncObj::exportJS()
{
JSP_CLASS("_callbackFuncObj", JSCallbackFuncObj);
JSP_ADD_METHOD("addCallbackFunc", JSCallbackFuncObj::addCallbackFunc);
JSP_ADD_METHOD("testCall", JSCallbackFuncObj::testCall);
JSP_REG_CONSTRUCTOR(JSCallbackFuncObj, int);
JSP_INSTALL_CLASS("_callbackFuncObj", JSCallbackFuncObj);
}
}
//------------------------------------------------------------------------------
//-----------------------------END FILE--------------------------------
@@ -0,0 +1,65 @@
/**
@file JSCallbackFuncObj.h
@brief
@author James
@version 1.0
@date 2018_6_21
*/
#ifndef __JSCallbackFuncObj_H__
#define __JSCallbackFuncObj_H__
#include <stdio.h>
#include <string>
#include <vector>
#include "../JSInterface/JSInterface.h"
#include <JSObjBase.h>
namespace laya
{
class JSCallbackFuncObj :public JsObjBase, public JSObjNode
{
public:
static JsObjClassInfo JSCLSINFO;
static void exportJS();
JSCallbackFuncObj();
JSCallbackFuncObj(int nID);
~JSCallbackFuncObj();
void addCallbackFunc(int nFuncID, JSValueAsParam pFunction);
void callJS(int nID);
template<typename P1>
void callJS(int nID, P1 p1)
{
{
if (m_vFunc[nID])
{
m_vFunc[nID]->Call(p1);
}
else
{
LOGI("JSCallbackFuncObj::callJS error id=%d", nID);
}
}
}
public:
void testCall(int nID);
public:
int m_nID;
std::vector<JsObjHandle*> m_vFunc;
};
}
//------------------------------------------------------------------------------
#endif //__JSCallbackFuncObj_H__
//-----------------------------END FILE--------------------------------
@@ -0,0 +1,684 @@
/**
@file JSConchConfig.cpp
@brief
@author hugao
@version 1.0
@date 2016_5_18
*/
//包含头文件
#include "JSConchConfig.h"
#include "JSInput.h"
#include "resource/JCFileResManager.h"
#include "../../JCScriptRuntime.h"
#include "../../../Conch/source/conch/JCConch.h"
#ifdef ANDROID
#include "../../CToJavaBridge.h"
#elif WIN32
#include <Windows.h>
#elif __APPLE__
#include "../../CToObjectC.h"
#endif
#include "downloadMgr/JCDownloadMgr.h"
#include "util/Log.h"
#include "../../JCSystemConfig.h"
#include "../../JCConchRender.h"
#include "../../JCConch.h"
#include "../../WebSocket/WebSocket.h"
#include <resource/Audio/JCAudioWavPlayer.h>
#include "../../Audio/JCAudioManager.h"
#include <LayaGL/JCLayaGL.h>
#include <LayaGL/JCLayaGLDispatch.h>
extern int g_nDebugLevel;
extern int g_nInnerWidth;
extern int g_nInnerHeight;
extern bool g_bGLCanvasSizeChanged;
#ifdef WIN32
extern HWND g_hWnd;
#endif
extern int s_nGLCaps;
namespace laya
{
ADDJSCLSINFO(JSConchConfig, JSObjNode);
JSConchConfig* JSConchConfig::ms_pInstance = NULL;
JSConchConfig* JSConchConfig::getInstance()
{
if (ms_pInstance == NULL)
{
ms_pInstance = new JSConchConfig();
}
return ms_pInstance;
}
JSConchConfig::JSConchConfig()
{
m_fScreenScaleW = m_fScreenScaleH = 1;
m_fScreenTx = m_fScreenTy = 0;
m_sGUID = "unknow";
m_sDeviceModel = "unknow";
m_sDeviceInfo = "{\"resolution\":\"unknow\", \"guid\":\"unknow\",\"imei\":[\"unknow\"],\"imsi\":[\"unknow\"],\"os\":\"unknow\",\"osversion\":\"unknow\",\"phonemodel\":\"unknow\" }";
//AdjustAmountOfExternalAllocatedMemory( 128 ); 可能还没有js环境
JCMemorySurvey::GetInstance()->newClass("conchConfig", 128, this);
}
JSConchConfig::~JSConchConfig()
{
ms_pInstance = NULL;
JCMemorySurvey::GetInstance()->releaseClass("conchConfig", this);
}
const char* JSConchConfig::getLocalStoragePath()
{
if (JCConch::s_pConch)
return JCConch::s_pConch->getLocalStoragePath();
return "";
}
float JSConchConfig::getTotalMem()
{
#ifdef ANDROID
CToJavaBridge::JavaRet kRet;
if (CToJavaBridge::GetInstance()->callMethod("layaair.game.utility.ProcessInfo", "getTotalMem", kRet, CToJavaBridge::JavaRet::RT_Float))
{
return kRet.floatRet;
}
return 0;
#elif WIN32
MEMORYSTATUSEX statex;
statex.dwLength = sizeof(statex);
GlobalMemoryStatusEx(&statex);
return (float)(statex.ullTotalPhys / 1024);
#elif __APPLE__
return CToObjectCGetTotalMem();
#endif
return 0;
}
int JSConchConfig::getUsedMem()
{
#ifdef ANDROID
CToJavaBridge::JavaRet kRet;
if (CToJavaBridge::GetInstance()->callMethod("layaair.game.utility.ProcessInfo", "getUsedMem", kRet, CToJavaBridge::JavaRet::RT_Float))
{
return (int)(kRet.floatRet);
}
return 0;
#elif __APPLE__
return CToObjectCGetUsedMem();
#elif WIN32
return getAppUsedMem();
#endif
return 0;
}
int JSConchConfig::getAvalidMem()
{
#ifdef ANDROID
CToJavaBridge::JavaRet kRet;
if (CToJavaBridge::GetInstance()->callMethod("layaair.game.utility.ProcessInfo", "getAvalidMem", kRet, CToJavaBridge::JavaRet::RT_Float))
{
return (int)(kRet.floatRet);
}
return 0;
#elif WIN32
MEMORYSTATUSEX statex;
statex.dwLength = sizeof(statex);
GlobalMemoryStatusEx(&statex);
return (int)(statex.ullAvailPhys / 1024);
#elif __APPLE__
return CToObjectCGetAvalidMem();
#endif
return 0;
}
float JSConchConfig::getScreenInch()
{
#ifdef ANDROID
CToJavaBridge::JavaRet kRet;
if (CToJavaBridge::GetInstance()->callMethod("layaair.game.utility.ProcessInfo", "getScreenInch", kRet, CToJavaBridge::JavaRet::RT_Float))
{
return kRet.floatRet;
}
return 0;
#elif WIN32
return 0;
#elif __APPLE__
return CToObjectCGetScreenInch();
#endif
return 0;
}
void JSConchConfig::setTouchMoveRange(float p_fMM)
{
#ifdef ANDROID
CToJavaBridge::JavaRet kRet;
CToJavaBridge::GetInstance()->callMethod(CToJavaBridge::JavaClass.c_str(), "setTouchMoveRange", p_fMM,kRet);
#elif WIN32
#endif
}
void JSConchConfig::setScreenOrientation(int p_nOrientation)
{
enum ori {
landscape = 0,
portrait = 1,
user = 2,
behind = 3,
sensor = 4,
nosensor = 5,
sensor_landscape = 6,
sensor_portrait = 7,
reverse_landscape = 8,
reverse_portrait = 9,
full_sensor = 10,
num
};
bool vbLandscapes[] = { true,false,false,false,false,false,true,false,true,false,false };
if (p_nOrientation >= num) {
return;
}
int w = g_nInnerWidth > g_nInnerHeight ? g_nInnerWidth : g_nInnerHeight;
int h = g_nInnerWidth > g_nInnerHeight ? g_nInnerHeight : g_nInnerWidth;
if (vbLandscapes[p_nOrientation]) {
g_nInnerWidth = w;
g_nInnerHeight = h;
}
else {
g_nInnerWidth = h;
g_nInnerHeight = w;
}
g_bGLCanvasSizeChanged = true;
#ifdef ANDROID
CToJavaBridge::JavaRet kRet;
CToJavaBridge::GetInstance()->callMethod(CToJavaBridge::JavaClass.c_str(), "setScreenOrientation", p_nOrientation, kRet);
#elif WIN32
MoveWindow(g_hWnd, 0, 0, g_nInnerWidth, g_nInnerHeight, true);
#elif __APPLE__
CToObjectCSetScreenOrientation(p_nOrientation);
#endif
}
void JSConchConfig::setUrlIgnoreCase(bool b) {
JCScriptRuntime::s_JSRT->m_pFileResMgr->m_bUrlToLowerCase = b;
}
bool JSConchConfig::getUrlIgnoreCase() {
return JCScriptRuntime::s_JSRT->m_pFileResMgr->m_bUrlToLowerCase;
}
int JSConchConfig::getNetworkType()
{
#ifdef ANDROID
CToJavaBridge::JavaRet kRet;
if (CToJavaBridge::GetInstance()->callMethod(CToJavaBridge::JavaClass.c_str(), "getContextedType", kRet, CToJavaBridge::JavaRet::RT_Int))
{
return kRet.intRet;
}
return 1;
#elif WIN32
return 1;
#elif __APPLE__
return CToObjectCGetNetworkType();
#endif
return 0;
}
void JSConchConfig::setDownloadTryNum(int p_nOptTry, int p_nConnTry) {
JCDownloadMgr* pDmgr = JCDownloadMgr::getInstance();
if (pDmgr) {
pDmgr->setOpt_tryNumOnTimeout(p_nOptTry, p_nConnTry);
}
}
void JSConchConfig::setDownloadPathReplace(const char* p_pszPath, const char* p_pszReplace) {
JCDownloadMgr* pDmgr = JCDownloadMgr::getInstance();
if (pDmgr) {
pDmgr->setFinalReplacePath(p_pszPath, p_pszReplace);
}
}
void JSConchConfig::setDownloadTail(int type, const char* p_strTail) {
JCDownloadMgr* pDmgr = JCDownloadMgr::getInstance();
if (pDmgr) {
pDmgr->setDownloadTail(type, p_strTail);
}
}
void JSConchConfig::setDownloadReplaceExt(const char* p_pszOrigin, const char* p_pszNew) {
}
void JSConchConfig::setDownloadIgnoreCRLR(bool b) {
}
void JSConchConfig::resetDownloadIgnoreCRLR() {
}
void JSConchConfig::addChkIgnoreChksumExt(const char* p_pszExt) {
}
void JSConchConfig::clearChkIgnoreChksumExt() {
}
void JSConchConfig::setDownloadUnmask(const char* p_pszExt, unsigned int p_nKey, int p_nLen) {
JCDownloadMgr* pdmgr = JCDownloadMgr::getInstance();
if (pdmgr) {
pdmgr->setDownloadUnmask(p_pszExt, p_nKey, p_nLen);
}
}
void JSConchConfig::resetDownloadUnmask() {
JCDownloadMgr* pdmgr = JCDownloadMgr::getInstance();
if (pdmgr) {
pdmgr->resetDownloadUnmask();
}
}
void JSConchConfig::setDownloadNoResponseTimeout(int p_nDuration) {
JCDownloadMgr::s_nNoResponseTimeout = p_nDuration;
}
void JSConchConfig::resetDownloadNoResponseTimeout() {
JCDownloadMgr::s_nNoResponseTimeout = 15000;
}
void JSConchConfig::setDownloadVersionString(const char* p_pszVersion) {
if (p_pszVersion && strlen(p_pszVersion) > 0) {
JCFileRes::s_strExtVersion = p_pszVersion;
JCFileRes::s_strExtVersion += "=";
}
else
JCFileRes::s_strExtVersion = "";
}
const char* JSConchConfig::getOS()
{
#ifdef __APPLE__
return "Conch-ios";
#elif ANDROID
return "Conch-android";
#elif WIN32
return "Conch-window";
#endif
}
const char* JSConchConfig::getBrowserInfo()
{
#ifdef __APPLE__
return "Conch-ios";
#elif ANDROID
return "Conch-android";
#elif WIN32
return "Conch-window";
#endif
}
const char* JSConchConfig::getGuid()
{
#ifdef __APPLE__
m_sGUID = CToObjectCGetGUID();
return m_sGUID.c_str();
#elif ANDROID
CToJavaBridge::JavaRet kRet;
if (CToJavaBridge::GetInstance()->callMethod(CToJavaBridge::JavaClass.c_str(), "getWifiMac", kRet))
{
m_sGUID = CToJavaBridge::GetInstance()->getJavaString(kRet.pJNI, kRet.strRet);
}
LOGI("getGuid::get_Value=%s", m_sGUID.c_str());
return m_sGUID.c_str();
#elif WIN32
return "window";
#endif
}
const char* JSConchConfig::getRuntimeVersion()
{
#ifdef __APPLE__
return "ios-conch6-release-2.9.0";
#elif ANDROID
return "android-conch6-release-2.9.0";
#elif WIN32
return "window-conch6-release-2.9.0";
#endif
}
const char* JSConchConfig::getAppVersion()
{
#ifdef __APPLE__
m_sAppVersion = CToObjectCGetAppVersion();
return m_sAppVersion.c_str();
#elif ANDROID
CToJavaBridge::JavaRet kRet;
if (CToJavaBridge::GetInstance()->callMethod(CToJavaBridge::JavaClass.c_str(), "getAppVersion", kRet))
{
return CToJavaBridge::GetInstance()->getJavaString(kRet.pJNI, kRet.strRet).c_str();;
}
return "";
#elif WIN32
return "2.0";
#endif
}
const char* JSConchConfig::getAppLocalVersion()
{
#ifdef __APPLE__
m_sAppLocalVersion = CToObjectCGetAppLocalVersion();
return m_sAppLocalVersion.c_str();
#elif ANDROID
CToJavaBridge::JavaRet kRet;
if (CToJavaBridge::GetInstance()->callMethod(CToJavaBridge::JavaClass.c_str(), "getAppLocalVersion", kRet))
{
return CToJavaBridge::GetInstance()->getJavaString(kRet.pJNI, kRet.strRet).c_str();;
}
return "";
#elif WIN32
return "2.0";
#endif
}
bool JSConchConfig::getIsPlug()
{
return JCSystemConfig::s_bIsPlug != 0;
}
const char* JSConchConfig::getJsonparamExt()
{
return g_kSystemConfig.m_jsonparamExt.c_str();
}
int JSConchConfig::getGLCaps()
{
return s_nGLCaps;
}
const char* JSConchConfig::getDeviceInfo()
{
#ifdef __APPLE__
m_sDeviceInfo = CToObjectCGetDeviceInfo();
return m_sDeviceInfo.c_str();
#elif ANDROID
CToJavaBridge::JavaRet kRet;
if (CToJavaBridge::GetInstance()->callMethod(CToJavaBridge::JavaClass.c_str(), "GetDeviceInfo", kRet))
{
m_sDeviceInfo = CToJavaBridge::GetInstance()->getJavaString(kRet.pJNI, kRet.strRet);
}
LOGI("getDeviceInfo::get_Value=%s", m_sDeviceInfo.c_str());
return m_sDeviceInfo.c_str();
#elif WIN32
return "{\"resolution\":\"1920*1080\", \"guid\":\"xxxxxxxxx\",\"imei\":[\"imeixxx\"],\"imsi\":[\"imsixxx\"],\"os\":\"windows\",\"osversion\":\"windows7 64\",\"phonemodel\":\"Wintel\" }";
#endif
}
float JSConchConfig::getCurrentDeviceSystemVersion()
{
#ifdef __APPLE__
return CToObjectCGetDeviceSystemVersion();
#else
return 0.0f;
#endif
}
void JSConchConfig::setScreenScale(float fScaleW, float fScaleH, float ftx, float fty)
{
m_fScreenTx = ftx;
m_fScreenTy = fty;
m_fScreenScaleW = fScaleW;
m_fScreenScaleH = fScaleH;
JCLayaGL::s_fMainCanvasScaleX = fScaleW;
JCLayaGL::s_fMainCanvasScaleY = fScaleH;
JCLayaGL::s_fMainCanvasTX = ftx;
JCLayaGL::s_fMainCanvasTY = fty;
}
float JSConchConfig::getScreenScaleW()
{
return m_fScreenScaleW;
}
float JSConchConfig::getScreenScaleH()
{
return m_fScreenScaleH;
}
bool JSConchConfig::getLocalable()
{
return JCSystemConfig::s_bLocalizable;
}
void JSConchConfig::setLocalable(bool isLocalPackage)
{
JCSystemConfig::s_bLocalizable = isLocalPackage;
}
void JSConchConfig::setMouseFrame(double thredholdms)
{
g_kSystemConfig.m_nFrameType = FT_MOUSE;
g_kSystemConfig.m_nFrameThreshold = thredholdms;
g_kSystemConfig.m_nSleepTime = 32;
}
void JSConchConfig::setSlowFrame(bool p_bIsSlow)
{
g_kSystemConfig.m_nFrameType = p_bIsSlow ? FT_SLOW : FT_FAST;
g_kSystemConfig.m_nSleepTime = 32;
}
void JSConchConfig::setLimitFPS(int nFpsNum)
{
if( nFpsNum >= 60 )
{
g_kSystemConfig.m_nFrameType = FT_FAST;
}
else
{
g_kSystemConfig.m_nFrameType = FT_SLOW;
g_kSystemConfig.m_nSleepTime = 1000 / nFpsNum - 1;
}
}
void JSConchConfig::setCurlProxy(const char* pProxy) {
if (pProxy) {
LOGI("setCurlProxy %s", pProxy);
JCDownloadMgr::s_curlProxyString = pProxy;
JCDownloadMgr::getInstance()->setProxyString(pProxy);
}
}
void JSConchConfig::setWebsocketProxy(const char* pProxy) {
if (pProxy) {
WebSocket::s_strProxy = pProxy;
LOGI("setWebsocketProxy:%s", pProxy);
}
}
void JSConchConfig::setTouchMode(bool bMode)
{
JSInput::getInstance()->setTouchMode(bMode);
}
bool JSConchConfig::getTouchMode()
{
return JSInput::getInstance()->getTouchMode();
}
void JSConchConfig::setDebugLevel(int nLevel)
{
g_nDebugLevel = nLevel;
}
void JSConchConfig::setImageReleaseSpaceTime(int nSpaceTime)
{
if (g_kSystemConfig.m_nThreadMODE == THREAD_MODE_DOUBLE)
{
JCScriptRuntime::s_JSRT->flushSharedCmdBuffer();
JCCommandEncoderBuffer* pCmd = JCScriptRuntime::s_JSRT->m_pRenderCmd;
pCmd->append(LAYA_SET_IMAGE_RELEASE_SPACE_TIME);
pCmd->append(nSpaceTime);
}
else
{
JCConch::s_pConchRender->m_pImageManager->setReleaseSpaceTime(nSpaceTime);
}
}
void JSConchConfig::enableMemorySurvey(bool bEnable)
{
JCMemorySurvey::GetInstance()->setEnable(bEnable);
}
void JSConchConfig::showInternalPerfBar(int b, float scale)
{
if (scale == 0.0f)scale = 10.0f;
if (b > 0) {
g_kSystemConfig.m_bShowInternalPerBar = true;
JCPerfHUD::addData(new perfBarData(JCPerfHUD::PHUD_BAR_JS_ONDRAW, 0x6600ff00, "jsbar", scale));
JCPerfHUD::addData(new perfBarData(JCPerfHUD::PHUD_BAR_RENDER, 0x66ff0000, "renderbar", scale));
JCPerfHUD::addData(new perfBarData(JCPerfHUD::PHUD_BAR_JSWAIT, 0x66003300, "jswait", scale));
JCPerfHUD::addData(new perfBarData(JCPerfHUD::PHUD_BAR_GLWAIT, 0x66330000, "glwait", scale));
}
else {
g_kSystemConfig.m_bShowInternalPerBar = false;
JCPerfHUD::delData(JCPerfHUD::PHUD_BAR_JS_ONDRAW);
JCPerfHUD::delData(JCPerfHUD::PHUD_BAR_RENDER);
JCPerfHUD::delData(JCPerfHUD::PHUD_BAR_JSWAIT);
JCPerfHUD::delData(JCPerfHUD::PHUD_BAR_GLWAIT);
}
}
void JSConchConfig::useChoreographer(int b) {
#ifdef ANDROID
#else
b = 0;
#endif
g_kSystemConfig.m_bUseChoreographer = b > 0;
#ifdef ANDROID
CToJavaBridge::JavaRet kRet;
CToJavaBridge::GetInstance()->callMethod(CToJavaBridge::JavaClass.c_str(), "useChoreographer", b ,kRet);
#endif
if (!b)
{
if (JCScriptRuntime::s_JSRT)
{
JCScriptRuntime::s_JSRT->m_pScriptThread->post(std::bind(&JCScriptRuntime::onUpdate, JCScriptRuntime::s_JSRT));
}
}
}
void JSConchConfig::testSleep(int tm)
{
std::this_thread::sleep_for(std::chrono::milliseconds(tm));
}
void JSConchConfig::setDownloadConnTimeout(int tm)
{
JCDownloadMgr::s_nConnTimeout = tm;
}
void JSConchConfig::setDownloadOptTimeout(int tm)
{
JCDownloadMgr::s_nOptTimeout = tm;
}
void JSConchConfig::setResolution(int w, int h) {
#ifdef ANDROID
CToJavaBridge::JavaRet kRet;
CToJavaBridge::GetInstance()->callMethod(CToJavaBridge::JavaClass.c_str(), "setResolution", w, h, kRet);
#else
#endif
}
bool JSConchConfig::getUseAndroidSystemFont() {
return g_kSystemConfig.m_bUseAndroidSystemFont;
}
void JSConchConfig::setUseAndroidSystemFont(bool b) {
g_kSystemConfig.m_bUseAndroidSystemFont = b;
}
void JSConchConfig::printAllMemorySurvey(char* sPath)
{
string sWritePath = "";
if (sPath == NULL || strlen(sPath) <= 0)
{
sWritePath = JCConch::s_pConch->m_sCachePath.c_str();
}
else
{
sWritePath = sPath;
}
JCMemorySurvey::GetInstance()->printAll(sWritePath.c_str());
}
void JSConchConfig::enableEncodeURI(bool b)
{
JCDownloadMgr::s_bEncodeURI = b;
}
void JSConchConfig::setJSDebugMode(int nMode)
{
JCConch::s_pConch->m_nJSDebugMode = (JS_DEBUG_MODE)nMode;
}
int JSConchConfig::getJSDebugMode()
{
return JCConch::s_pConch->m_nJSDebugMode;
}
void JSConchConfig::setJSDebugPort(int nPort)
{
JCConch::s_pConch->m_nJSDebugPort = nPort;
}
int JSConchConfig::getJSDebugPort()
{
return JCConch::s_pConch->m_nJSDebugPort;
}
void JSConchConfig::setSoundGarbageCollectionTime(int nTime)
{
JCAudioWavPlayer::s_nGarbageCollectionTime = nTime;
}
int JSConchConfig::getThreadMode()
{
return g_kSystemConfig.m_nThreadMODE;
}
void JSConchConfig::exportJS()
{
JSP_GLOBAL_CLASS("conchConfig", JSConchConfig);
JSP_ADD_PROPERTY_RO(threadMode, JSConchConfig, getThreadMode);
JSP_ADD_PROPERTY_RO(glCaps, JSConchConfig, getGLCaps);
JSP_ADD_PROPERTY_RO(paramExt, JSConchConfig, getJsonparamExt);
JSP_ADD_PROPERTY(urlIgnoreCase, JSConchConfig, getUrlIgnoreCase, setUrlIgnoreCase);
JSP_ADD_PROPERTY(localizable, JSConchConfig, getLocalable, setLocalable);
JSP_ADD_PROPERTY(useAndroidSystemFont, JSConchConfig, getUseAndroidSystemFont, setUseAndroidSystemFont);
JSP_ADD_METHOD("getStoragePath", JSConchConfig::getLocalStoragePath);
JSP_ADD_METHOD("getTotalMem", JSConchConfig::getTotalMem);
JSP_ADD_METHOD("getUsedMem", JSConchConfig::getUsedMem);
JSP_ADD_METHOD("getAvalidMem", JSConchConfig::getAvalidMem);
JSP_ADD_METHOD("getScreenInch", JSConchConfig::getScreenInch);
JSP_ADD_METHOD("setTouchMoveRange", JSConchConfig::setTouchMoveRange);
JSP_ADD_METHOD("setScreenOrientation", JSConchConfig::setScreenOrientation);
JSP_ADD_METHOD("setScreenScale", JSConchConfig::setScreenScale);
JSP_ADD_METHOD("getScreenScaleW", JSConchConfig::getScreenScaleW);
JSP_ADD_METHOD("getScreenScaleH", JSConchConfig::getScreenScaleH);
JSP_ADD_METHOD("setUrlIgnoreCase", JSConchConfig::setUrlIgnoreCase);
JSP_ADD_METHOD("getUrlIgnoreCase", JSConchConfig::getUrlIgnoreCase);
JSP_ADD_METHOD("getNetworkType", JSConchConfig::getNetworkType);
JSP_ADD_METHOD("getRuntimeVersion", JSConchConfig::getRuntimeVersion);
JSP_ADD_METHOD("setDownloadTryNum", JSConchConfig::setDownloadTryNum);
JSP_ADD_METHOD("setDownloadPathReplace", JSConchConfig::setDownloadPathReplace);
JSP_ADD_METHOD("setDownloadTail", JSConchConfig::setDownloadTail);
JSP_ADD_METHOD("setDownloadNoResponseTimeout", JSConchConfig::setDownloadNoResponseTimeout);
JSP_ADD_METHOD("setDownloadReplaceExt", JSConchConfig::setDownloadReplaceExt);
JSP_ADD_METHOD("setDownloadIgnoreCRLR", JSConchConfig::setDownloadIgnoreCRLR);
JSP_ADD_METHOD("addChkIgnoreChksumExt", JSConchConfig::addChkIgnoreChksumExt);
JSP_ADD_METHOD("clearChkIgnoreChksumExt", JSConchConfig::clearChkIgnoreChksumExt);
JSP_ADD_METHOD("setDownloadUnmask", JSConchConfig::setDownloadUnmask);
JSP_ADD_METHOD("resetDownloadUnmask", JSConchConfig::resetDownloadUnmask);
JSP_ADD_METHOD("setDownloadVersionString", JSConchConfig::setDownloadVersionString);
JSP_ADD_METHOD("getOS", JSConchConfig::getOS);
JSP_ADD_METHOD("getAppVersion", JSConchConfig::getAppVersion);
JSP_ADD_METHOD("getAppLocalVersion", JSConchConfig::getAppLocalVersion);
JSP_ADD_METHOD("getBrowserInfo", JSConchConfig::getBrowserInfo);
JSP_ADD_METHOD("getGuid", JSConchConfig::getGuid);
JSP_ADD_METHOD("getDeviceInfo", JSConchConfig::getDeviceInfo);
JSP_ADD_METHOD("getIsPlug", JSConchConfig::getIsPlug);
JSP_ADD_METHOD("setLimitFPS", JSConchConfig::setLimitFPS);
JSP_ADD_METHOD("setMouseFrame", JSConchConfig::setMouseFrame);
JSP_ADD_METHOD("setSlowFrame", JSConchConfig::setSlowFrame);
JSP_ADD_METHOD("setCurlProxy", JSConchConfig::setCurlProxy);
JSP_ADD_METHOD("setWebsocketProxy", JSConchConfig::setWebsocketProxy);
JSP_ADD_METHOD("setTouchMode", JSConchConfig::setTouchMode);
JSP_ADD_METHOD("getTouchMode", JSConchConfig::getTouchMode);
JSP_ADD_METHOD("setDebugLevel", JSConchConfig::setDebugLevel);
JSP_ADD_METHOD("setImageReleaseSpaceTime", JSConchConfig::setImageReleaseSpaceTime);
JSP_ADD_METHOD("enableMemorySurvey", JSConchConfig::enableMemorySurvey);
JSP_ADD_METHOD("showInternalPerfBar", JSConchConfig::showInternalPerfBar);
JSP_ADD_METHOD("useChoreographer", JSConchConfig::useChoreographer);
#ifdef ANDROID
//目前只有android实现了这个函数,所以ios等就不往外导了,这样判断方便。
JSP_ADD_METHOD("setResolution", JSConchConfig::setResolution);
#endif
JSP_ADD_METHOD("test_sleep", JSConchConfig::testSleep);
JSP_ADD_METHOD("setDownloadConnTimeout", JSConchConfig::setDownloadConnTimeout);
JSP_ADD_METHOD("setDownloadOptTimeout", JSConchConfig::setDownloadOptTimeout);
JSP_ADD_METHOD("printAllMemorySurvey", JSConchConfig::printAllMemorySurvey);
JSP_ADD_METHOD("enableEncodeURI", JSConchConfig::enableEncodeURI);
JSP_ADD_PROPERTY(JSDebugMode, JSConchConfig, getJSDebugMode, setJSDebugMode);
JSP_ADD_PROPERTY(JSDebugPort, JSConchConfig, getJSDebugPort, setJSDebugPort);
JSP_ADD_METHOD("setSoundGarbageCollectionTime", JSConchConfig::setSoundGarbageCollectionTime);
JSP_INSTALL_GLOBAL_CLASS("conchConfig", JSConchConfig, this);
}
}
//------------------------------------------------------------------------------
//-----------------------------END FILE--------------------------------
@@ -0,0 +1,174 @@
/**
@file JSConchConfig.h
@brief
@author hugao
@version 1.0
@date 2016_5_18
*/
#ifndef __JSConchConfig_H__
#define __JSConchConfig_H__
//包含头文件
//------------------------------------------------------------------------------
#include <string>
#include "../JSInterface/JSInterface.h"
#include "../../../Conch/source/conch/JCSystemConfig.h"
namespace laya
{
class JSConchConfig:public JsObjBase
{
public:
static JsObjClassInfo JSCLSINFO;
void exportJS();
JSConchConfig();
~JSConchConfig();
static JSConchConfig* getInstance();
bool getUrlIgnoreCase();
void setUrlIgnoreCase(bool b);
int getNetworkType();
void setDownloadTryNum(int,int);
void setDownloadPathReplace(const char* p_pstrPath, const char* p_pszReplace);
void setDownloadTail(int type, const char* p_strTail);
//下载的时候修改文件的扩展名,以防止中间被修改。
//扩展名没有.
void setDownloadReplaceExt(const char* p_pszOrigin, const char* p_pszNew );
//是否转换文本文件的回车换行
void setDownloadIgnoreCRLR(bool b);
void resetDownloadIgnoreCRLR();
//设置不需要严格校验的文件。对于这些文件,如果校验失败了,则直接算作成功,并且保存下来
//扩展名有.
void addChkIgnoreChksumExt( const char* p_pszExt );
void clearChkIgnoreChksumExt();
//凡是扩展名为p_pszExt的文件,用key来进行异或操作,操作长度为p_nLen。如果p_nKey=0则去掉
//扩展名有.
void setDownloadUnmask(const char* p_pszExt, unsigned int p_nKey, int p_nLen );
void resetDownloadUnmask();
//如果传送过程中没有反应了,就在超时后重试,如果为0则不使用这一规则
void setDownloadNoResponseTimeout(int p_nDuration);
void resetDownloadNoResponseTimeout();
/** @brief 设置外部版本控制字符串,例如 index.htm?ver=10 则 p_pszVersion就是 ver
* @param p_pszVersion NULL或者 ""
*/
void setDownloadVersionString(const char* p_pszVersion);
void setMouseFrame(double thredholdms);
void setSlowFrame(bool p_bIsSlow);
void setLimitFPS(int nFpsNum);
void setScreenScale(float fScaleW, float fScaleH, float ftx, float fty);
float getScreenScaleW();
float getScreenScaleH();
void setCurlProxy(const char* pProxy);
void setWebsocketProxy(const char* pProxy);
bool getUseAndroidSystemFont();
void setUseAndroidSystemFont(bool b);
void setJSDebugMode(int nMode);
int getJSDebugMode();
void setJSDebugPort(int nPort);
int getJSDebugPort();
public:
const char* getLocalStoragePath();
float getTotalMem();
int getUsedMem();
int getAvalidMem();
float getScreenInch();
void setTouchMoveRange( float p_fMM );
void setScreenOrientation( int p_nOrientation );
bool getIsPlug();
bool getLocalable();
void setLocalable(bool isLocalPackage);
/**
* @brief url后加版本號的方法
* searchPart只有版本號字符串的時候
* 使searchPart
* v
* http://host/get?v=1, http://host/get?v=2 佔用同一個緩存文件
* http://host/get?v=1&bb=1 就不會佔用相同的緩存文件,
* http://host/get?id=1
* @param[in] p_strVersion
*/
//void setUrlVersionStr(const char* p_strVersion);
//const char* getUrlVersionStr();
void setDownloadConnTimeout(int tm);
void setDownloadOptTimeout(int tm);
int getGLCaps();
public:
const char* getOS();
const char* getBrowserInfo();
const char* getGuid();
//得到一个版本描述字符串
const char* getRuntimeVersion();
const char* getJsonparamExt();
const char* getDeviceInfo();
const char* getAppVersion();
const char* getAppLocalVersion();
void setTouchMode(bool bMode);
bool getTouchMode();
void setDebugLevel(int nLevel);
//设置图片释放的间隔时间
void setImageReleaseSpaceTime(int nSpaceTime);
//打开内存检测
void enableMemorySurvey(bool bEnable);
//打开内部的js和gl条状图
void showInternalPerfBar(int b, float scale);
//如果是android的话,使用choreographer
void useChoreographer(int b);
/*
android可以随时设置
*/
void setResolution(int w, int h);
void testSleep(int tm);
void setImageMisoperationWarningTime( int nSpaceTime );
float getCurrentDeviceSystemVersion();
void printAllMemorySurvey(char* sPath);
void enableEncodeURI(bool b);
void setSoundGarbageCollectionTime(int nTime);
int getThreadMode();
public:
static JSConchConfig* ms_pInstance;
std::string m_sGUID;
std::string m_sDeviceModel;
std::string m_sDeviceInfo;
std::string m_sAppVersion;
std::string m_sAppLocalVersion;
//std::string m_sVersionStr;
float m_fScreenScaleW = 1.0f;
float m_fScreenScaleH = 1.0f;
float m_fScreenTx = 0.0f;
float m_fScreenTy = 0.0f;
};
}
//------------------------------------------------------------------------------
#endif //__JSConchConfig_H__
//-----------------------------END FILE--------------------------------
@@ -0,0 +1,139 @@
/**
@file JSConsole.cpp
@brief
@author James
@version 1.0
@date 2016_5_18
*/
//包含头文件
#include "JSConsole.h"
#include "../JSInterface/JSInterface.h"
#include "util/Log.h"
#include "util/JCMemorySurvey.h"
namespace laya
{
ADDJSCLSINFO(JSConsole, JSObjNode);
JSConsole* JSConsole::m_spConsole = NULL;
//------------------------------------------------------------------------------
JSConsole::JSConsole()
{
AdjustAmountOfExternalAllocatedMemory( 4 );
JCMemorySurvey::GetInstance()->newClass( "console",4,this );
}
//------------------------------------------------------------------------------
JSConsole::~JSConsole()
{
m_spConsole = NULL;
JCMemorySurvey::GetInstance()->releaseClass( "console",this );
}
//------------------------------------------------------------------------------
JSConsole* JSConsole::GetInstance()
{
if( m_spConsole == NULL )
{
m_spConsole = new JSConsole();
}
return m_spConsole;
}
void JSConsole::DelInstance()
{
if( m_spConsole ){
delete m_spConsole;
m_spConsole = NULL;
}
}
//------------------------------------------------------------------------------
void JSConsole::log(int p_nType,const char* p_sBuffer )
{
LogLevel logLevel = (LogLevel)p_nType;
#ifdef WIN32
if( p_sBuffer==NULL)
return;
int nLen = strlen( p_sBuffer ) + 3;
if (nLen>3) {
unsigned short* ucStr = new unsigned short[nLen];
int nlen = UTF8StrToUnicodeStr((unsigned char*)p_sBuffer, ucStr, nLen);
switch (logLevel)
{
case Warn:
wprintf(L"warn:%s\n", (wchar_t *)ucStr);
break;
case Error:
wprintf(L"error:%s\n", (wchar_t *)ucStr);
break;
default:
wprintf(L"%s\n", (wchar_t *)ucStr);
break;
}
delete[] ucStr;
ucStr = NULL;
}
#elif __APPLE__
switch (logLevel)
{
case Warn:
LOGIExt(p_sBuffer);
break;
case Error:
LOGIExt(p_sBuffer);
break;
default:
LOGIExt(p_sBuffer);
break;
}
#else
switch (logLevel)
{
case Warn:
LOGI(" %s", p_sBuffer);
break;
case Error:
LOGI(" %s", p_sBuffer);
break;
default:
LOGI(" %s", p_sBuffer);
break;
}
#endif
#ifdef JS_V8
if (gLayaLogNoParam)
{
v8::HandleScope hs(mpJsIso);
int flags = v8::StackTrace::kLineNumber | v8::StackTrace::kScriptNameOrSourceURL | v8::StackTrace::kFunctionName;
int wantcount = 1;
v8::Local<StackTrace> curstack = v8::StackTrace::CurrentStackTrace(mpJsIso, wantcount, (v8::StackTrace::StackTraceOptions)flags);
int count = curstack->GetFrameCount();
for (int i = 0; i < count; i++ ){
v8::Local<StackFrame> curfrm = curstack->GetFrame(i);
v8::Local<v8::String> fname = curfrm->GetFunctionName();
std::string fnamestr = *v8::String::Utf8Value(fname->ToString());
int ln = curfrm->GetLineNumber();
v8::Local<v8::String> scname = curfrm->GetScriptName();
std::string srcfile;
if (!scname.IsEmpty()) {
srcfile = *v8::String::Utf8Value(scname->ToString());
}
v8::Local<v8::String> srcurl = curfrm->GetScriptNameOrSourceURL();
if (!srcurl.IsEmpty()) {
srcfile = *v8::String::Utf8Value(srcurl->ToString());
}
gLayaLogNoParam(Info, srcfile.c_str(), ln, p_sBuffer);
}
//gLayaLog(Info,
}
#endif
}
void JSConsole::exportJS()
{
JSP_GLOBAL_CLASS("_console", JSConsole);
JSP_ADD_METHOD("log", JSConsole::log);
JSP_INSTALL_GLOBAL_CLASS("_console", JSConsole, JSConsole::GetInstance());
}
}
//------------------------------------------------------------------------------
//-----------------------------END FILE--------------------------------
@@ -0,0 +1,49 @@
/**
@file JSConsole.h
@brief
@author James
@version 1.0
@date 2016_5_18
*/
#ifndef __JSConsole_H__
#define __JSConsole_H__
#include <stdio.h>
#include "../JSInterface/JSInterface.h"
/**
* @brief
*/
namespace laya
{
class JSConsole :public JsObjBase, public JSObjNode
{
public:
static JsObjClassInfo JSCLSINFO;
static void exportJS();
JSConsole();
~JSConsole();
static JSConsole* GetInstance();
static void DelInstance();
public:
void log(int p_nType, const char* p_sBuffer);
public:
static JSConsole* m_spConsole;
};
}
//------------------------------------------------------------------------------
#endif //__JSConsole_H__
//-----------------------------END FILE--------------------------------
@@ -0,0 +1,125 @@
/**
@file JSDOMParser.cpp
@brief
@author James
@version 1.0
@date 2016_5_18
*/
//包含头文件
#include "JSDOMParser.h"
#include <downloadMgr/JCDownloadMgr.h>
#include "../../JCScriptRuntime.h"
#include <util/Log.h>
#include <util/JCIThreadCmdMgr.h>
#define OnLoadJSFunctionID 0
#define OnErrorJSFunctionID 1
namespace laya
{
ADDJSCLSINFO(JSDOMParser, JSObjNode);
JSDOMParser::JSDOMParser()
{
jsDOC = NULL;
m_CallbackRef.reset(new int(1));
AdjustAmountOfExternalAllocatedMemory(640000);
JCMemorySurvey::GetInstance()->newClass("DOMParser", 640000, this);
}
JSDOMParser::~JSDOMParser()
{
JCMemorySurvey::GetInstance()->releaseClass("DOMParser", this);
if (jsDOC != NULL)
{
jsDOC = NULL;
}
}
JsValue JSDOMParser::parseFromString(const char *str, const char *type)
{
jsDOC = new JSXmlDocument();
jsDOC->parse(str);
return JSP_TO_JS(JSXmlDocument, jsDOC);
}
const char* JSDOMParser::getSrc()
{
return m_sUrl.c_str();
}
//这个可能在下载线程,所以不能是成员对象。
void JSDOM_onDownloadOK(JSDOMParser* pThis, JCResStateDispatcher* p_pRes, std::weak_ptr<int>& callbackref)
{
JCFileRes* pFileRes = (JCFileRes*)p_pRes;
if (pFileRes->m_pBuffer != NULL)
{
int length = pFileRes->m_nLength;
std::string xmlstr;
xmlstr.assign(pFileRes->m_pBuffer.get(), length);
auto pFunction = std::bind(&JSDOMParser::onLoadedCallJSFunction, pThis, xmlstr, callbackref);
JCScriptRuntime::s_JSRT->m_pPoster->postToJS(pFunction);
}
else
{
auto pFunction = std::bind(&JSDOMParser::onErrorCallJSFunction, pThis, -1, callbackref);
JCScriptRuntime::s_JSRT->m_pPoster->postToJS(pFunction);
}
}
void JSDOM_onDownloadError(JSDOMParser* pThis, JCResStateDispatcher*, int e, std::weak_ptr<int>& callbackref)
{
auto pFunction = std::bind(&JSDOMParser::onErrorCallJSFunction, pThis, e, callbackref);
JCScriptRuntime::s_JSRT->m_pPoster->postToJS(pFunction);
}
void JSDOMParser::setSrc(const char* p_sSrc)
{
m_sUrl = p_sSrc;
std::weak_ptr<int> cbref(m_CallbackRef);
JCFileRes* pRes =JCScriptRuntime::s_JSRT->m_pFileResMgr->getRes(m_sUrl);
pRes->setOnReadyCB(std::bind(JSDOM_onDownloadOK, this, std::placeholders::_1, cbref));
pRes->setOnErrorCB(std::bind(JSDOM_onDownloadError, this, std::placeholders::_1, std::placeholders::_2, cbref));
}
void JSDOMParser::SetOnload(JSValueAsParam p_pFunction)
{
m_pOnLoadJSFunction.set(OnLoadJSFunctionID, this, p_pFunction);
}
JsValue JSDOMParser::GetOnload()
{
return m_pOnLoadJSFunction.getJsObj();
}
void JSDOMParser::SetOnError(JSValueAsParam p_pFunction)
{
m_pOnErrorJSFunction.set(OnErrorJSFunctionID, this, p_pFunction);
}
JsValue JSDOMParser::GetOnError()
{
return m_pOnErrorJSFunction.getJsObj();
}
void JSDOMParser::onLoadedCallJSFunction(std::string& str, std::weak_ptr<int>& callbackref)
{
if (!callbackref.lock())return;
LOGI("download xml file seccuss! %s\n", m_sUrl.c_str());
jsDOC = new JSXmlDocument();
jsDOC->parse(str.c_str());
m_pOnLoadJSFunction.Call();
}
void JSDOMParser::onErrorCallJSFunction(int e, std::weak_ptr<int>& callbackref)
{
if (!callbackref.lock()) return;
m_pOnErrorJSFunction.Call(e);
}
JsValue JSDOMParser::getXml()
{
return JSP_TO_JS(JSXmlDocument, jsDOC);
}
void JSDOMParser::exportJS()
{
JSP_CLASS("_DOMParser", JSDOMParser);
JSP_ADD_METHOD("parseFromString", JSDOMParser::parseFromString);
JSP_ADD_PROPERTY(src, JSDOMParser, getSrc, setSrc);
JSP_ADD_PROPERTY(onload, JSDOMParser, GetOnload, SetOnload);
JSP_ADD_PROPERTY(onerror, JSDOMParser, GetOnError, SetOnError);
JSP_ADD_METHOD("getResult", JSDOMParser::getXml);
JSP_INSTALL_CLASS("_DOMParser", JSDOMParser);
}
}
//------------------------------------------------------------------------------
//-----------------------------END FILE--------------------------------
@@ -0,0 +1,55 @@
/**
@file JSXml.h
@brief
@author James
@version 1.0
@date 2015_5_5
*/
#ifndef __JSDOMParser_H__
#define __JSDOMParser_H__
#include <stdio.h>
#include "../JSInterface/JSInterface.h"
#include "resource/JCFileResManager.h"
#include "JSXmlNode.h"
/**
* @brief
*/
namespace laya
{
class JSDOMParser : public JsObjBase, public JSObjNode
{
public:
static JsObjClassInfo JSCLSINFO;
static void exportJS();
JSDOMParser();
~JSDOMParser();
JsValue parseFromString(const char * str,const char *type);
const char* getSrc();
void setSrc( const char* p_sSrc );
void SetOnload( JSValueAsParam p_pFunction );
JsValue GetOnload();
void SetOnError( JSValueAsParam p_pFunction );
JsValue GetOnError();
JsValue getXml();
public:
void onLoadedCallJSFunction(std::string& str,std::weak_ptr<int>& callbackref);
void onErrorCallJSFunction( int e , std::weak_ptr<int>& callbackref);
public:
std::shared_ptr<int> m_CallbackRef;
public:
std::string m_sUrl;
JsObjHandle m_pOnLoadJSFunction;
JsObjHandle m_pOnErrorJSFunction;
private:
JSXmlDocument* jsDOC;
};
}
#endif //__JSDOMParser_H__
//-----------------------------END FILE--------------------------------
@@ -0,0 +1,148 @@
/**
@file JSFile.cpp
@brief
@author James
@version 1.0
@date 2017_11_28
*/
#include "JSFile.h"
namespace laya
{
ADDJSCLSINFO(JsBlob, JSObjNode);
ADDJSCLSINFO(JsFile, JsBlob);
JsFile::JsFile()
{
m_pszName = 0;
m_iPos = __IsLocal;
m_bEnableCache = true;
UpdateTime();
AdjustAmountOfExternalAllocatedMemory(301);
JCMemorySurvey::GetInstance()->newClass("JsFile", 301, this);
}
JsFile::JsFile(const char *p_pszName)
{
m_pszName = 0;
m_iPos = __IsLocal;
m_bEnableCache = true;
UpdateTime();
SetName(p_pszName);
AdjustAmountOfExternalAllocatedMemory(301);
JCMemorySurvey::GetInstance()->newClass("JsFile", 301, this);
}
JsFile::JsFile(const char *p_pszName, const char *p_pszType)
{
m_pszName = 0;
m_iPos = __IsLocal;
m_bEnableCache = true;
UpdateTime();
SetName(p_pszName);
SetType(p_pszType);
AdjustAmountOfExternalAllocatedMemory(301);
JCMemorySurvey::GetInstance()->newClass("JsFile", 301, this);
}
JsFile::~JsFile()
{
if (0 != m_pszName)
{
delete[] m_pszName;
m_pszName = 0;
}
JCMemorySurvey::GetInstance()->releaseClass("JsFile", this);
}
void JsFile::UpdateTime(time_t p_tm) // unix timestamp
{
if (0 == p_tm)
{
p_tm = time(0);
}
lastModifiedDate = p_tm;
lastModifiedDate *= 1000;
}
JsValue JsFile::GetlastModifiedDate()
{
return (__TransferToJs<int64_t>::ToJsDate(lastModifiedDate));
}
const char *JsFile::GetName()
{
if (0 == m_pszName)
return "";
else
return m_pszName;
}
//给 m_FullName 和 m_pszName 赋值
void JsFile::SetName(const char *p_pszName)
{
if (0 != m_pszName)
{
delete[] m_pszName;
m_pszName = 0;
}
size_t len;
if (0 == p_pszName || 0 == (len = strlen(p_pszName)))
{
return;
}
if (len > 7 && (strncasecmp(p_pszName, "http://", 7) == 0 || strncasecmp(p_pszName, "https://", 8) == 0))
{
m_iPos = __IsRemote;
//由于在复杂的url中有?:|等很多符号,容易导致非法。所以需要处理一下
m_FullName = p_pszName;
const char* pQpos = strchr(p_pszName, '?');
int len = strlen(p_pszName);
if (pQpos) len = pQpos - p_pszName;
std::string strName = "";
strName.append(p_pszName, len);
std::string strname = fs::path(strName).filename().generic_string();
len = strname.length();
if (len > 0)
{
m_pszName = new char[len + 1];
memcpy(m_pszName, strname.c_str(), len + 1);
}
}
else
{
m_iPos = __IsLocal;
if (len > 7 && strncasecmp(p_pszName, "file://", 7) == 0)
p_pszName += 7;
if (p_pszName[2] == ':') //有盘符
p_pszName++;
const char* pQpos = strchr(p_pszName, '?');
int len = strlen(p_pszName);
if (pQpos) len = pQpos - p_pszName;
std::string strName = "";
strName.append(p_pszName, len);
m_FullName = strName.c_str();
std::string strname = fs::path(m_FullName).filename().generic_string();
len = strname.length();
if (len > 0)
{
m_pszName = new char[len + 1];
memcpy(m_pszName, strname.c_str(), len + 1);
}
}
}
void JsFile::RegisterToJS()
{
JSP_CLASS("File", JsFile);
JSP_ADD_PROPERTY_RO(lastModifiedDate, JsFile, GetlastModifiedDate);
JSP_ADD_PROPERTY_RO(name, JsFile, GetName);
JSP_ADD_PROPERTY_RO(size, JsFile, GetSize);
JSP_ADD_PROPERTY_RO(type, JsFile, GetType);
JSP_ADD_METHOD("close", JsFile::close);
JSP_ADD_METHOD("slice", JsFile::slice);
JSP_ADD_PROPERTY(enableCache, JsFile, getEnableCache, setEnableCache);
JSP_REG_CONSTRUCTOR(JsFile, const char *);
JSP_REG_CONSTRUCTOR(JsFile, const char *, const char *);
JSP_INSTALL_CLASS("File", JsFile);
}
}
//------------------------------------------------------------------------------
//-----------------------------END FILE--------------------------------
@@ -0,0 +1,84 @@
/**
@file JSFile.h
@brief
@author James
@version 1.0
@date 2017_11_28
*/
#ifndef __JSFile_H__
#define __JSFile_H__
#include "../JSInterface/JSInterface.h"
#include <time.h>
#include "JsBlob.h"
#include <util/JCMemorySurvey.h>
#include <fileSystem/JCFileSystem.h>
#ifdef WIN32
#define strcasecmp _stricmp
#define strncasecmp _strnicmp
#endif
namespace laya
{
class JsFile : public JsBlob
{
public:
JsFile();
JsFile(const char *p_pszName);
JsFile(const char *p_pszName, const char *p_pszType);
~JsFile();
void UpdateTime(time_t p_tm = 0);
JsValue GetlastModifiedDate();
const char *GetName();
void SetName(const char *p_pszName);
bool getEnableCache()
{
return m_bEnableCache;
}
void setEnableCache(bool b)
{
m_bEnableCache = b;
}
static void RegisterToJS();
public:
static JsObjClassInfo JSCLSINFO;
friend class JsFileReader;
enum
{
__IsLocal = 0,
__IsRemote = 1,
};
protected:
long long lastModifiedDate;
/*
* file://和?后的内容。
* cache的key
*/
std::string m_FullName;
int m_iPos;
char* m_pszName;
bool m_bEnableCache;
};
}
//------------------------------------------------------------------------------
#endif //__JSFile_H__
//-----------------------------END FILE--------------------------------
@@ -0,0 +1,430 @@
/**
@file JSFileReader.cpp
@brief
@author James
@version 1.0
@date 2017_11_28
*/
#include "JSFileReader.h"
#include <resource/JCFileResManager.h>
#include <thread>
#include <util/Log.h>
#include <util/JCZlib.h>
#include <util/JCMemorySurvey.h>
#include "../../JCScriptRuntime.h"
#include "JSGlobalExportCFun.h"
#include <fstream>
namespace laya
{
bool IsTextUTF8(char* str, unsigned long length)
{
unsigned long nBytes = 0;//UFT8可用1-6个字节编码,ASCII用一个字节
unsigned char chr;
bool bAllAscii = true; //如果全部都是ASCII, 说明不是UTF-8
for (size_t i = 0; i < length; i++)
{
chr = *(str + i);
if ((chr & 0x80) != 0) // 判断是否ASCII编码,如果不是,说明有可能是UTF-8,ASCII用7位编码,但用一个字节存,最高位标记为0,o0xxxxxxx
bAllAscii = false;
if (nBytes == 0) //如果不是ASCII码,应该是多字节符,计算字节数
{
if (chr >= 0x80)
{
if (chr >= 0xFC && chr <= 0xFD)
nBytes = 6;
else if (chr >= 0xF8)
nBytes = 5;
else if (chr >= 0xF0)
nBytes = 4;
else if (chr >= 0xE0)
nBytes = 3;
else if (chr >= 0xC0)
nBytes = 2;
else
{
return false;
}
nBytes--;
}
}
else //多字节符的非首字节,应为 10xxxxxx
{
if ((chr & 0xC0) != 0x80)
{
return false;
}
nBytes--;
}
}
if (nBytes > 0) //违返规则
{
return false;
}
if (bAllAscii) //如果全部都是ASCII, 说明不是UTF-8
{
return true;
}
return true;
}
ADDJSCLSINFO(JsFileReader, JSObjNode);
JsFileReader::JsFileReader()
{
m_nResponseType = 0;
m_bSync = false;
m_nBufferSize = 0;
readyState = EMPTY;
m_pszError = 0;
m_iContentType = content_type_string;
AdjustAmountOfExternalAllocatedMemory(86);
JCMemorySurvey::GetInstance()->newClass("JsFileReader", 86, this);
m_CallbackRef.reset(new int(1));
m_bIgnoreError = false;
m_pFile = NULL;
}
JsFileReader::~JsFileReader()
{
JCMemorySurvey::GetInstance()->releaseClass("JsFileReader", this);
}
void JsFileReader::readAsArrayBuffer(JSValueAsParam p_pFile)
{
m_iContentType = content_type_buffer;
m_pFile = (JsFile*)__TransferToCpp<JsFile*>::ToCpp(p_pFile);
m_hFileObject.set(6, this, p_pFile);
__LoadRemoteFile(m_pFile);
}
void JsFileReader::readAsText(JSValueAsParam p_pFile)
{
m_iContentType = content_type_string;
m_pFile = (JsFile*)__TransferToCpp<JsFile*>::ToCpp(p_pFile);
m_hFileObject.set(6, this, p_pFile);
__LoadRemoteFile(m_pFile);
}
void JsFileReader::readAsDataURL(JSValueAsParam p_pFile)
{
m_hFileObject.set(6, this, p_pFile);
return;
}
void JsFileReader::__LoadLocalFile(JsFile *p_pFile)
{
OnStart();
p_pFile->close();
size_t iFileSize;
std::time_t tmLastWrite;
try
{
iFileSize = (size_t)fs::file_size(p_pFile->m_FullName);
#ifdef WIN32
tmLastWrite = std::chrono::system_clock::to_time_t(fs::last_write_time(p_pFile->m_FullName));
#else
tmLastWrite = fs::last_write_time(p_pFile->m_FullName);
#endif
}
catch (fs::filesystem_error &ec)
{
printf("read file error :%s\n", ec.what());
OnFinished(false, JsFileReaderErr_NotFoundError);
return;
}
if (0 == iFileSize)
{
OnFinished(false, JsFileReaderErr_NotFoundError);
return;
}
std::ifstream ifile;
ifile.open(p_pFile->m_FullName.c_str(), std::ios::in | std::ios::binary);
if (!ifile.is_open())
{
OnFinished(false, JsFileReaderErr_SecurityError);
return;
}
if (content_type_string == m_iContentType)
{
//判断是否有BOM,如果有,就去掉
if (iFileSize >= 3) {
int bom = 0;
ifile.read((char*)&bom, 3);
if (ifile.gcount() == 3) {
if (bom == 0xbfbbef) {
iFileSize -= 3;
}
else {
ifile.seekg(0);
}
}
else {
OnFinished(false, JsFileReaderErr_NotReadableError);
ifile.close();
return;
}
}
p_pFile->Allocate(iFileSize + 1);
ifile.read(p_pFile->m_pBuffer, iFileSize);
if (ifile.gcount() != iFileSize) {
OnFinished(false, JsFileReaderErr_NotReadableError);
ifile.close();
return;
}
p_pFile->m_pBuffer[iFileSize] = 0;
p_pFile->m_i64Size--;
}
else
{
LOGE("JsFileReader::__LoadLocalFile not implement yet!");
throw - 1;
p_pFile->Allocate(iFileSize);
ifile.read(p_pFile->m_pBuffer, iFileSize);
if (ifile.gcount() != iFileSize) {
OnFinished(false, JsFileReaderErr_NotReadableError);
ifile.close();
return;
}
}
ifile.close();
p_pFile->UpdateTime(tmLastWrite);
OnFinished(true);
}
/*
std::mutex g_kMutex;
*/
/*
http文件
*/
void JsFileReader::__LoadRemoteFile(JsFile *p_pFile)
{
retainThis(); //防止被釋放
OnStart();
if (m_bSync)
{
}
else
{
std::string file = p_pFile->m_FullName;
if (p_pFile->m_iPos == JsFile::__IsLocal)
{
file = std::string("file:///") + file;
}
JCFileResManager* pfsMgr = JCScriptRuntime::s_JSRT->m_pFileResMgr;
JCFileRes* res = pfsMgr->getRes(file,m_nConnTimeout, m_nOptTimeout);
res->setIgnoreError(m_bIgnoreError);
std::weak_ptr<int> cbref(m_CallbackRef);
res->setOnReadyCB(std::bind(&JsFileReader::onDownloadEnd, this, p_pFile, std::placeholders::_1, cbref));
res->setOnErrorCB(std::bind(&JsFileReader::onDownloadErr, this, std::placeholders::_1, std::placeholders::_2, cbref));
}
}
bool JsFileReader::onDownloadEnd(JsFile *p_pFile, void* p_pRes, std::weak_ptr<int> callbackref)
{
if (!callbackref.lock())
return false;
JCResStateDispatcher* pRes = (JCResStateDispatcher*)p_pRes;
JCFileRes* pFileRes = (JCFileRes*)pRes;
if (pFileRes->m_pBuffer.get() == NULL || pFileRes->m_nLength == 0)
{
OnFinished(false, JsFileReaderErr_NotFoundError);
return false;
}
else
{
unsigned char* pBuff = (unsigned char*)(pFileRes->m_pBuffer.get());
int nLen = pFileRes->m_nLength;
//-------------------------------------------------
//解压
//-------------------------------------------------
int nOffset = 0;
uLong nUncompressSize = getLayaBoxUncompressSize(pBuff, nLen, nOffset);
if (nUncompressSize > 0)
{
double nTime = tmGetCurms();
unsigned char* sUCBuffer = new unsigned char[nUncompressSize];
memset(sUCBuffer, 0, nUncompressSize);
if (uncompress(sUCBuffer, &nUncompressSize, pBuff + nOffset, nLen) != Z_OK)
{
delete[] sUCBuffer;
sUCBuffer = NULL;
//解压失败
OnFinished(false);
return false;
}
nLen = nUncompressSize;
pBuff = sUCBuffer;
int nSpace = (int)(tmGetCurms() - nTime);
LOGI("LayaUncompress time=%d fileName=%s", nSpace, p_pFile->GetName());
//-------------------------------------------------
//-------------------------------------------------
}
//临时存储一下为了删除,因为下去去掉bom,指针会被改变
unsigned char* pTemp = pBuff;
if (content_type_string == m_iContentType)
{
#ifdef __APPLE__
if (IsTextUTF8((char*)pBuff, nLen) == false)
{
char sBuffer[1024] = { 0 };
sprintf(sBuffer, "严重错误 iOS does not support non utf8 format files url=%s", p_pFile->GetName());
LOGE( sBuffer );
}
#endif
//循环去掉BOM
while (true)
{
if (nLen >= 3 && ((*(int*)pBuff) & 0x00ffffff) == 0xbfbbef)
{
nLen -= 3;
pBuff += 3;
}
else
{
break;
}
}
p_pFile->Allocate(nLen + 1);
memcpy(p_pFile->m_pBuffer, pBuff, nLen);
p_pFile->m_pBuffer[nLen] = 0;
p_pFile->m_i64Size--;
}
else
{
p_pFile->Allocate(nLen);
memcpy(p_pFile->m_pBuffer, pBuff, nLen);
}
//析构
if (nUncompressSize > 0)
{
delete[] pTemp;
pTemp = 0;
}
OnFinished(true);
}
return true;
}
void JsFileReader::onDownloadErr(void* p_pRes, int p_nErrCode, std::weak_ptr<int> callbackref)
{
if (!callbackref.lock())
return;
JCFileRes* pFRes = (JCFileRes*)p_pRes;
m_strSvIP = pFRes->m_strSvIP;
m_nErrorCode = pFRes->m_nErrNo;
m_nHttpResponse = pFRes->m_nLastHttpResponse;
if (p_nErrCode == 1)
OnFinished(false, JsFileReaderErr_NotFoundError);
else
OnFinished(false, "UnknownError");
}
void JsFileReader::OnFinished(bool p_bSuccess, const char *p_pszError)
{
if (!IsMyJsEnv())return;
if (p_bSuccess)
{
m_pszError = 0;
readyState = DONE;
if (m_pFile)
m_pFile->UpdateTime();
onload.Call();
}
else
{
if (m_pFile)
m_pFile->close();
m_pszError = JsFileReaderErr_NotReadableError;
readyState = DONE;
onerror.Call(p_pszError);
}
onloadend.Call();
m_pszError = 0;
readyState = EMPTY;
m_hFileObject.Reset(); //完成后,要把对File的引用去掉
m_pFile = 0;
releaseThis();
}
JsValue JsFileReader::GetResult()
{
if (DONE != readyState) {
return JSP_TO_JS_UNDEFINE;
}
else if (0 == m_pFile || 0 == m_pFile->m_i64Size) {
return JSP_TO_JS_NULL;
}
else if (content_type_buffer == m_iContentType)
{
if (m_pFile->m_i64Size <= 0 || m_pFile->m_pBuffer == NULL) {
return JSP_TO_JS_NULL;
}
if (m_pFile->m_i64Size > 0x7fffffff) {
LOGE("文件太大,无法返回!%s", (char*)m_pFile->m_FullName.c_str());
throw - 1;
}
return createJSAB(m_pFile->m_pBuffer, (int)m_pFile->m_i64Size);
//JSArrayBuffer* pAB = JSArrayBuffer::create((int)m_pFile->m_i64Size);
//memcpy( pAB->getPtr(),m_pFile->m_pBuffer,(int)m_pFile->m_i64Size);
//return (pAB->toLocal());
}
else
{
if (m_nResponseType == 1)
{
if (m_pFile->m_i64Size > 0x7fffffff) {
LOGE("文件太大,无法返回!%s", (char*)m_pFile->m_FullName.c_str());
throw - 1;
}
return createJSAB(m_pFile->m_pBuffer, (int)m_pFile->m_i64Size);
//JSArrayBuffer* pAB = JSArrayBuffer::create((int)m_pFile->m_i64Size);
//memcpy( pAB->getPtr(),m_pFile->m_pBuffer,(int)m_pFile->m_i64Size);
//return (pAB->toLocal());
//return JSP_TO_JS_BYTE_ARRAY( (unsigned char *)(m_hFile.m_pFile->m_pBuffer),m_hFile.m_pFile->m_i64Size );
}
else
{
return (JSP_TO_JS_STR(m_pFile->m_pBuffer));
}
}
}
void JsFileReader::setConnTimeout(int tm) {
m_nConnTimeout = tm;
}
void JsFileReader::setOptTimeout(int tm) {
m_nOptTimeout = tm;
}
char* JsFileReader::getSVIP() {
return (char*)m_strSvIP.c_str();
}
void JsFileReader::RegisterToJS()
{
JSP_CLASS("FileReader", JsFileReader);
JSP_ADD_FIXED_PROPERTY(EMPTY, JsFileReader, (int)JsFileReader::EMPTY);
JSP_ADD_FIXED_PROPERTY(LOADING, JsFileReader, (int)JsFileReader::LOADING);
JSP_ADD_FIXED_PROPERTY(DONE, JsFileReader, (int)JsFileReader::DONE);
JSP_ADD_PROPERTY_RO(readyState, JsFileReader, GetReadyState);
JSP_ADD_PROPERTY_RO(error, JsFileReader, GetError);
JSP_ADD_PROPERTY_RO(result, JsFileReader, GetResult);
JSP_ADD_PROPERTY(onloadstart, JsFileReader, Get_onloadstart, Set_onloadstart);
JSP_ADD_PROPERTY(onprogress, JsFileReader, Get_onprogress, Set_onprogress);
JSP_ADD_PROPERTY(onload, JsFileReader, Get_onload, Set_onload);
JSP_ADD_PROPERTY(onabort, JsFileReader, Get_onabort, Set_onabort);
JSP_ADD_PROPERTY(onerror, JsFileReader, Get_onerror, Set_onerror);
JSP_ADD_PROPERTY(onloadend, JsFileReader, Get_onloadend, Set_onloadend);
JSP_ADD_PROPERTY(sync, JsFileReader, GetSync, SetSync);
JSP_ADD_PROPERTY(responseType, JsFileReader, getResponseType, setResponseType);
JSP_ADD_METHOD("abort", JsFileReader::abort);
JSP_ADD_METHOD("readAsArrayBuffer", JsFileReader::readAsArrayBuffer);
JSP_ADD_METHOD("readAsText", JsFileReader::readAsText);
JSP_ADD_METHOD("readAsDataURL", JsFileReader::readAsDataURL);
JSP_ADD_METHOD("setIgnoreError", JsFileReader::setIgnoreError);
JSP_ADD_METHOD("getErrorCode", JsFileReader::getErrorCode);
JSP_ADD_METHOD("getHttpCode", JsFileReader::getHttpResponseCode);
JSP_ADD_METHOD("getSVIP", JsFileReader::getSVIP);
JSP_ADD_METHOD("setConnTimeout", JsFileReader::setConnTimeout);
JSP_ADD_METHOD("setOptTimeout", JsFileReader::setOptTimeout);
JSP_INSTALL_CLASS("FileReader", JsFileReader);
}
}
//------------------------------------------------------------------------------
//-----------------------------END FILE--------------------------------
@@ -0,0 +1,188 @@
/**
@file JSFileReader.h
@brief
@author James
@version 1.0
@date 2017_11_28
*/
#ifndef __JSFileReader_H__
#define __JSFileReader_H__
//------------------------------------------------------------------------------
#include "../JSInterface/JSInterface.h"
#include "JSFile.h"
#include <util/JCMemorySurvey.h>
namespace laya
{
#define __Js_FileReader_Property_Func(pfn,n) \
JsValue Get_##pfn() \
{return (pfn.getJsObj());} \
void Set_##pfn( JSValueAsParam p_pfn) \
{ \
pfn.set(n,this,p_pfn); \
}
class JsFileReader :public JsObjBase, public JSObjNode
{
public:
JsFileReader();
~JsFileReader();
//以二进制格式读取文件内容
void readAsArrayBuffer(JSValueAsParam p_pFile);
//以文本(及字符串)格式读取文件内容,并且可以强制选择文件编码
void readAsText(JSValueAsParam p_pFile);
// 以DataURL格式读取文件内容,主要为了直接嵌入网页
void readAsDataURL(JSValueAsParam p_pFile);
void __LoadLocalFile(JsFile *p_pFile);
void __LoadRemoteFile(JsFile *p_pFile);
bool onDownloadEnd(JsFile *p_pFile, void* p_pRes, std::weak_ptr<int> callbackref);
void onDownloadErr(void* p_pRes, int p_nErrCode, std::weak_ptr<int> callbackref);
void OnFinished(bool p_bSuccess, const char *p_pszError = 0);
JsValue GetResult();
static void RegisterToJS();
//如果需要下载的话,设置超时参数。非标准
void setConnTimeout(int tm);
void setOptTimeout(int tm);
char* getSVIP();
public:
void SetContenttype(int p_iType)
{
switch (p_iType)
{
case content_type_string:
case content_type_buffer:
m_iContentType = p_iType;
break;
default:
break;
}
}
unsigned int GetReadyState()
{
return readyState;
}
const char *GetError()
{
return m_pszError;
}
void abort()
{
JSP_THROW("abort not impl");
}
void OnFinishedSafe(bool p_bSuccess, const char *p_pszError, std::weak_ptr<int> callbackref)
{
if (!callbackref.lock())
return;
OnFinished(p_bSuccess, p_pszError);
}
void OnStart()
{
readyState = LOADING;
onloadstart.Call();
}
void OnProgress(size_t p_iSaved, size_t p_iTotal)
{
}
bool GetSync()
{
return m_bSync;
}
void setIgnoreError(bool b)
{
m_bIgnoreError = b;
}
void SetSync(bool p_bSync)
{
m_bSync = p_bSync;
}
void setResponseType(int p_nResponseType)
{
m_nResponseType = p_nResponseType;
}
int getResponseType()
{
return m_nResponseType;
}
int getErrorCode() { return m_nErrorCode; }
int getHttpResponseCode() { return m_nHttpResponse; }
public:
static JsObjClassInfo JSCLSINFO;
enum
{
EMPTY = 0,
LOADING = 1,
DONE = 2,
NotFoundError = 0,
SecurityError = 1,
NotReadableError = 2,
content_type_string = 0,
content_type_buffer = 1,
};
protected:
#define JsFileReaderErr_NotFoundError "NotFoundError"
#define JsFileReaderErr_SecurityError "SecurityError"
#define JsFileReaderErr_NotReadableError "NotReadableError"
JsFile* m_pFile;
JsObjHandle m_hFileObject;
JsObjHandle onloadstart; // 在读取开始时触发
JsObjHandle onprogress; // 在读取进行中定时触发
JsObjHandle onload; // 在读取成功结束后触发
JsObjHandle onabort; // 在读取中断时触发
JsObjHandle onerror; // 在读取错误时触发
JsObjHandle onloadend; // 在读取结束后,无论成功或者失败都会触发
const char* m_pszError;
unsigned int readyState;
static const char* s_ErrorStr[];
int m_iContentType;
std::shared_ptr<int> m_CallbackRef;
bool m_bSync; //是否为同步加载
int m_nBufferSize; //buffersize
int m_nResponseType;
bool m_bIgnoreError;
int m_nErrorCode = 0;
int m_nHttpResponse = 0;
std::string m_strSvIP; //调试用。
int m_nConnTimeout = 0;
int m_nOptTimeout = 0;
public:
__Js_FileReader_Property_Func(onloadstart, 0);
__Js_FileReader_Property_Func(onprogress, 1);
__Js_FileReader_Property_Func(onabort, 2);
__Js_FileReader_Property_Func(onloadend, 3);
__Js_FileReader_Property_Func(onload, 4);
__Js_FileReader_Property_Func(onerror, 5);
};
}
//------------------------------------------------------------------------------
#endif //__JSFileReader_H__
//-----------------------------END FILE--------------------------------
@@ -0,0 +1,178 @@
/**
@file JSFileSystem.cpp
@brief
@author James
@version 1.0
@date 2017_11_28
*/
#include "JSFileSystem.h"
#include "../JSInterface/JSInterface.h"
#include <util/Log.h>
#include <fileSystem/JCFileSystem.h>
namespace laya
{
bool JSFileSystem::exists(const char* p_pszPath )
{
bool bret = false;
try {
bret = fs::exists(p_pszPath);
}
catch (...) {
return false;
}
return bret;
}
bool JSFileSystem::mkdir( const char* p_pszPath )
{
bool bret = false;
try
{
bret = fs::create_directories(p_pszPath);
}
catch (...)
{
return false;
}
return bret;
}
bool ChkPermission( const char* p_pszFile, const char* p_pszDesc )
{
return true;
}
bool JSFileSystem::rm(const char* p_pszFile)
{
if(!ChkPermission(p_pszFile,"rm is forbidden!"))
{
return false;
}
try
{
return fs::remove(p_pszFile);
}
catch (...)
{
return false;
}
}
bool JSFileSystem::rmDir(const char* p_pszPath, JSValueAsParam onprogress, JSValueAsParam oncomplete, JSValueAsParam onerror)
{
return true;
}
bool JSFileSystem::rmDirSync(const char* p_pszPath)
{
return true;
}
JsValue JSFileSystem::readdirSync(const char* pPath)
{
std::vector < std::string> paths;
std::string path = pPath;
if (!fs::exists(path))
return JSP_TO_JS_NULL;
fs::directory_iterator item_begin(path);
fs::directory_iterator item_end;
for (; item_begin != item_end; item_begin++) {
auto pp = (*item_begin).path().filename();
paths.push_back(pp.generic_string());
}
return __TransferToJs<std::vector<std::string> >::ToJs(paths);
}
JsValue JSFileSystem::lstatSync(const char* pPath)
{
std::vector < std::string> paths;
std::string path = pPath;
if (!fs::exists(path))
return JSP_TO_JS_NULL;
try {
auto st = fs::status(path);
std::time_t wtime;
#ifdef WIN32
wtime = std::chrono::system_clock::to_time_t(fs::last_write_time(path));
#else
wtime = fs::last_write_time(path);
#endif
bool isDir = fs::is_directory(st);
bool isFile = fs::is_regular_file(st);
int sz = 0;
if (!isDir)sz = (int)fs::file_size(path);
#ifdef JS_V8
//st.type;
v8::Isolate* pIso = v8::Isolate::GetCurrent();
//v8::HandleScope scope(pIso); 不用了,还得想办法escape
v8::Local<v8::Object> retobj = v8::Object::New(pIso);
retobj->Set(Js_Str(pIso, "isDirectory"), v8::Boolean::New(pIso, isDir));
retobj->Set(Js_Str(pIso, "isFile"), v8::Boolean::New(pIso, isFile));
retobj->Set(Js_Str(pIso, "size"), v8::Number::New(pIso, sz));
retobj->Set(Js_Str(pIso, "mtime"), v8::Date::New(pIso, (double)(wtime*1000)));
return retobj;
#elif JS_JSC
JSContextRef ctx = laya::__TlsData::GetInstance()->GetCurContext();
JSObjectRef retobj = JSObjectMake(ctx, nullptr, nullptr);
JSObjectSetProperty(ctx, retobj, JSStringCreateWithUTF8CString("isDirectory"), JSValueMakeBoolean(ctx, isDir), kJSPropertyAttributeNone, nullptr);
JSObjectSetProperty(ctx, retobj, JSStringCreateWithUTF8CString("isFile"), JSValueMakeBoolean(ctx,isFile), kJSPropertyAttributeNone, nullptr);
JSObjectSetProperty(ctx, retobj, JSStringCreateWithUTF8CString("size"), JSValueMakeNumber(ctx,sz), kJSPropertyAttributeNone, nullptr);
JSObjectSetProperty(ctx, retobj, JSStringCreateWithUTF8CString("mtime"), laya::__TransferToJs<long>::ToJsDate(wtime*1000), kJSPropertyAttributeNone, nullptr);
return retobj;
#endif
}
catch (...)
{
JSP_THROW("lstatSync error!");
}
return JSP_TO_JS_NULL;
}
bool JSFileSystem::JSWriteFileSync(const char* p_sUrl, JSValueAsParam args)
{
if (!p_sUrl) return false;
char* pABPtr = NULL;
int nABLen = 0;
bool bisab = extractJSAB(args, pABPtr, nABLen);
bool bret = false;
if (bisab)
{
if (pABPtr && nABLen > 0)
{
bret = writeFileSync1(p_sUrl, pABPtr, nABLen, 0);
}
}
else
{
if (__TransferToCpp<char *>::is(args))
{
char* pData = JS_TO_CPP(char*, args);
if ( pData )
{
int len = strlen(pData);
JCBuffer buf((char*)pData, len, false, false);
bret = writeFileSync( p_sUrl, buf, JCBuffer::utf8);
}
}
}
return bret;
}
JsValue JSFileSystem::readBinFileSync(const char* p_pszFile)
{
if(!ChkPermission(p_pszFile,"readBinFileSync is forbidden!"))
{
return JSP_TO_JS_NULL;
}
JCBuffer buf;
if (readFileSync(p_pszFile, buf, JCBuffer::raw))
{
return laya::createJSAB(buf.m_pPtr, buf.m_nLen);
}
else
{
return JSP_TO_JS_NULL;
}
}
void JSFileSystem::exportJS()
{
}
};
//------------------------------------------------------------------------------
//-----------------------------END FILE--------------------------------
@@ -0,0 +1,36 @@
/**
@file JSFileSystem.h
@brief
@author James
@version 1.0
@date 2017_11_28
*/
#ifndef __JSFileSystem_H__
#define __JSFileSystem_H__
#include "../JSInterface/JSInterface.h"
namespace laya
{
class JSFileSystem
{
public:
static void exportJS();
static bool exists(const char* p_pszPath );
static bool mkdir( const char* p_pszPath );
static bool rm(const char* p_pszFile);
static bool rmDir(const char* p_pszPath, JSValueAsParam onprogress, JSValueAsParam oncomplete, JSValueAsParam onerror);
static bool rmDirSync(const char* p_pszPath);
static JsValue readBinFileSync(const char* p_pszFile);
static JsValue readdirSync(const char* pPath);
static JsValue lstatSync(const char* pPath);
static bool JSWriteFileSync(const char* p_sUrl, JSValueAsParam args);
};
}
//------------------------------------------------------------------------------
#endif //__JSFileSystem_H__
//-----------------------------END FILE--------------------------------
@@ -0,0 +1,527 @@
/**
@file JSGlobalExportCFun.cpp
@brief
@author James
@version 1.0
@date 2013_11_12
*/
#include "JSGlobalExportCFun.h"
#include "../JSInterface/JSInterface.h"
#include <util/Log.h>
#include <util/JCCommonMethod.h>
#include <fileSystem/JCFileSystem.h>
#include <util/JCMemorySurvey.h>
#include <util/JCLayaUrl.h>
#include <util/JCCrypto.h>
#include <util/Log.h>
#include "JSConsole.h"
#include "XMLHttpRequest.h"
#include "JSConchConfig.h"
#include "JSXmlNode.h"
#include "JSXmlAttr.h"
#include "JSDOMParser.h"
#include "JSAudio.h"
#include "JSAppCache.h"
#include "JSWebSocket.h"
#include "JSFileSystem.h"
#include "JSZip.h"
#include "JSNotify.h"
#ifdef ANDROID
#include "JSAndroidEditBox.h"
#include "../../CToJavaBridge.h"
#elif WIN32
#include <Windows.h>
#include "JSWindowEditBox.h"
#elif __APPLE__
#include "JSIOSEditBox.h"
#include "CToObjectC.h"
#endif
#include "JSRuntime.h"
#include "../../JCConch.h"
#include <downloadCache/JCFileSource.h>
#include "JSImage.h"
#include "JSHistory.h"
#include "JSTextMemoryCanvas.h"
#include <downloadMgr/JCDownloadMgr.h>
#include "JSLayaGL.h"
#include "JSShaderActiveInfo.h"
#include "JSTextBitmapInfo.h"
#include "JSShaderPrecisionFormat.h"
#include "JSCallbackFuncObj.h"
#include "Bullet/bullet_glue.h"
#include "Video/JSVideo.h"
#include <LayaGL/JCLayaGLDispatch.h>
#include "JCWebGLPlus.h"
#include "Bullet/LayaBulletExport.h"
extern int g_nInnerWidth ;
extern int g_nInnerHeight ;
extern bool g_bGLCanvasSizeChanged;
#ifdef WIN32
int g_bEnableTouch = false;
#elif ANDROID
int g_bEnableTouch = true;
#elif __APPLE__
int g_bEnableTouch = true;
#endif
std::string g_sExePath = "";
/** @brief 这个函数是为了实现comman库中的alert函数
*
*/
void alert(const char* fmt, ...)
{
char buf[1024];
char* pBuf = NULL;
va_list args;
va_start(args, fmt);
int len = vsprintf(buf, fmt, args);
if (len < 0) {
pBuf = new char[4096];
len = vsprintf(pBuf, fmt, args);
}
va_end(args);
laya::LayaAlert(pBuf ? pBuf : buf);
if (pBuf)
{
delete[] pBuf;
}
}
namespace laya
{
//下载大文件,zip用的
struct JSFuncWrapper :public JsObjBase
{
enum { onprogid, oncompid };
static JsObjClassInfo JSCLSINFO;
JsObjHandle funcOnProg;
JsObjHandle funcOnComp;
bool stop;
JSFuncWrapper(JSValueAsParam onprog, JSValueAsParam onComp)
{
createJSObj();
funcOnProg.set(onprogid, this, onprog);
funcOnComp.set(oncompid, this, onComp);
stop = false;
}
};
ADDJSCLSINFO(JSFuncWrapper, JSObjNode);
void downloadBig_onProg_js(JSFuncWrapper* pWrapper, unsigned int total, unsigned int now, float speed)
{
if (pWrapper->funcOnProg.Empty())return;
pWrapper->funcOnProg.Call(total, now, speed);
pWrapper->stop = __TransferToCpp<bool>::ToCpp(pWrapper->funcOnProg.m_pReturn);
}
int downloadBig_onProg(unsigned int total, unsigned int now, float speed, JSFuncWrapper* pWrapper)
{
if (pWrapper && pWrapper->stop)return 1;
JCScriptRuntime::s_JSRT->m_pPoster->postToJS(std::bind(downloadBig_onProg_js, pWrapper, total, now, speed));
return 0;
}
void downloadBig_onComp_js(int curlret, int httpret, JSFuncWrapper* pWrapper)
{
if (!pWrapper->IsMyJsEnv()){
delete pWrapper;
return;
}
if (!pWrapper->funcOnComp.Empty())
{
pWrapper->funcOnComp.Call(curlret,httpret);
}
delete pWrapper;
}
void downloadBig_onComp(JCBuffer& buff, const std::string& localip,const std::string& svip, int curlret, int httpret,const std::string& httpresheader, JSFuncWrapper* pWrapper)
{
JCScriptRuntime::s_JSRT->m_pPoster->postToJS(std::bind(downloadBig_onComp_js, curlret,httpret, pWrapper));
}
long _downloadBigFile(const char* p_pszUrl, const char* p_pszLocal, JSValueAsParam p_ProgCb,JSValueAsParam p_CompleteCb, int p_nTryNum, int p_nOptTimeout)
{
/*
if (!canWrite(pCurProcess->getFSPermission(p_pszLocal))) {
JSP_THROW("downloadBigFile to this localfile is forbidden!");
LOGE("本用户不允许在%s目录下写文件", p_pszLocal);
return 0;
}
*/
JCDownloadMgr* dmgr = JCDownloadMgr::getInstance();
JSFuncWrapper* pJSObj = new JSFuncWrapper(p_ProgCb, p_CompleteCb);
dmgr->downloadBigFile(p_pszUrl, p_pszLocal,
std::bind(downloadBig_onProg, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, pJSObj),
std::bind(downloadBig_onComp, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5, std::placeholders::_6, pJSObj),
p_nTryNum, p_nOptTimeout);;
return (long)pJSObj;
}
void downloadHeader_onComp_js(char* pBuff, int curlret, int httpret, JSFuncWrapper* pWrapper)
{
if (!pWrapper->IsMyJsEnv())
{
delete pWrapper;
return;
}
if (!pWrapper->funcOnComp.Empty())
{
if (pBuff)
{
pWrapper->funcOnComp.Call(curlret, httpret, pBuff);
delete [] pBuff;
}
else
{
pWrapper->funcOnComp.Call(curlret, httpret);
}
}
delete pWrapper;
}
void downloadHeader_onComp(JCBuffer& buff, const std::string& localip,
const std::string& svip, int curlret, int httpret,
const std::string& httpresheader, JSFuncWrapper* pWrapper)
{
char* pBuff = nullptr;
if (buff.m_pPtr && buff.m_nLen)
{
//这个肯定是字符串
pBuff = new char[buff.m_nLen+1];
memcpy(pBuff, buff.m_pPtr, buff.m_nLen);
pBuff[buff.m_nLen] = 0;
}
JCScriptRuntime::s_JSRT->m_pPoster->postToJS(std::bind(downloadHeader_onComp_js, pBuff, curlret, httpret, pWrapper));
}
long _downloadGetHeader(const char* p_pszUrl, JSValueAsParam p_CompleteCb, int p_nTryNum, int p_nOptTimeout)
{
JCDownloadMgr* dmgr = JCDownloadMgr::getInstance();
JSFuncWrapper* pJSObj = new JSFuncWrapper(p_CompleteCb, p_CompleteCb);//第一个没有用
dmgr->getHeader(p_pszUrl,
std::bind(downloadHeader_onComp, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5, std::placeholders::_6, pJSObj),
p_nTryNum, p_nOptTimeout);
return (long)pJSObj;
}
void setTouchEvtFunc(JSValueAsParam pObj)
{
}
void setKeyEvtFunc(JSValueAsParam pObj)
{
}
void setJoystickEvtFunc(JSValueAsParam pObj)
{
}
void evalJS(const char* p_sSource)
{
JSP_RUN_SCRIPT(p_sSource);
}
void JSPrint(const char* p_sBuffer)
{
int nLen = strlen(p_sBuffer) + 3;
unsigned short* ucStr = new unsigned short[nLen];
int nlen = UTF8StrToUnicodeStr((unsigned char*)p_sBuffer, ucStr, nLen);
LOGI("%ws\n", (wchar_t*)ucStr);
delete[] ucStr;
ucStr = NULL;
}
void LayaAlert(const char* p_sBuffer)
{
#ifdef WIN32
int nLen = strlen(p_sBuffer) + 3;
unsigned short* ucStr = new unsigned short[nLen];
int nlen = UTF8StrToUnicodeStr((unsigned char*)p_sBuffer, ucStr, nLen);
delete[] ucStr;
ucStr = NULL;
std::wstring wsBuffer = (wchar_t*)utf8_unicode(p_sBuffer).c_str();
MessageBoxW(NULL, wsBuffer.c_str(), L"alert", MB_OK);
#elif ANDROID
std::string strBuffer = p_sBuffer;
CToJavaBridge::JavaRet kRet;
CToJavaBridge::GetInstance()->callMethod(CToJavaBridge::JavaClass.c_str(), "alert", strBuffer.c_str(), kRet);
#elif __APPLE__
CToObjectCAlert(p_sBuffer);
#endif
}
void JSAlert(const char* p_sBuffer)
{
LayaAlert(p_sBuffer);
#ifndef WIN32
LOGI("alert=%s", p_sBuffer);
#endif
}
int getInnerWidth()
{
return g_nInnerWidth;
}
int getInnerHeight()
{
return g_nInnerHeight;
}
int getDevicePixelRatio()
{
#ifdef WIN32
return 1.0;
#elif ANDROID
return 1.0;
#elif __APPLE__
return 1.0;// CToObjectCGetDevicePixelRatio();
#endif
}
JsValue getExePath()
{
#ifdef WIN32
TCHAR szPath[MAX_PATH];
::GetModuleFileName(NULL, szPath, MAX_PATH);
::GetFullPathName(szPath, MAX_PATH, szPath, NULL);
g_sExePath = szPath;
return JSP_TO_JS(const char*, g_sExePath.c_str());
#elif __APPLE__
return JSP_TO_JS_NULL;
#else
return JSP_TO_JS_NULL;
#endif
}
void PerfAddData(int nID, int nColor, float fScale, float fAlert )
{
if (g_kSystemConfig.m_nThreadMODE == THREAD_MODE_DOUBLE)
{
JCScriptRuntime::s_JSRT->flushSharedCmdBuffer();
JCCommandEncoderBuffer* pCmd = JCScriptRuntime::s_JSRT->m_pRenderCmd;
pCmd->append(LAYA_PERFADDDATA);
pCmd->append(nID);
pCmd->append(nColor);
pCmd->append(fScale);
pCmd->append(fAlert);
}
else
{
JCPerfHUD::addData(nID, nColor, fScale, fAlert);
}
}
void PerfUpdateDt(int nID, float nSpace)
{
if (g_kSystemConfig.m_nThreadMODE == THREAD_MODE_DOUBLE)
{
JCScriptRuntime::s_JSRT->flushSharedCmdBuffer();
JCCommandEncoderBuffer* pCmd = JCScriptRuntime::s_JSRT->m_pRenderCmd;
pCmd->append(LAYA_PERFUPDATEDT);
pCmd->append(nID);
pCmd->append(nSpace);
}
else
{
JCPerfHUD::updateData(nID, nSpace);
}
}
void PerfShow(float f)
{
JCPerfHUD::m_fGlobalScale = f;
JCPerfHUD::init();
JCConch::s_pConchRender->m_fShowPerfScale = f;
}
void writeStrFileSync(const char* p_pszFile, const char* p_pString )
{
JCBuffer buf((char*)p_pString, strlen(p_pString), false, false);
writeFileSync(p_pszFile, buf, JCBuffer::utf8);
}
void reloadCurJSThread()
{
#ifdef __APPLE__
CToObjectCRunStopJSLoop();
#endif
if (JCConch::s_pConch)
{
JCConch::s_pConch->postCmdToMainThread(JCConch::CMD_ReloadProcess, 0, 0);
}
}
std::string readTextAsset(const char* p_pszFile)
{
char* sBuffer = NULL;
int nSize = 0;
if (JCConch::s_pAssetsFiles->loadFileContent(p_pszFile, sBuffer, nSize))
{
std::string rsBuffer = sBuffer;
delete[] sBuffer;
return rsBuffer;
}
return "";
}
bool gbAlertException = true;
void showAlertOnJsException(bool show)
{
gbAlertException = show;
}
std::string calcMD5(unsigned char* buf, int len)
{
JCMD5 imd5;
imd5.GenerateMD5(buf, len);
return imd5.ToString();
}
std::string calcMD5_JSAB(JSValueAsParam pjs)
{
char* pABPtr = NULL;
int nABLen = 0;
if (!extractJSAB(pjs, pABPtr, nABLen))return "";
std::string ret = calcMD5((unsigned char*)pABPtr, nABLen);
return ret;
}
static std::string toBase64(const char* type, float encoderOptions, JSValueAsParam ab, int w, int h, bool flipY)
{
char* pPixels = NULL;
int nABLen = 0;
bool bIsArrayBuffer = extractJSAB(ab, pPixels, nABLen);
int size = sizeof(GLubyte) * w * h * 4;
if (!bIsArrayBuffer || w == 0 || h == 0 || size != nABLen)
{
const char* pstrHeader = "data:";
int length = strlen(pstrHeader);
std::unique_ptr<char[]> pDest(new char[length + 1]);
memcpy(pDest.get(), pstrHeader, length);
pDest.get()[length] = '\0';
return string(pDest.get());
}
if (flipY)
{
laya::flipPixelsY((uint8_t*)pPixels, w * 4, h);
}
string strType(type);
int length = (size + 2) / 3 * 4;
std::unique_ptr<char[]> pDest(new char[length]);
memset(pDest.get(), 0, length);
char *pCurrent = pDest.get();
std::pair<unsigned char*, unsigned long> result;
if (strType == "image/jpeg")
{
const char* pstrHeader = "data:image/jpeg;base64,";
int length = strlen(pstrHeader);
for (int i = 0; i < length; i++)
{
*pCurrent = pstrHeader[i];
pCurrent++;
}
result = convertBitmapToJpeg((const char*)pPixels, w, h, 32);
}
else
{
const char* pstrHeader = "data:image/png;base64,";
int length = strlen(pstrHeader);
for (int i = 0; i < length; i++)
{
*pCurrent = pstrHeader[i];
pCurrent++;
}
result = laya::convertBitmapToPng((const char*)pPixels, w, h, 8);
}
base64Encode(pCurrent, (const char*)result.first, result.second);
delete[] result.first;
return string(pDest.get());
}
std::string conchToBase64FlipY(const char* type, float encoderOptions, JSValueAsParam ab, int w, int h)
{
return toBase64(type, encoderOptions, ab, w, h, true);
}
std::string conchToBase64(const char* type, float encoderOptions, JSValueAsParam ab, int w, int h)
{
return toBase64(type, encoderOptions, ab, w, h, false);
}
void JSGlobalExportC()
{
JSP_GLOBAL_START1();
JSRuntime* pJSRuntime = new JSRuntime();
pJSRuntime->exportJS();
JSHistory* pJsHistory = new JSHistory();
pJsHistory->exportJS();
JSConsole::exportJS();
JSImage::exportJS();
XMLHttpRequest::exportJS();
JSConchConfig::getInstance()->exportJS();
JSXmlDocument::exportJS();
JSXmlNode::exportJS();
JSXmlAttr::exportJS();
JSDOMParser::exportJS();
JSAudio::exportJS();
JsAppCache::exportJS();
JSWebSocket::exportJS();
JSZip::exportJS();
JSNotify::exportJS();
if (JSLayaGL::s_pLayaGL != NULL)
{
delete JSLayaGL::s_pLayaGL;
JSLayaGL::s_pLayaGL = NULL;
}
JSLayaGL::getInstance()->exportJS();
JSShaderActiveInfo::exportJS();
JSShaderPrecisionFormat::exportJS();
#ifdef WIN32
JSWindowEditBox::exportJS();
#elif ANDROID
JSAndroidEditBox::exportJS();
#elif __APPLE__
JSIOSEditBox::exportJS();
#endif
//JSTextCanvas
JSTextBitmapInfo::exportJS();
if (JSTextMemoryCanvas::ms_pTextMemoryCanvas != NULL)
{
delete JSTextMemoryCanvas::ms_pTextMemoryCanvas;
JSTextMemoryCanvas::ms_pTextMemoryCanvas = NULL;
}
JSTextMemoryCanvas::getInstance()->exportJS();
JSCallbackFuncObj::exportJS();
#ifdef __APPLE__
JSContextRef ctx = laya::__TlsData::GetInstance()->GetCurContext();
JCWebGLPlus::getInstance()->exportJS((void*)ctx, JSContextGetGlobalObject(ctx));
#else
v8::Isolate* isolate = v8::Isolate::GetCurrent();
v8::Local<v8::Context> context = isolate->GetCurrentContext();
//v8::Local<v8::Object> object = v8::Object::New(isolate);
//context->Global()->Set(v8::String::NewFromUtf8(isolate, "qq"), object);
v8::Local<v8::Object> object = context->Global();
JCWebGLPlus::getInstance()->exportJS((void*)NULL, &object);
#endif
JSVideo::exportJS();
//以下是全局函数
//------------------------------------------------------------------------------
JSP_ADD_GLOBAL_FUNCTION(setTouchEvtFunction, setTouchEvtFunc, JSValueAsParam);
JSP_ADD_GLOBAL_FUNCTION(setKeyEvtFunction, setKeyEvtFunc, JSValueAsParam);
JSP_ADD_GLOBAL_FUNCTION(setJoystickEvtFunction, setJoystickEvtFunc, JSValueAsParam);
JSP_ADD_GLOBAL_FUNCTION(tmGetCurms, tmGetCurms);
JSP_ADD_GLOBAL_FUNCTION(reloadJS, reloadCurJSThread);
JSP_ADD_GLOBAL_FUNCTION(getExePath, getExePath);
JSP_ADD_GLOBAL_FUNCTION(getInnerHeight, getInnerHeight);
JSP_ADD_GLOBAL_FUNCTION(getInnerWidth, getInnerWidth);
JSP_ADD_GLOBAL_FUNCTION(getDevicePixelRatio, getDevicePixelRatio);
JSP_ADD_GLOBAL_PROPERTY(enableTouch, g_bEnableTouch);
JSP_ADD_GLOBAL_FUNCTION(alert, JSAlert, const char*);
JSP_ADD_GLOBAL_FUNCTION(print, JSPrint, const char*);
JSP_ADD_GLOBAL_FUNCTION(evalJS, evalJS, const char*);
JSP_ADD_GLOBAL_FUNCTION(PerfShow, PerfShow, int);
JSP_ADD_GLOBAL_FUNCTION(PerfAddData, PerfAddData, int,int,float,float);
JSP_ADD_GLOBAL_FUNCTION(PerfUpdateDt, PerfUpdateDt, int,float);
JSP_ADD_GLOBAL_FUNCTION(readFileSync, readFileSync1, const char*, const char*);
JSP_ADD_GLOBAL_FUNCTION(writeStrFileSync, writeStrFileSync, const char*, const char*);
JSP_ADD_GLOBAL_FUNCTION(readTextAsset, readTextAsset, const char*);
JSP_ADD_GLOBAL_FUNCTION(fs_exists, JSFileSystem::exists, const char*);
JSP_ADD_GLOBAL_FUNCTION(fs_mkdir, JSFileSystem::mkdir, const char*);
JSP_ADD_GLOBAL_FUNCTION(fs_rm, JSFileSystem::rm, const char*);
JSP_ADD_GLOBAL_FUNCTION(fs_rmDir, JSFileSystem::rmDir);
JSP_ADD_GLOBAL_FUNCTION(fs_rmDirSync, JSFileSystem::rmDirSync);
JSP_ADD_GLOBAL_FUNCTION(fs_readdirSync, JSFileSystem::readdirSync);
JSP_ADD_GLOBAL_FUNCTION(fs_lstatSync, JSFileSystem::lstatSync);
JSP_ADD_GLOBAL_FUNCTION(fs_writeFileSync, JSFileSystem::JSWriteFileSync);
JSP_ADD_GLOBAL_FUNCTION(decodeTemp, UrlDecode);//以后实现各和JS一样的这个就可以删了
JSP_ADD_GLOBAL_FUNCTION(showAlertOnJsException, showAlertOnJsException,bool);
JSP_ADD_GLOBAL_FUNCTION(fs_readFileSync, JSFileSystem::readBinFileSync, const char*);//这个返回的是ArrayBuffer接口
JSP_ADD_GLOBAL_FUNCTION(downloadBigFile, _downloadBigFile);
JSP_ADD_GLOBAL_FUNCTION(downloadGetHeader, _downloadGetHeader);
JSP_ADD_GLOBAL_FUNCTION(calcmd5, calcMD5_JSAB);
JSP_ADD_GLOBAL_FUNCTION(conchToBase64, conchToBase64);
JSP_ADD_GLOBAL_FUNCTION(conchToBase64FlipY, conchToBase64FlipY);
ExportJS_bullet();
JSLayaConchBullet::exportJS();
}
}
//------------------------------------------------------------------------------
//-----------------------------END FILE--------------------------------
@@ -0,0 +1,37 @@
/**
@file JSGlobalExportCFun.h
@brief
@author James
@version 1.0
@date 2013_11_12
*/
#ifndef __JSGlobalExportCFun_H__
#define __JSGlobalExportCFun_H__
//包含头文件
#include "../JSInterface/JSInterface.h"
namespace laya
{
void JSPrint( const char* p_sBuffer );
void LayaAlert(const char* p_sBuffer);
void JSAlert( const char* p_sBuffer );
void evalJS( const char* p_sSource );
void JSGlobalExportC();
bool IsStreamMode();
std::string conchToBase64(const char* type, float encoderOptions, JSValueAsParam ab, int w, int h);
std::string conchToBase64FlipY(const char* type, float encoderOptions, JSValueAsParam ab, int w, int h);
}
#endif //__JSGlobalExportCFun_H__
//-----------------------------END FILE--------------------------------
@@ -0,0 +1,65 @@
/**
@file JSHistory.cpp
@brief
@author James
@version 1.0
@date 2017_11_28
*/
#include "JSHistory.h"
#include "../../JCConch.h"
namespace laya
{
ADDJSCLSINFO(JSHistory, JSObjNode);
int JSHistory::getLength()
{
if (JCConch::s_pConch)
{
return JCConch::s_pConch->urlHistoryLength();
}
return 0;
}
void JSHistory::back()
{
if (JCConch::s_pConch)
{
return JCConch::s_pConch->urlBack();
}
}
void JSHistory::forward()
{
if (JCConch::s_pConch)
{
return JCConch::s_pConch->urlBack();
}
}
void JSHistory::go(int step)
{
if (JCConch::s_pConch)
{
return JCConch::s_pConch->urlGo(step);
}
}
void JSHistory::push(char* strUrl)
{
if (JCConch::s_pConch)
{
return JCConch::s_pConch->urlHistoryPush(strUrl);
}
}
void JSHistory::exportJS()
{
JSP_GLOBAL_CLASS("history", JSHistory);
JSP_ADD_PROPERTY_RO(length, JSHistory, getLength);
JSP_ADD_METHOD("back", JSHistory::back);
JSP_ADD_METHOD("forward", JSHistory::forward);
JSP_ADD_METHOD("go", JSHistory::go);
JSP_ADD_METHOD("_push", JSHistory::push);
JSP_INSTALL_GLOBAL_CLASS("history", JSHistory, this);
}
}
//------------------------------------------------------------------------------
//-----------------------------END FILE--------------------------------
@@ -0,0 +1,39 @@
/**
@file JSHistory.h
@brief
@author James
@version 1.0
@date 2017_11_28
*/
#ifndef __JSHistory_H__
#define __JSHistory_H__
#include <JSObjBase.h>
#include "../JSInterface/JSInterface.h"
namespace laya
{
class JSHistory :public JsObjBase, public JSObjNode
{
public:
static JsObjClassInfo JSCLSINFO;
void exportJS();
public:
int getLength();
void back();
void forward();
void go(int step);
void push(char* strUrl);
};
}
//------------------------------------------------------------------------------
#endif //__JSHistory_H__
//-----------------------------END FILE--------------------------------
@@ -0,0 +1,355 @@
/**
@file JSIOSEditBox.cpp
@brief
@author wyw
@version 1.0
@date 2014_8_22
*/
//包含头文件
#include "JSIOSEditBox.h"
#include "../JSInterface/JSInterface.h"
#include <util/Log.h>
#include <util/JCColor.h>
#include "../../CToObjectC.h"
#include "../../JCScriptRuntime.h"
namespace laya
{
ADDJSCLSINFO(JSIOSEditBox, JSObjNode);
//------------------------------------------------------------------------------
JSIOSEditBox::JSIOSEditBox()
{
//大概估算内部变量 11个int 4个字符串
AdjustAmountOfExternalAllocatedMemory( 208 );
JCMemorySurvey::GetInstance()->newClass( "iOSEditBox",208,this );
m_nLeft = 0;
m_nTop = 0;
m_nWidth = 0;
m_nHeight = 0;
m_fOpacity = 1;
m_sStyle = "";
m_sValue = "";
m_sType = "type";
m_nFontSize = 12;
m_nScaleX = 1;
m_nScaleY = 1;
m_bForbidEdit = false;
m_CallbackRef.reset(new int(1));
}
//------------------------------------------------------------------------------
JSIOSEditBox::~JSIOSEditBox()
{
JCMemorySurvey::GetInstance()->releaseClass( "iOSEditBox",this );
}
//------------------------------------------------------------------------------
int JSIOSEditBox::set_Left( int p_nLeft )
{
m_nLeft = p_nLeft;
CToObjectCSetEditBoxX( p_nLeft );
return m_nLeft;
}
//------------------------------------------------------------------------------
int JSIOSEditBox::get_Left()
{
return m_nLeft;
}
//------------------------------------------------------------------------------
int JSIOSEditBox::set_Top( int p_nTop )
{
m_nTop = p_nTop;
CToObjectCSetEditBoxY( p_nTop );
return m_nTop;
}
//------------------------------------------------------------------------------
int JSIOSEditBox::get_Top()
{
return m_nTop;
}
//------------------------------------------------------------------------------
int JSIOSEditBox::set_Width( int p_nWidth )
{
m_nWidth = p_nWidth;
CToObjectCSetEditBoxWidth( p_nWidth*m_nScaleX );
return m_nWidth;
}
//------------------------------------------------------------------------------
int JSIOSEditBox::get_Width()
{
return m_nWidth;
}
//------------------------------------------------------------------------------
int JSIOSEditBox::set_Height( int p_nHeight )
{
m_nHeight = p_nHeight;
CToObjectCSetEditBoxHeight( p_nHeight*m_nScaleY );
return m_nHeight;
}
//------------------------------------------------------------------------------
int JSIOSEditBox::get_Height()
{
return m_nHeight;
}
//------------------------------------------------------------------------------
float JSIOSEditBox::set_Opacity( float p_Opacity )
{
m_fOpacity = p_Opacity;
return m_fOpacity;
}
//------------------------------------------------------------------------------
float JSIOSEditBox::get_Opacity()
{
return m_fOpacity;
}
//------------------------------------------------------------------------------
const char* JSIOSEditBox::set_Value( const char* p_sValue )
{
m_sValue = ( p_sValue != NULL ) ? p_sValue : "";
CToObjectCSetEditBoxValue( m_sValue.c_str() );
m_nSetValueUpdateCount = JCScriptRuntime::s_JSRT->m_nUpdateCount;
return m_sValue.c_str();
}
//------------------------------------------------------------------------------
const char* JSIOSEditBox::get_Value()
{
int curUpdateCount = JCScriptRuntime::s_JSRT->m_nUpdateCount;
if(m_nSetValueUpdateCount != 0 && m_nSetValueUpdateCount == curUpdateCount)
{
m_nSetValueUpdateCount = 0;
return m_sValue.c_str();
}
m_nSetValueUpdateCount = 0;
const char* sValue = CToObjectCGetEditBoxValue();
m_sValue = sValue==NULL?"":sValue;
return m_sValue.c_str();
}
//------------------------------------------------------------------------------
void JSIOSEditBox::set_Style( const char* p_sStyle )
{
m_sStyle = p_sStyle;
CToObjectCSetEditBoxStyle( p_sStyle );
}
//------------------------------------------------------------------------------
const char* JSIOSEditBox::get_Style()
{
return m_sStyle.c_str();
}
//------------------------------------------------------------------------------
bool JSIOSEditBox::set_Visible( bool p_bVisible )
{
m_bVisible = p_bVisible;
CToObjectCSetEditBoxVisible( m_bVisible );
return m_bVisible;
}
//------------------------------------------------------------------------------
bool JSIOSEditBox::get_Visible()
{
return m_bVisible;
}
//------------------------------------------------------------------------------
void JSIOSEditBox::setLeft( int p_nLeft )
{
set_Left( p_nLeft );
}
//------------------------------------------------------------------------------
void JSIOSEditBox::setTop( int p_nTop )
{
set_Top( p_nTop );
}
//------------------------------------------------------------------------------
void JSIOSEditBox::setWidth( int p_nWidth )
{
set_Width( p_nWidth );
}
//------------------------------------------------------------------------------
void JSIOSEditBox::setHeight( int p_nHeight )
{
set_Height( p_nHeight );
}
//------------------------------------------------------------------------------
void JSIOSEditBox::setOpacity( float p_Opacity )
{
set_Opacity( p_Opacity );
}
//------------------------------------------------------------------------------
void JSIOSEditBox::setValue( const char* p_sValue )
{
set_Value( p_sValue );
}
//------------------------------------------------------------------------------
const char* JSIOSEditBox::getValue()
{
return get_Value();
}
//------------------------------------------------------------------------------
void JSIOSEditBox::setStyle( const char* p_sStyle )
{
set_Style( p_sStyle );
}
//------------------------------------------------------------------------------
void JSIOSEditBox::setVisible( bool p_bVisible )
{
set_Visible( p_bVisible );
}
//------------------------------------------------------------------------------
void JSIOSEditBox::focus()
{
JCScriptRuntime::s_JSRT->m_pCurEditBox=this;
CToObjectCSetEditBoxFocus();
}
//------------------------------------------------------------------------------
void JSIOSEditBox::blur()
{
CToObjectCSetEditBoxBlur();
JCScriptRuntime::s_JSRT->m_pCurEditBox=NULL;
}
//------------------------------------------------------------------------------
void JSIOSEditBox::setColor( const char* p_sColor )
{
int nColor = JCColor::getColorUintFromString( p_sColor );
CToObjectCSetEditBoxColor( nColor );
}
//------------------------------------------------------------------------------
void JSIOSEditBox::setFontSize( int p_nFontSize )
{
m_nFontSize = p_nFontSize;
CToObjectCSetEditBoxFontSize( m_nFontSize*m_nScaleX );
}
//------------------------------------------------------------------------------
void JSIOSEditBox::setPos( int x,int y )
{
m_nLeft = x;
m_nTop = y;
CToObjectCSetEditBoxFontPos( m_nLeft,m_nTop );
}
//------------------------------------------------------------------------------
void JSIOSEditBox::setSize( int w,int h )
{
m_nWidth = w;
m_nHeight = h;
CToObjectCSetEditBoxFontSize( m_nWidth*m_nScaleX,m_nHeight*m_nScaleY );
}
//------------------------------------------------------------------------------
void JSIOSEditBox::setCursorPosition( int pos )
{
CToObjectCSetEditBoxCursorPosition( pos );
}
//------------------------------------------------------------------------------
void JSIOSEditBox::setScale( float p_nSx,float p_nSy )
{
m_nScaleX = p_nSx;
m_nScaleY = p_nSy;
setFontSize( m_nFontSize );
setSize( m_nWidth,m_nHeight );
}
//------------------------------------------------------------------------------
void JSIOSEditBox::setMaxLength( int p_nMaxLength )
{
m_nMaxLength = p_nMaxLength;
CToObjectCSetEditBoxMaxLength( p_nMaxLength );
}
//------------------------------------------------------------------------------
void JSIOSEditBox::setType( const char* p_sType )
{
m_sType = p_sType;
bool bPassword = false;
if( m_sType == "password" )
{
bPassword = true;
}
CToObjectCSetEditBoxPassword( bPassword );
}
//------------------------------------------------------------------------------
void JSIOSEditBox::setRegular( const char* p_sRegular )
{
m_sRegular = p_sRegular;
CToObjectCSetEditBoxRegular( p_sRegular );
}
//------------------------------------------------------------------------------
void JSIOSEditBox::setFont( const char* p_sFont )
{
}
//------------------------------------------------------------------------------
void JSIOSEditBox::setNumberOnly( bool p_bNumberOnly )
{
CToObjectCSetEditBoxNumberOnly( p_bNumberOnly );
}
void JSIOSEditBox::addEventListener(const char* p_sName, JSValueAsParam p_pFunction)
{
if(strcmp(p_sName,"input")==0)
{
m_pJSFunctionOnInput.set(0,this,p_pFunction);
}
}
void JSIOSEditBox::onInput()
{
std::weak_ptr<int> cbref(m_CallbackRef);
std::function<void(void)>pFunction =std::bind(&JSIOSEditBox::onInputCallJSFunction,this,cbref);
JCScriptRuntime::s_JSRT->m_pScriptThread->post(pFunction);
}
void JSIOSEditBox::onInputCallJSFunction(std::weak_ptr<int> callbackref)
{
if(!callbackref.lock())
return;
m_pJSFunctionOnInput.Call();
}
void JSIOSEditBox::setMultiAble(bool p_bMultiAble)
{
CToObjectCSetEditBoxMultiAble(p_bMultiAble);
}
void JSIOSEditBox::setForbidEdit(bool bForbidEdit)
{
m_bForbidEdit = bForbidEdit;
CToObjectCSetEditBoxForbidEdit(bForbidEdit);
}
bool JSIOSEditBox::getForbidEdit()
{
return m_bForbidEdit;
}
void JSIOSEditBox::exportJS()
{
JSP_CLASS("ConchInput", JSIOSEditBox);
JSP_ADD_PROPERTY(left, JSIOSEditBox, get_Left, set_Left);
JSP_ADD_PROPERTY(top, JSIOSEditBox, get_Top, set_Top);
JSP_ADD_PROPERTY(width, JSIOSEditBox, get_Width, set_Width);
JSP_ADD_PROPERTY(height, JSIOSEditBox, get_Height, set_Height);
JSP_ADD_PROPERTY(opacity, JSIOSEditBox, get_Opacity, set_Opacity);
JSP_ADD_PROPERTY(style, JSIOSEditBox, get_Style, set_Style);
JSP_ADD_PROPERTY(value, JSIOSEditBox, get_Value, set_Value);
JSP_ADD_PROPERTY(visible, JSIOSEditBox, get_Visible, set_Visible);
JSP_ADD_METHOD("addEventListener", JSIOSEditBox::addEventListener);
JSP_ADD_METHOD("setLeft", JSIOSEditBox::setLeft);
JSP_ADD_METHOD("setTop", JSIOSEditBox::setTop);
JSP_ADD_METHOD("setWidth", JSIOSEditBox::setWidth);
JSP_ADD_METHOD("setHeight", JSIOSEditBox::setHeight);
JSP_ADD_METHOD("setOpacity", JSIOSEditBox::setOpacity);
JSP_ADD_METHOD("setValue", JSIOSEditBox::setValue);
JSP_ADD_METHOD("getValue", JSIOSEditBox::getValue);
JSP_ADD_METHOD("setStyle", JSIOSEditBox::setStyle);
JSP_ADD_METHOD("setVisible", JSIOSEditBox::setVisible);
JSP_ADD_METHOD("focus", JSIOSEditBox::focus);
JSP_ADD_METHOD("blur", JSIOSEditBox::blur);
JSP_ADD_METHOD("setColor", JSIOSEditBox::setColor);
JSP_ADD_METHOD("setFontSize", JSIOSEditBox::setFontSize);
JSP_ADD_METHOD("setPos", JSIOSEditBox::setPos);
JSP_ADD_METHOD("setSize", JSIOSEditBox::setSize);
JSP_ADD_METHOD("setCursorPosition", JSIOSEditBox::setCursorPosition);
JSP_ADD_METHOD("setScale", JSIOSEditBox::setScale);
JSP_ADD_METHOD("setMaxLength", JSIOSEditBox::setMaxLength);
JSP_ADD_METHOD("setType", JSIOSEditBox::setType);
JSP_ADD_METHOD("setNumberOnly", JSIOSEditBox::setNumberOnly);
JSP_ADD_METHOD("setRegular", JSIOSEditBox::setRegular);
JSP_ADD_METHOD("setFont", JSIOSEditBox::setFont);
JSP_ADD_METHOD("setMultiAble", JSIOSEditBox::setMultiAble);
JSP_ADD_METHOD("setForbidEdit", JSIOSEditBox::setForbidEdit);
JSP_ADD_METHOD("getForbidEdit", JSIOSEditBox::getForbidEdit);
JSP_INSTALL_CLASS("ConchInput", JSIOSEditBox);
}
//------------------------------------------------------------------------------
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//-----------------------------END FILE--------------------------------
@@ -0,0 +1,157 @@
/**
@file JSIOSEditBox.h
@brief
@author wyw
@version 1.0
@date 2014_8_22
*/
#ifndef __JSIOSEditBox_H__
#define __JSIOSEditBox_H__
//包含头文件
#include <stdio.h>
#include <string>
#include "../JSInterface/JSInterface.h"
/**
* @brief
*/
namespace laya
{
class JSIOSEditBox : public JsObjBase
{
public:
static JsObjClassInfo JSCLSINFO;
void JSConstructor( JsFuncArgs& args ){};
JSIOSEditBox();
~JSIOSEditBox();
static void exportJS();
public:
int set_Left( int p_nLeft );
int get_Left();
int set_Top( int p_nTop );
int get_Top();
int set_Width( int p_nWidth );
int get_Width();
int set_Height( int p_nHeight );
int get_Height();
float set_Opacity( float p_Opacity );
float get_Opacity();
const char* set_Value( const char* p_sValue );
const char* get_Value();
void set_Style( const char* p_sStyle );
const char* get_Style();
bool set_Visible( bool p_bVisible );
bool get_Visible();
public:
void setColor( const char* p_sColor );
void setFontSize( int p_nFontSize );
void setPos( int x,int y );
void setSize( int w,int h );
void setCursorPosition( int pos );
void setLeft( int p_nLeft );
void setTop( int p_nTop );
void setWidth( int p_nWidth );
void setHeight( int p_nHeight );
void setOpacity( float p_Opacity );
void setValue( const char* p_sValue );
const char* getValue();
void setStyle( const char* p_sStyle );
void setVisible( bool p_bVisible );
void setFont( const char* p_sFont );
void focus();
void blur();
void setForbidEdit(bool bForbidEdit);
bool getForbidEdit();
public:
void setScale( float p_nSx,float p_nSy );
void setMaxLength( int p_nMaxLength );
void setType( const char* p_sType );
void setRegular( const char* p_sRegular );
void setNumberOnly( bool p_bNumberOnly );
void addEventListener(const char* p_sName, JSValueAsParam p_pFunction );
void setMultiAble(bool p_bMultiAble);
void onInputCallJSFunction(std::weak_ptr<int> callbackref);
void onInput();
public:
int m_nLeft;
int m_nTop;
int m_nWidth;
int m_nHeight;
int m_nSetValueUpdateCount;
bool m_bVisible;
float m_fOpacity;
int m_nMaxLength;
int m_nFontSize;
float m_nScaleX;
float m_nScaleY;
std::string m_sType;
std::string m_sStyle;
std::string m_sValue;
std::string m_sRegular;
bool m_bForbidEdit;
private:
std::shared_ptr<int> m_CallbackRef;
JsObjHandle m_pJSFunctionOnInput;
};
}
#endif //JSError
//-----------------------------END FILE--------------------------------
@@ -0,0 +1,440 @@
/**
@file JSImage.cpp
@brief
@author James
@version 1.0
@date 2014_11_17
*/
//包含头文件
#include "JSImage.h"
#include <util/Log.h>
#ifndef WEBASM
#include <util/JCMemorySurvey.h>
#include "../JSInterface/JSInterface.h"
#include "../../JCScriptRuntime.h"
#include <downloadCache/JCFileSource.h>
#include <resource/JCFileResManager.h>
#include "JSRuntime.h"
#include <fileSystem/JCFileSystem.h>
#else
#include "../../JCScrpitRuntimeWASM.h"
#endif
#include "../../JCConch.h"
#include "../../JCSystemConfig.h"
#include <LayaGL/JCLayaGLDispatch.h>
#include <util/JCCrypto.h>
namespace laya
{
#ifndef WEBASM
ADDJSCLSINFO(JSImage, JSObjNode);
#endif
JSImage::JSImage()
{
m_pImage = new JCImage();
m_nID = JCConch::s_pConchRender->m_pImageManager->getImageID();
#ifndef WEBASM
m_pImage->setManager(JCConch::s_pConchRender->m_pFileResManager, JCConch::s_pConchRender->m_pImageManager);
m_CallbackRef.reset(new int(1));
m_bComplete = false;
m_pClsInfo = &JSImage::JSCLSINFO;
m_nDownloadState = 0;
#else
m_pImage->setManager(JCConch::s_pConchRender->m_pAtlasManager, JCConch::s_pConchRender->m_pTextureManager, NULL, JCConch::s_pConchRender->m_pImageManager);
#endif
}
JSImage::~JSImage()
{
#ifndef WEBASM
m_pOnLoad.Reset();
m_pOnError.Reset();
m_pObj.Reset();
JCMemorySurvey::GetInstance()->releaseClass( "image",this );
#endif
destroy();
}
void JSImage::destroy()
{
if (m_pImage)
{
//通知渲染线程
deleteImageOnRenderThread(m_nID);
}
}
void JSImage::releaseTexture()
{
if (m_pImage)
{
releaseImageOnRenderThread(m_nID);
}
}
#ifndef WEBASM
void JSImage::onLoaded(std::weak_ptr<int> callbackref)
{
std::function<void(void)> pFunction = std::bind(&JSImage::onLoadedCallJSFunction,this, callbackref);
JCScriptRuntime::s_JSRT->m_pPoster->postToJS(pFunction);
}
void JSImage::onError( int p_nError,std::weak_ptr<int> callbackref )
{
std::function<void(void)> pFunction = std::bind(&JSImage::onErrorCallJSFunction,this,p_nError, callbackref);
JCScriptRuntime::s_JSRT->m_pPoster->postToJS( pFunction );
}
void JSImage::onLoadedCallJSFunction(std::weak_ptr<int> callbackref)
{
if (!callbackref.lock()) return;
if (JCScriptRuntime::s_JSRT->m_bIsExit == true)return;
if (!IsMyJsEnv()) return;
if (GetWidth() <= 0 || GetHeight() <= 0|| m_pImage->m_kBitmapData.m_pImageData==NULL) {
m_pOnError.Call(500);
}
else {
int nMemSize = GetWidth() * GetHeight() * 4 + 272;
AdjustAmountOfExternalAllocatedMemory(nMemSize);
JCMemorySurvey::GetInstance()->newClass("image", 1024, this);
m_pImage->m_sUrl = m_sUrl;
//通知渲染线程
createImageOnRenderThread(m_nID, m_pImage);
m_bComplete = true;
m_pOnLoad.Call();
}
}
void JSImage::onErrorCallJSFunction( int p_nError,std::weak_ptr<int> callbackref )
{
if (!callbackref.lock())return;
if (JCScriptRuntime::s_JSRT->m_bIsExit == true)return;
if (!IsMyJsEnv())return;
LOGW("download image file error! %s\n", m_sUrl.c_str());
m_pOnError.Call(p_nError);
}
bool JSImage::getComplete()
{
return m_bComplete;
}
void JSImage::SetOnload(JSValueAsParam p_pFunction )
{
m_pOnLoad.set(onloadid,this,p_pFunction);
}
JsValue JSImage::GetOnload()
{
return m_pOnLoad.getJsObj();
}
void JSImage::SetOnError(JSValueAsParam p_pFunction )
{
m_pOnError.set(onerrorid,this,p_pFunction);
}
JsValue JSImage::GetOnError()
{
return m_pOnError.getJsObj();
}
JsValue JSImage::getObj()
{
return m_pObj.getJsObj();
}
void JSImage::setObj(JSValueAsParam obj)
{
m_pObj.set(objid,this,obj);
}
const char* JSImage::getSrc()
{
return m_sUrl.c_str();
}
bool JSImage::syncRestoreResource()
{
//if (!m_pImage || !m_pImage->m_pImageFile ) return false;
//return m_pImage->m_pImageFile->downloadImage(true);
return false;
}
void JSImage::setSrc( const char* p_sSrc )
{
if (!p_sSrc) return;
m_sUrl = p_sSrc;
std::weak_ptr<int> cbref(m_CallbackRef);
downloadImage( false );
}
void JSImage::onDecodeEnd(BitmapData& p_bmp, std::weak_ptr<int>& callbackref)
{
if (!callbackref.lock())
{
if (p_bmp.m_pImageData)
{
delete[] p_bmp.m_pImageData;
}
return;
}
if (m_pImage && m_pImage->m_kBitmapData.m_pImageData)
{
m_pImage->m_kBitmapData.releaseData();
m_pImage->m_kBitmapData.m_pImageData = NULL;
}
m_pImage->m_kBitmapData = p_bmp;
onLoaded(callbackref);
}
void JSImage::onDecodeEndDecThread(BitmapData p_bmp, std::weak_ptr<int>& callbackref)
{
JCScriptRuntime::s_JSRT->m_pPoster->postToJS(std::bind(&JSImage::onDecodeEnd, this, p_bmp, callbackref));
}
void JSImage::onDownloadOK(JCResStateDispatcher* p_pRes, bool p_bDecodeSync, std::weak_ptr<int>& callbackref)
{
m_nDownloadState = 0;
JCFileRes* pFileRes = (JCFileRes*)p_pRes;
if (pFileRes->m_pBuffer.get())
{
releaseThis();
//同步加载
if (p_bDecodeSync)
{
}
else
{
imgDecodeCB cb = std::bind(&JSImage::onDecodeEndDecThread, this, std::placeholders::_1, callbackref);
loadImageMemASync(pFileRes->m_pBuffer, pFileRes->m_nLength, cb);
}
}
else
{
onDownloadError(p_pRes, 1, callbackref);
}
}
void JSImage::onDownloadError(JCResStateDispatcher*, int e, std::weak_ptr<int>& callbackref)
{
if (!callbackref.lock())return;
releaseThis();
m_nDownloadState = 0;
onError(e,callbackref);
}
bool JSImage::downloadImage(bool p_bSyncDecode)
{
if (m_nDownloadState == 1)return false;
m_nDownloadState = 1;
//TODO 要处理本地文件的情况
std::weak_ptr<int> cbref(m_CallbackRef);
JCFileRes* pRes = JCScriptRuntime::s_JSRT->m_pFileResMgr->getRes(m_sUrl);
pRes->setOnReadyCB(std::bind(&JSImage::onDownloadOK, this, std::placeholders::_1, false, cbref));
pRes->setOnErrorCB(std::bind(&JSImage::onDownloadError, this, std::placeholders::_1, std::placeholders::_2, cbref));
retainThis();
return true;
}
int JSImage::GetWidth()
{
return m_pImage->getWidth();
}
int JSImage::GetHeight()
{
return m_pImage->getHeight();
}
void JSImage::setPremultiplyAlpha(bool bPremultiplyAlpha)
{
if (g_kSystemConfig.m_nThreadMODE == THREAD_MODE_DOUBLE)
{
JCScriptRuntime::s_JSRT->flushSharedCmdBuffer();
JCCommandEncoderBuffer* pCmd = JCScriptRuntime::s_JSRT->m_pRenderCmd;
pCmd->append(LAYA_SET_PREMULTIPLY_ALPHA);
pCmd->append(m_nID);
pCmd->append((int)bPremultiplyAlpha);
}
else
{
JCImage* pImage = JCConch::s_pConchRender->m_pImageManager->getImage(m_nID);
if (pImage)
{
pImage->setPremultiplyAlpha(bPremultiplyAlpha);
}
}
}
void JSImage::putBitmapDataJS(JSValueAsParam pArrayBuffer, int width, int height)
{
char* pArrayBufferPtr = NULL;
int nABLen = 0;
bool bIsArrayBuffer = extractJSAB(pArrayBuffer, pArrayBufferPtr, nABLen);
if (bIsArrayBuffer)
{
if (nABLen >= width * height * 4)
{
putBitmapData(pArrayBufferPtr,width, height);
}
else
{
LOGE("JSImage::pushBitmapData array buffer size < width * height * 4");
}
}
else
{
LOGE("JSImage::pushBitmapData param is not an ArrayBuffer!");
}
}
static void deleter(char* p)
{
//不删除 JS保证在onDecodeEndDecThread前pArrayBuffer不垃圾回收
}
void JSImage::putDataJS(JSValueAsParam pArrayBuffer)
{
char* pArrayBufferPtr = NULL;
int nABLen = 0;
bool bIsArrayBuffer = extractJSAB(pArrayBuffer, pArrayBufferPtr, nABLen);
if (bIsArrayBuffer)
{
if (nABLen <= 0)
return;
//设置url的名字
char sCachePath[1024];
memset(sCachePath, 0, 1024);
sprintf(sCachePath, "%s/%d.LayaBoxImg", JCConch::s_pConch->m_sCachePath.c_str(), m_nID);
m_sUrl = sCachePath;
std::weak_ptr<int> cbref(m_CallbackRef);
imgDecodeCB cb = std::bind(&JSImage::onDecodeEndDecThread, this, std::placeholders::_1, cbref);
std::shared_ptr<char> pBuffer(pArrayBufferPtr, deleter);
loadImageMemASync(pBuffer, nABLen, cb);
}
else
{
LOGE("JSImage::putData param is not an ArrayBuffer!");
}
}
void JSImage::setBase64(char* base64)
{
if (!base64)
return;
//设置url的名字
char sCachePath[1024];
memset(sCachePath, 0, 1024);
sprintf(sCachePath, "%s/%d.LayaBoxImg", JCConch::s_pConch->m_sCachePath.c_str(), m_nID);
m_sUrl = sCachePath;
std::weak_ptr<int> cbref(m_CallbackRef);
imgDecodeCB cb = std::bind(&JSImage::onDecodeEndDecThread, this, std::placeholders::_1, cbref);
int length = 0;
std::shared_ptr<char> pBuffer(base64_decode((const unsigned char*)base64, strlen(base64), &length));
loadImageMemASync(pBuffer, length, cb);
}
void JSImage::putBitmapData(char* pData, int width, int height )
{
if (m_pImage && m_pImage->m_kBitmapData.m_pImageData)
{
m_pImage->m_kBitmapData.releaseData();
m_pImage->m_kBitmapData.m_pImageData = NULL;
}
m_pImage->m_kBitmapData.m_nWidth = width;
m_pImage->m_kBitmapData.m_nHeight = height;
m_pImage->m_kBitmapData.m_pImageData = new char[width * height * 4];
memcpy(m_pImage->m_kBitmapData.m_pImageData, pData, width*height * 4);
//设置url的名字
char sCachePath[1024];
memset(sCachePath, 0, 1024);
sprintf(sCachePath,"%s/%d.LayaBoxImg", JCConch::s_pConch->m_sCachePath.c_str(),m_nID);
//写入文件
writeFileSync1(sCachePath, pData, width*height * 4);
m_sUrl = sCachePath;
m_pImage->m_bPushBitmapData = true;
onLoaded(m_CallbackRef);
}
JsValue JSImage::getImageData( int p_nX,int p_nY,int p_nW,int p_nH )
{
if( m_bComplete == false ) return JSP_TO_JS_NULL;
if( m_pImage == NULL ) return JSP_TO_JS_NULL;
BitmapData* pImg = &(m_pImage->m_kBitmapData);
if( pImg )
{
if( p_nX < 0 || p_nY < 0 || p_nX >= pImg->m_nWidth || p_nY >= pImg->m_nHeight )return JSP_TO_JS_NULL;
if( ( p_nX + p_nW ) > pImg->m_nWidth || ( p_nY + p_nH ) > pImg->m_nHeight )return JSP_TO_JS_NULL;
if (pImg->m_pImageData != NULL || (pImg->m_pImageData == NULL && m_pImage->enableImage()))
{
if( p_nX == 0 && p_nY == 0 && p_nW == pImg->m_nWidth && p_nH == pImg->m_nHeight )
{
return createJSAB( (char *)(pImg->m_pImageData),pImg->m_nWidth * pImg->m_nHeight * 4 );
}
else
{
unsigned char* pTemp = (unsigned char *)(pImg->m_pImageData);
int nSize = p_nH * p_nW * 4;
int nDstLine = p_nW*4;
int nSrcLine = pImg->m_nWidth*4;
unsigned char* pBuffer = new unsigned char[nSize];
for( int i = 0; i < p_nH; i++ )
{
memcpy(&pBuffer[nDstLine*i],&pTemp[nSrcLine*(i+p_nY)+p_nX*4],nDstLine);
}
return createJSAB( (char*)pBuffer,nSize );
}
}
}
return JSP_TO_JS_NULL;
}
#endif
void JSImage::setImageInfo(const char* sUrl, int w, int h)
{
#ifdef WEBASM
if(sUrl)m_pImage->m_sUrl = sUrl;
m_pImage->m_kBitmapData.m_nWidth = w;
m_pImage->m_kBitmapData.m_nHeight = h;
createImageOnRenderThread(m_nID, m_pImage);
#endif
}
int JSImage::getImageID()
{
return m_nID;
}
#ifndef WEBASM
void JSImage::exportJS()
{
JSP_CLASS("conchImage", JSImage);
JSP_ADD_PROPERTY_RO(conchImgId, JSImage, getImageID);
JSP_ADD_PROPERTY_RO(width, JSImage, GetWidth);
JSP_ADD_PROPERTY_RO(height, JSImage, GetHeight);
JSP_ADD_METHOD("setBase64", JSImage::setBase64);
JSP_ADD_PROPERTY(src, JSImage, getSrc, setSrc);
JSP_ADD_PROPERTY(_onload, JSImage, GetOnload, SetOnload);
JSP_ADD_PROPERTY(onload, JSImage, GetOnload, SetOnload);
JSP_ADD_PROPERTY(onerror, JSImage, GetOnError, SetOnError);
JSP_ADD_PROPERTY(obj, JSImage, getObj, setObj);
JSP_ADD_PROPERTY_RO(complete, JSImage, getComplete);
JSP_ADD_METHOD("getImageID", JSImage::getImageID);
JSP_ADD_METHOD("setSrc", JSImage::setSrc);
JSP_ADD_METHOD("getImageData", JSImage::getImageData);
JSP_ADD_METHOD("putBitmapData", JSImage::putBitmapDataJS);
JSP_ADD_METHOD("putData", JSImage::putDataJS);
JSP_ADD_METHOD("setPremultiplyAlpha", JSImage::setPremultiplyAlpha);
JSP_ADD_METHOD("syncRestoreResource", JSImage::syncRestoreResource);
JSP_ADD_METHOD("destroy", JSImage::destroy);
JSP_INSTALL_CLASS("conchImage", JSImage);
}
#endif
void JSImage::createImageOnRenderThread(int nID, JCImage* pImage)
{
if (g_kSystemConfig.m_nThreadMODE == THREAD_MODE_DOUBLE)
{
JCScriptRuntime::s_JSRT->flushSharedCmdBuffer();
JCCommandEncoderBuffer* pCmd = JCScriptRuntime::s_JSRT->m_pRenderCmd;
pCmd->append(LAYA_CREATE_IMAGE_ON_RENDER_THREAD);
pCmd->append(nID);
pCmd->append((long)(pImage));
}
else
{
JCConch::s_pConchRender->m_pImageManager->setImage(nID, pImage);
}
}
void JSImage::deleteImageOnRenderThread(int nID)
{
JCCommandEncoderBuffer* pCmd = JCScriptRuntime::s_JSRT->m_pGCCmd;
pCmd->append(LAYA_DELETE_IMAGE_ON_RENDER_THREAD);
pCmd->append(nID);
}
void JSImage::releaseImageOnRenderThread(int nID)
{
JCCommandEncoderBuffer* pCmd = JCScriptRuntime::s_JSRT->m_pGCCmd;
pCmd->append(LAYA_RELEASE_IMAGE_ON_RENDER_THREAD);
pCmd->append(nID);
}
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//-----------------------------END FILE--------------------------------
@@ -0,0 +1,142 @@
/**
@file JSImage.h
@brief
@author James
@version 1.0
@date 2014_11_17
*/
#ifndef __JSImage_H__
#define __JSImage_H__
//包含头文件
#include <stdio.h>
#ifndef WEBASM
#include <JSObjBase.h>
#include "../JSInterface/JSInterface.h"
#endif
#include <Image/JCImage.h>
#include <resource/JCResource.h>
/**
* @brief
*/
namespace laya
{
class IConchThreadCmdMgr;
#ifndef WEBASM
class JSImage :public JsObjBase, public JSObjNode
#else
class JSImage
#endif
{
public:
JSImage();
~JSImage();
#ifndef WEBASM
public:
enum { onloadid, onerrorid, thisid, objid };
static JsObjClassInfo JSCLSINFO;
static void exportJS();
void onLoaded(std::weak_ptr<int> callbackref);
void onError( int p_nError,std::weak_ptr<int> callbackref );
void onLoadedCallJSFunction(std::weak_ptr<int> callbackref);
void onErrorCallJSFunction( int p_nError,std::weak_ptr<int> callbackref);
void setObj(JSValueAsParam p_pFunction);
JsValue getObj();
void SetOnload(JSValueAsParam p_pFunction );
JsValue GetOnload();
void SetOnError(JSValueAsParam p_pFunction );
JsValue GetOnError();
int GetWidth();
int GetHeight();
const char* getSrc();
void setSrc( const char* p_sSrc );
bool getComplete();
JsValue getImageData( int p_nX,int p_nY,int p_nW,int p_nH );
bool syncRestoreResource();
void putBitmapData( char* pData,int width, int height);
void putBitmapDataJS( JSValueAsParam pArrayBuffer, int width, int height );
void putDataJS(JSValueAsParam pArrayBuffer);
void setPremultiplyAlpha(bool bPremultiplyAlpha);
void setBase64(char* base64);
private:
void onDecodeEnd(BitmapData& p_bmp, std::weak_ptr<int>& callbackref);
void onDecodeEndDecThread(BitmapData p_bmp, std::weak_ptr<int>& callbackref);
void onDownloadOK(JCResStateDispatcher* p_pRes, bool p_bDecodeSync, std::weak_ptr<int>& callbackref);
void onDownloadError(JCResStateDispatcher* p_pRes, int e, std::weak_ptr<int>& callbackref);
bool downloadImage(bool p_bSyncDecode);
#endif
public:
int getImageID();
void destroy();
void releaseTexture();
void setImageInfo(const char* sUrl,int w, int h);
void createImageOnRenderThread(int nID,JCImage* pImage);
void deleteImageOnRenderThread(int nID);
void releaseImageOnRenderThread(int nID);
#ifndef WEBASM
public:
JsObjHandle m_pOnLoad;
JsObjHandle m_pOnError;
JsObjHandle m_pObj;
bool m_bComplete;
std::shared_ptr<int> m_CallbackRef;
std::string m_sUrl;
int m_nDownloadState;
#endif
public:
JCImage* m_pImage;
int m_nID;
};
}
#endif //__JSImage_H__
//-----------------------------END FILE--------------------------------
@@ -0,0 +1,187 @@
/**
@file JSInput.cpp
@brief
@author James
@version 1.0
@date 2016_5_18
*/
#include "JSInput.h"
#include <util/Log.h>
#include "../../JSWrapper/LayaWrap/JSInput.h"
#include <util/JCIThreadCmdMgr.h>
#include "../../JCConch.h"
namespace laya
{
ADDJSCLSINFO(JSInput, JSObjNode);
JSInput* JSInput::m_pInstance = NULL;
JSInput* JSInput::getInstance()
{
if (m_pInstance == NULL)
{
m_pInstance = new JSInput();
}
return m_pInstance;
}
void JSInput::Reset()
{
}
JSInput::JSInput()
{
m_pCmdPoster = JCScriptRuntime::s_JSRT->m_pPoster;
m_bTouchMode = false;
m_vInputEvents.reserve( 64 );
m_vInputEventsJS.reserve( 64 );
m_nTouchFrame = 0;
}
JSInput::~JSInput()
{
}
void JSInput::onDeviceOrientationCallJSFunction(DeviceOrientationEvent e)
{
JCScriptRuntime::s_JSRT->m_pJSDeviceMotionEvtFunction.Call(e.type,e.ra,e.rb,e.rg);
}
void JSInput::onDeviceMotionCallJSFunction(DeviceMotionEvent e)
{
float* t = (float *)JCScriptRuntime::s_JSRT->m_pOtherBufferSharedWidthJS;
t[0] = e.ax;
t[1] = e.ay;
t[2] = e.az;
t[3] = e.agx;
t[4] = e.agy;
t[5] = e.agz;
t[6] = e.ra;
t[7] = e.rb;
t[8] = e.rg;
t[9] = e.interval;
JCScriptRuntime::s_JSRT->m_pJSDeviceMotionEvtFunction.Call(e.type);
}
void JSInput::setTouchMode(bool bMode)
{
m_bTouchMode = bMode;
}
bool JSInput::getTouchMode()
{
return m_bTouchMode;
}
void JSInput::swapCurrentTouchEvent()
{
m_Lock.lock();
std::swap(m_vInputEvents, m_vInputEventsJS);
m_vInputEvents.clear();
m_Lock.unlock();
}
void JSInput::onInputCallJSFunction(inputEvent e)
{
//touch
if (e.nType <= E_ONACTION_POINTER_UP)
{
JCScriptRuntime::s_JSRT->m_pJSTouchEvtFunction.Call(e.nTouchType, e.id, e.type, e.posX, e.posY);
}
//鼠标
else if (e.nType >= E_ONMOUSEDOWN && e.nType <= E_ONRIGHTMOUSEUP)
{
JCScriptRuntime::s_JSRT->m_pJSMouseEvtFunction.Call(e.nTouchType, e.type, e.posX, e.posY, e.nWheel);
}
//键盘
else if (e.nType >= E_ONKEYDOWN && e.nType <= E_ONKEYUP)
{
int bAlt = e.bAlt ? 1 : 0;
int bShift = e.bShift ? 2 : 0;
int bCtrl = e.bCtrl ? 4 : 0;
JCScriptRuntime::s_JSRT->m_pJSKeyEvtFunction.Call(e.type, e.keyCode, e.keyChar, bAlt&bShift&bCtrl);
}
else if (e.nType == E_JOYSTICK)
{
//JCScriptRuntime::s_JSRT->m_JoystickEvtHandler.Call(e.type, e.fTHUMBL_xOffset, e.fTHUMBL_yOffset, e.fTHUMBR_xOffset, e.fTHUMBR_yOffset, e.fLT_Offset, e.fRT_Offset);
}
}
bool JSInput::activeCall(inputEvent e)
{
if (e.nType > E_TYPE_COUNT)
{
return false;
}
if (e.nType <= E_ONACTION_POINTER_UP && m_bTouchMode == true)
{
TouchEventInfo info = { e.nTouchType,e.id,e.posX,e.posY};
m_Lock.lock();
m_vInputEvents.push_back(info);
m_Lock.unlock();
}
else
{
#ifdef WIN32
if (e.nType == E_ONMOUSEDOWN || e.nType == E_ONMOUSEMOVE)
{
#else
if (e.nType == E_ONTOUCHSTART || e.nType == E_ONTOUCHMOVE)
{
#endif
double fTime = tmGetCurms();
#ifdef __APPLE__
if (JCConch::s_pConchRender)
JCConch::s_pConchRender->onTouchStart(fTime);
#elif ANDROID
//如何转到渲染线程?有线程问题但应该影响不大
if (JCConch::s_pConchRender)
JCConch::s_pConchRender->onTouchStart(fTime);
#elif WIN32
if (JCConch::s_pConchRender)
{
std::function<void(void)> pFunction = std::bind(&JCConchRender::onTouchStart, JCConch::s_pConchRender, fTime);
JCConch::s_pConchRender->m_pRenderThread->post(pFunction);
}
#endif
}
std::function<void(void)> pFunction = std::bind(&JSInput::onInputCallJSFunction, this, e);
if (JCScriptRuntime::s_JSRT->m_pPoster)
{
JCScriptRuntime::s_JSRT->m_pPoster->postToJS(pFunction);
}
}
return true;
}
bool JSInput::activeCall(DeviceMotionEvent e)
{
if (e.nType > E_TYPE_COUNT)
{
return false;
}
std::function<void(void)> pFunction = std::bind(&JSInput::onDeviceMotionCallJSFunction, this, e);
if (JCScriptRuntime::s_JSRT->m_pPoster)
JCScriptRuntime::s_JSRT->m_pPoster->postToJS(pFunction);
return true;
}
bool JSInput::activeCall(DeviceOrientationEvent e)
{
std::function<void(void)> pFunction = std::bind(&JSInput::onDeviceOrientationCallJSFunction, this, e);
if (JCScriptRuntime::s_JSRT->m_pPoster)
JCScriptRuntime::s_JSRT->m_pPoster->postToJS(pFunction);
return true;
}
void JSInput::captureScreenCallBack(char *p_pBuffer, int p_nLen, int p_nW, int p_nH)
{
std::function<void(void)> pFunction = std::bind(&JSInput::onCaptureScreenCallJSFunction, this, p_pBuffer,p_nLen,p_nW,p_nH);
if (JCScriptRuntime::s_JSRT->m_pPoster)
JCScriptRuntime::s_JSRT->m_pPoster->postToJS(pFunction);
}
void JSInput::onCaptureScreenCallJSFunction(char *p_pBuffer, int p_nlen, int p_nW, int p_nH)
{
#ifdef JS_V8
v8::HandleScope scope(v8::Isolate::GetCurrent());
#endif
JsValue ab = createJSAB(p_pBuffer, p_nlen);
delete[] p_pBuffer;
JCScriptRuntime::s_JSRT->m_pJSOnceOtherEvtFuction.Call(ab, p_nW,p_nH);
}
void JSInput::exportJS()
{
}
}
//------------------------------------------------------------------------------
//-----------------------------END FILE--------------------------------
@@ -0,0 +1,64 @@
/**
@file JSInput.h
@brief
@author James
@version 1.0
@date 2017_11_28
*/
#ifndef __JSInput_H__
#define __JSInput_H__
#include <stdio.h>
#include "../JSInterface/JSInterface.h"
#include "../../JCScriptRuntime.h"
#include <mutex>
namespace laya
{
struct TouchEventInfo
{
int nType;
int nID;
int x;
int y;
};
class IConchThreadCmdMgr;
class JSInput:public JsObjBase
{
public:
static JsObjClassInfo JSCLSINFO;
static void exportJS();
static JSInput* getInstance();
static void Reset();
public:
JSInput();
~JSInput();
void onInputCallJSFunction(inputEvent e);
void onDeviceOrientationCallJSFunction(DeviceOrientationEvent e);
void onDeviceMotionCallJSFunction(DeviceMotionEvent e);
bool activeCall( inputEvent param );
bool activeCall(DeviceOrientationEvent param);
bool activeCall(DeviceMotionEvent param);
void captureScreenCallBack(char *p_pBuffer,int p_nLen, int p_nW, int p_nH);
void onCaptureScreenCallJSFunction(char *p_pBuffer, int p_nLen, int p_nW, int p_nH);
void swapCurrentTouchEvent();
void setTouchMode( bool bMode );
bool getTouchMode();
public:
static JSInput* m_pInstance;
IConchThreadCmdMgr* m_pCmdPoster;
bool m_bTouchMode; ///<trueΪ²éѯģʽ falseΪ»Øµ÷ģʽ
std::vector<TouchEventInfo> m_vInputEvents;
std::vector<TouchEventInfo> m_vInputEventsJS;
std::recursive_mutex m_Lock;
int m_nTouchFrame;
};
}
//------------------------------------------------------------------------------
#endif //__JSInput_H__
//-----------------------------END FILE--------------------------------
@@ -0,0 +1,921 @@
/**
@file JSLayaGL.cpp
@brief
@author James
@version 1.0
@date 2018_5_25
*/
#include "JSLayaGL.h"
#include "../../JCScriptRuntime.h"
#include "../../JCConchRender.h"
#include "../../JCConch.h"
#include <math/Matrix32.h>
#include "JSShaderActiveInfo.h"
#include "JSShaderPrecisionFormat.h"
#include "../../JCSystemConfig.h"
#include <LayaGL/JCLayaGLDispatch.h>
#include <set>
#include "JCWebGLPlus.h"
#ifdef __APPLE__
#include "jsc/JSArrayBufferRef.h"
#include "jsc/JSKeyframeNodeList.h"
#else
#include "v8/JSArrayBufferRef.h"
#include "v8/JSKeyframeNodeList.h"
#endif
extern int g_nInnerWidth;
extern int g_nInnerHeight;
//------------------------------------------------------------------------------
namespace laya
{
JSLayaGL* JSLayaGL::s_pLayaGL = NULL;
ADDJSCLSINFO(JSLayaGL, JSObjNode);
JSLayaGL::JSLayaGL()
{
AdjustAmountOfExternalAllocatedMemory(8192);
JCMemorySurvey::GetInstance()->newClass("layagl", 8192, this);
m_nSyncToRenderABListID = -1;
m_nFrameAndSyncCountABListID = -1;
m_nRootCommandEncoderID = -1;
m_pValueTemplate = new JCGlobalValue();
m_nProgramParameter = 0;
m_nAttribLocation = 0;
m_pShaderActiveInfo = new WebGLActiveInfo();
m_pShaderPrecisionFormat = new ShaderPrecisionFormat();
m_pShaderTemplate = NULL;
m_pGpuProgram = NULL;
m_nSyncArrayBufferCount = 0;
m_nFrameCount = 0;
m_nParameterResult = 0;
m_pRootCommandEncoder = NULL;
}
JSLayaGL::~JSLayaGL()
{
if (m_pValueTemplate)
{
delete m_pValueTemplate;
m_pValueTemplate = NULL;
}
if (m_pShaderActiveInfo)
{
delete m_pShaderActiveInfo;
m_pShaderActiveInfo = NULL;
}
if (m_pShaderTemplate)
{
delete m_pShaderTemplate;
m_pShaderTemplate = NULL;
m_pGpuProgram = NULL;
}
if (m_pShaderPrecisionFormat)
{
delete m_pShaderPrecisionFormat;
m_pShaderPrecisionFormat = NULL;
}
JCMemorySurvey::GetInstance()->releaseClass("layagl", this);
s_pLayaGL = NULL;
}
JSLayaGL* JSLayaGL::getInstance()
{
if (s_pLayaGL == NULL)
{
s_pLayaGL = new JSLayaGL();
}
return s_pLayaGL;
}
void JSLayaGL::setSyncArrayBufferID(int nSyncArrayBufferID)
{
m_nSyncToRenderABListID = nSyncArrayBufferID;
}
void JSLayaGL::setFrameAndSyncCountArrayBufferID(int nBufferID)
{
m_nFrameAndSyncCountABListID = nBufferID;
}
void JSLayaGL::setRootCommandEncoder(int nCommandEncoderID)
{
m_nRootCommandEncoderID = nCommandEncoderID;
m_pRootCommandEncoder = JCScriptRuntime::s_JSRT->m_pArrayBufferManager->getArrayBuffer(m_nRootCommandEncoderID);
}
int JSLayaGL::getThreadMode()
{
return (int)g_kSystemConfig.m_nThreadMODE;
}
int JSLayaGL::getProgramParameterEx(const char* vs, const char* ps, const char* define, int type)
{
std::string str_vs = vs;
std::string str_ps = ps;
std::string str_define = define;
JCConch::s_pConchRender->setInterruptFunc(std::bind(&JSLayaGL::_getProgramParameterEx, this, str_vs, str_ps, str_define, type));
return m_nProgramParameter;
}
JsValue JSLayaGL::getActiveAttribEx(const char* vs, const char* ps, const char* define, int nIndex)
{
std::string str_vs = vs;
std::string str_ps = ps;
std::string str_define = define;
JCConch::s_pConchRender->setInterruptFunc(std::bind(&JSLayaGL::_getActiveAttribEx, this, str_vs, str_ps, str_define, nIndex));
JSShaderActiveInfo * pActiveInfo = new JSShaderActiveInfo();
pActiveInfo->m_sName = m_pShaderActiveInfo->name;
pActiveInfo->m_nType = m_pShaderActiveInfo->type;
pActiveInfo->m_nSize = m_pShaderActiveInfo->size;
return JSP_TO_JS(JSShaderActiveInfo, pActiveInfo);
}
JsValue JSLayaGL::getActiveUniformEx(const char* vs, const char* ps, const char* define, int nIndex)
{
std::string str_vs = vs;
std::string str_ps = ps;
std::string str_define = define;
JCConch::s_pConchRender->setInterruptFunc(std::bind(&JSLayaGL::_getActiveUniformEx, this, str_vs, str_ps, str_define, nIndex));
JSShaderActiveInfo * pActiveInfo = new JSShaderActiveInfo();
pActiveInfo->m_sName = m_pShaderActiveInfo->name;
pActiveInfo->m_nType = m_pShaderActiveInfo->type;
pActiveInfo->m_nSize = m_pShaderActiveInfo->size;
return JSP_TO_JS(JSShaderActiveInfo, pActiveInfo);
}
JsValue JSLayaGL::getShaderPrecisionFormat(int shaderType, int precisionType)
{
JCConch::s_pConchRender->setInterruptFunc(std::bind(&JSLayaGL::_getShaderPrecisionFormat, this, shaderType, precisionType));
JSShaderPrecisionFormat* pShaderPrecision = new JSShaderPrecisionFormat();
pShaderPrecision->m_nPrecision = m_pShaderPrecisionFormat->precision[0];
pShaderPrecision->m_nRangeMin = m_pShaderPrecisionFormat->range[0];
pShaderPrecision->m_nRangeMax = m_pShaderPrecisionFormat->range[1];
return JSP_TO_JS(JSShaderPrecisionFormat, pShaderPrecision);
}
JsValue JSLayaGL::getUniformEx(const char* locationName)
{
std::string strLocName = locationName;
JCConch::s_pConchRender->setInterruptFunc(std::bind(&JSLayaGL::_getUniformEx, this, strLocName));
return __JsArray<float>::ToJsArray(m_nParameterResultArray);
}
int JSLayaGL::getParameter(int pname)
{
JCConch::s_pConchRender->setInterruptFunc(std::bind(&JSLayaGL::_getParameter, this, pname));
return m_nParameterResult;
}
bool JSLayaGL::getBooleanv(int pname)
{
JCConch::s_pConchRender->setInterruptFunc(std::bind(&JSLayaGL::_getBooleanv, this, pname));
return m_nParameterResultBool;
}
int JSLayaGL::getIntegerv(int pname)
{
JCConch::s_pConchRender->setInterruptFunc(std::bind(&JSLayaGL::_getIntegerv, this, pname));
return m_nParameterResult;
}
JsValue JSLayaGL::getIntegerArrayv(int pname)
{
JCConch::s_pConchRender->setInterruptFunc(std::bind(&JSLayaGL::_getIntegerArrayv, this, pname));
return __JsArray<float>::ToJsArray(m_nParameterResultArray);
}
float JSLayaGL::getFloatv(int pname)
{
JCConch::s_pConchRender->setInterruptFunc(std::bind(&JSLayaGL::_getFloatv, this, pname));
return m_nParameterResultFloat;
}
JsValue JSLayaGL::getFloatArrayv(int pname)
{
JCConch::s_pConchRender->setInterruptFunc(std::bind(&JSLayaGL::_getFloatArrayv, this, pname));
return __JsArray<float>::ToJsArray(m_nParameterResultArray);
}
JsValue JSLayaGL::readPixels(int x, int y, int width, int height, int format, int type)
{
JCConch::s_pConchRender->setInterruptFunc(std::bind(&JSLayaGL::_readPixels, this, x, y, width, height, format, type));
return createJSAB((char*)m_nParameterResultByteArray.data(), m_nParameterResultByteArray.size());
}
int JSLayaGL::getAttribLocationEx(const char* vs, const char* ps, const char* define, const char* sName)
{
std::string str_vs = vs;
std::string str_ps = ps;
std::string str_define = define;
std::string str_name = sName;
JCConch::s_pConchRender->setInterruptFunc(std::bind(&JSLayaGL::_getAttribLocationEx, this, str_vs, str_ps,str_define,str_name));
return m_nAttribLocation;
}
const char* JSLayaGL::getStringEx(unsigned int name)
{
m_sGLString = "";
JCConch::s_pConchRender->setInterruptFunc(std::bind(&JSLayaGL::_getStringEx, this, name));
return m_sGLString.c_str();
}
void JSLayaGL::_getStringEx(unsigned int name)
{
m_sGLString = (char*)glGetString(name);
}
void JSLayaGL::_getProgramParameterEx(const std::string& vs, const std::string& ps, const std::string& define, int type)
{
_createShader(vs, ps, define);
::glGetProgramiv(m_pGpuProgram->getGpuProgram(), type, &m_nProgramParameter);
}
void JSLayaGL::_getActiveAttribEx(const std::string& vs, const std::string& ps, const std::string& define, int nIndex)
{
_createShader(vs, ps, define);
::glGetActiveAttrib(m_pGpuProgram->getGpuProgram(), nIndex, m_pShaderActiveInfo->bufsize, &m_pShaderActiveInfo->length, &m_pShaderActiveInfo->size, &m_pShaderActiveInfo->type, m_pShaderActiveInfo->name);
}
void JSLayaGL::_getActiveUniformEx(const std::string& vs, const std::string& ps, const std::string& define, int nIndex)
{
_createShader(vs, ps, define);
::glGetActiveUniform(m_pGpuProgram->getGpuProgram(), nIndex, m_pShaderActiveInfo->bufsize, &m_pShaderActiveInfo->length, &m_pShaderActiveInfo->size, &m_pShaderActiveInfo->type, m_pShaderActiveInfo->name);
}
void JSLayaGL::_getAttribLocationEx(const std::string& vs, const std::string& ps, const std::string& define, const std::string& name)
{
_createShader(vs, ps, define);
m_nAttribLocation = ::glGetAttribLocation(m_pGpuProgram->getGpuProgram(), name.c_str());
}
void JSLayaGL::_getShaderPrecisionFormat(int shaderType, int precisionType)
{
::glGetShaderPrecisionFormat(shaderType, precisionType, m_pShaderPrecisionFormat->range, m_pShaderPrecisionFormat->precision);
}
struct TypeDesc {
GLenum category;
int size;
};
void JSLayaGL::_getUniformEx(const std::string& locationName)
{
static int iRet[16];
static float fRet[16];
static std::map<GLenum, TypeDesc> typeMap =
{
// float
{ GL_FLOAT, { GL_FLOAT, 1 } },
{ GL_FLOAT_VEC2, { GL_FLOAT, 2 } },
{ GL_FLOAT_VEC3, { GL_FLOAT, 3 } },
{ GL_FLOAT_VEC4, { GL_FLOAT, 4 } },
{ GL_FLOAT_MAT2, { GL_FLOAT, 4 } },
{ GL_FLOAT_MAT3, { GL_FLOAT, 9 } },
{ GL_FLOAT_MAT4, { GL_FLOAT, 16 } },
// int
{ GL_INT, { GL_INT, 1 } },
{ GL_INT_VEC2,{ GL_INT, 2 } },
{ GL_INT_VEC3,{ GL_INT, 3 } },
{ GL_INT_VEC4,{ GL_INT, 4 } },
// sampler
{ GL_SAMPLER_2D, {GL_INT, 1 } },
{ GL_SAMPLER_CUBE, {GL_INT, 1}},
// bool
{ GL_BOOL, { GL_BOOL, 1 } },
{ GL_BOOL_VEC2, { GL_BOOL, 2 } },
{ GL_BOOL_VEC3, { GL_BOOL, 3 } },
{ GL_BOOL_VEC4, { GL_BOOL, 4 } },
};
if (g_kSystemConfig.m_nThreadMODE == THREAD_MODE_SINGLE)
{
m_nParameterResultArray.clear();
GLint gpuProgram = 0;
::glGetIntegerv(GL_CURRENT_PROGRAM, &gpuProgram);
if (!gpuProgram)
{
return;
}
else
{
GLint location = ::glGetUniformLocation(gpuProgram, locationName.c_str());
GLenum type = 0;
GLsizei size = 0;
::glGetActiveUniform(gpuProgram, location, 0, nullptr, &size, &type, nullptr);
auto it = typeMap.find(type);
if (it == typeMap.end())
{
return;
}
const TypeDesc& typeDesc = it->second;
m_nParameterResultArray.push_back((float)(typeDesc.category));
if (typeDesc.category == GL_FLOAT)
{
::glGetUniformfv(gpuProgram, location, fRet);
for (int i = 0; i < typeDesc.size; i++)
{
m_nParameterResultArray.push_back(fRet[i]);
}
}
else
{
::glGetUniformiv(gpuProgram, location, iRet);
for (int i = 0; i < typeDesc.size; i++)
{
m_nParameterResultArray.push_back((float)iRet[i]);
}
}
}
}
else
{
LOGI("getUniformEx is not supported");
}
}
void JSLayaGL::_getParameter(int pname)
{
::glGetIntegerv(pname, &m_nParameterResult);
}
void JSLayaGL::_getBooleanv(int pname)
{
if (g_kSystemConfig.m_nThreadMODE == THREAD_MODE_SINGLE)
{
if (pname == GL_BLEND || pname == GL_CULL_FACE ||
pname == GL_DEPTH_TEST || pname == GL_DEPTH_WRITEMASK ||
pname == GL_DITHER || pname == GL_SAMPLE_COVERAGE_INVERT ||
pname == GL_SCISSOR_TEST || pname == GL_STENCIL_TEST)
{
JCScriptRuntime::s_JSRT->dispatchLayaGLBuffer(false);
}
::glGetBooleanv(pname, &m_nParameterResultBool);
}
else
{
LOGI("getBooleanv not supported");
m_nParameterResultBool = GL_FALSE;
}
}
void JSLayaGL::_getIntegerv(int pname)
{
if (g_kSystemConfig.m_nThreadMODE == THREAD_MODE_SINGLE)
{
if(pname == GL_ACTIVE_TEXTURE || pname == GL_BLEND_DST_ALPHA ||
pname == GL_BLEND_DST_RGB || pname == GL_BLEND_EQUATION ||
pname == GL_BLEND_EQUATION_ALPHA || pname == GL_BLEND_EQUATION_RGB ||
pname == GL_BLEND_SRC_ALPHA || pname == GL_BLEND_SRC_RGB ||
pname == GL_CULL_FACE_MODE || pname == GL_DEPTH_FUNC ||
pname == GL_FRONT_FACE || pname == GL_GENERATE_MIPMAP_HINT ||
pname == GL_STENCIL_BACK_FAIL || pname == GL_STENCIL_BACK_FUNC ||
pname == GL_STENCIL_BACK_PASS_DEPTH_FAIL || pname == GL_STENCIL_BACK_PASS_DEPTH_PASS || pname == GL_STENCIL_BACK_REF ||
pname == GL_STENCIL_BACK_VALUE_MASK || pname == GL_STENCIL_BACK_WRITEMASK || pname == GL_STENCIL_CLEAR_VALUE || pname == GL_STENCIL_FAIL || pname == GL_STENCIL_FUNC || pname == GL_STENCIL_PASS_DEPTH_FAIL || pname == GL_STENCIL_PASS_DEPTH_PASS || pname == GL_STENCIL_REF || pname == GL_STENCIL_VALUE_MASK || pname == GL_STENCIL_WRITEMASK || pname == GL_UNPACK_ALIGNMENT ||
pname == GL_CURRENT_PROGRAM || pname == GL_ELEMENT_ARRAY_BUFFER_BINDING ||
pname == GL_RENDERBUFFER_BINDING || pname == GL_TEXTURE_BINDING_2D ||
pname == GL_TEXTURE_CUBE_MAP || pname == GL_ARRAY_BUFFER_BINDING)
{
JCScriptRuntime::s_JSRT->dispatchLayaGLBuffer(false);
}
::glGetIntegerv(pname, &m_nParameterResult);
}
else
{
static set<unsigned int> supportedNameSet = {
GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, GL_MAX_CUBE_MAP_TEXTURE_SIZE,
GL_MAX_FRAGMENT_UNIFORM_VECTORS, GL_MAX_RENDERBUFFER_SIZE, GL_MAX_TEXTURE_IMAGE_UNITS,
GL_MAX_TEXTURE_SIZE, GL_MAX_VARYING_VECTORS, GL_MAX_VERTEX_ATTRIBS, GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS,
GL_MAX_VERTEX_UNIFORM_VECTORS, GL_NUM_COMPRESSED_TEXTURE_FORMATS, GL_NUM_SHADER_BINARY_FORMATS
};
if (supportedNameSet.find(pname) != supportedNameSet.end())
{
::glGetIntegerv(pname, &m_nParameterResult);
}
else
{
LOGI("getIntegerv not supported this type=%d", pname);
m_nParameterResult = 0;
}
}
}
void JSLayaGL::_getIntegerArrayv(int pname)
{
int size = 0;
int* pRet = nullptr;
if (pname == GL_MAX_VIEWPORT_DIMS)
{
size = 2;
int ret[2] = { 0 };
pRet = ret;
}
else if (pname == GL_SCISSOR_BOX || pname == GL_VIEWPORT)
{
size = 4;
int ret[4] = { 0 };
pRet = ret;
}
if (g_kSystemConfig.m_nThreadMODE == THREAD_MODE_SINGLE)
{
if (pname == GL_SCISSOR_BOX || pname == GL_VIEWPORT)
{
JCScriptRuntime::s_JSRT->dispatchLayaGLBuffer(false);
}
::glGetIntegerv(pname, pRet);
}
else
{
if (pname == GL_MAX_VIEWPORT_DIMS)
{
::glGetIntegerv(pname, pRet);
}
else
{
LOGI("getIntegerv not supported");
}
}
m_nParameterResultArray.clear();
for (int i = 0; i < size; i++)
{
m_nParameterResultArray.push_back(pRet[i]);
}
}
void JSLayaGL::_getFloatv(int pname)
{
if (g_kSystemConfig.m_nThreadMODE == THREAD_MODE_SINGLE)
{
if (pname == GL_DEPTH_CLEAR_VALUE || pname == GL_SAMPLE_COVERAGE_VALUE)
{
JCScriptRuntime::s_JSRT->dispatchLayaGLBuffer(false);
}
::glGetFloatv(pname, &m_nParameterResultFloat);
}
else
{
LOGI("getIntegerv not supported");
m_nParameterResultFloat = 0;
}
}
void JSLayaGL::_getFloatArrayv(int pname)
{
int size = 0;
float* pRet = nullptr;
if (pname == GL_ALIASED_LINE_WIDTH_RANGE || pname == GL_ALIASED_POINT_SIZE_RANGE ||
pname == GL_DEPTH_RANGE)
{
size = 2;
float ret[2] = { 0.0 };
pRet = ret;
}
else if (pname == GL_BLEND_COLOR || pname == GL_COLOR_CLEAR_VALUE)
{
size = 4;
float ret[4] = { 0.0 };
pRet = ret;
}
if (g_kSystemConfig.m_nThreadMODE == THREAD_MODE_SINGLE)
{
if (pname == GL_BLEND_COLOR || pname == GL_COLOR_CLEAR_VALUE ||
pname == GL_DEPTH_RANGE)
{
JCScriptRuntime::s_JSRT->dispatchLayaGLBuffer(false);
}
::glGetFloatv(pname, pRet);
}
else
{
if (pname == GL_ALIASED_LINE_WIDTH_RANGE || pname == GL_ALIASED_POINT_SIZE_RANGE ||
pname == GL_DEPTH_RANGE)
{
::glGetFloatv(pname, pRet);
}
else
{
LOGI("glGetFloatv not supported");
}
}
m_nParameterResultArray.clear();
for (int i = 0; i < size; i++)
{
m_nParameterResultArray.push_back(pRet[i]);
}
}
void JSLayaGL::_createShader(const std::string& vs, const std::string& ps, const std::string& define)
{
if (m_sShaderVS != vs || m_sShaderPS != ps || m_sShaderDefine != define)
{
if (m_pShaderTemplate)
{
delete m_pShaderTemplate;
m_pShaderTemplate = NULL;
m_pGpuProgram = NULL;
}
m_sShaderVS = vs;
m_sShaderPS = ps;
m_sShaderDefine = define;
//重新new新的shader
std::vector<std::string> vString;
m_pShaderTemplate = new JCGpuProgramTemplate(vs.c_str(), ps.c_str(),vString);
m_pGpuProgram = m_pShaderTemplate->getInstance(define.c_str());
}
}
const char* JSLayaGL::getShaderInfoLogEx(const char* source,int type)
{
std::string str_source = source;
m_sErrorInfo = "";
JCConch::s_pConchRender->setInterruptFunc(std::bind(&JSLayaGL::_getShaderInfoLog, this, str_source,type));
return m_sErrorInfo.c_str();
}
const char* JSLayaGL::getProgramInfoLogEx(const char* vs, const char* ps, const char* define)
{
std::string str_vs = vs;
std::string str_ps = ps;
std::string str_define = define;
m_sErrorInfo = "";
JCConch::s_pConchRender->setInterruptFunc(std::bind(&JSLayaGL::_getProgramInfoLog, this, str_vs, str_ps, str_define));
return m_sErrorInfo.c_str();
}
void JSLayaGL::_getShaderInfoLog(const std::string& source,int type)
{
GLuint nShader = glCreateShader(type);
const char* strShaders[1] = {source.c_str()};
glShaderSource(nShader, 1, strShaders, NULL);
glCompileShader(nShader);
//看错误
GLint nInfoLen = 0;
glGetShaderiv(nShader, GL_INFO_LOG_LENGTH, &nInfoLen);
if (nInfoLen)
{
char* buf = new char[nInfoLen];
glGetShaderInfoLog(nShader, nInfoLen, NULL, buf);
m_sErrorInfo = "";
m_sErrorInfo = buf;
delete buf;
}
glDeleteShader(nShader);
}
void JSLayaGL::_getProgramInfoLog(const std::string& vs, const std::string& ps, const std::string& define)
{
_createShader(vs, ps, define);
GLint nInfoLen = 0;
int gpuProgram = m_pGpuProgram->getGpuProgram();
if (!gpuProgram)
{
m_sErrorInfo = "invalid shaders";
}
else
{
glGetShaderiv(gpuProgram, GL_INFO_LOG_LENGTH, &nInfoLen);
if (nInfoLen)
{
char* buf = new char[nInfoLen];
glGetProgramInfoLog(m_pGpuProgram->getGpuProgram(), nInfoLen, NULL, buf);
m_sErrorInfo = "";
m_sErrorInfo = buf;
delete buf;
}
}
}
/*int JSLayaGL::getBufferParameter(int target, int pname)
{
JCConch::s_pConchRender->setInterruptFunc(std::bind(&JSLayaGL::_getBufferParameter, this, target,pname));
return m_nParameterResult;
}
void JSLayaGL::_getBufferParameter(int target, int pname)
{
::glGetBufferParameteriv(target, pname, &m_nParameterResult);
}*/
int JSLayaGL::getFramebufferAttachmentParameter(int target, int attachment, int pname)
{
JCConch::s_pConchRender->setInterruptFunc(std::bind(&JSLayaGL::_getFramebufferAttachmentParameter, this, target, attachment, pname));
return m_nParameterResult;
}
void JSLayaGL::_getFramebufferAttachmentParameter(int target, int attachment, int pname)
{
if (g_kSystemConfig.m_nThreadMODE == THREAD_MODE_SINGLE)
{
JCScriptRuntime::s_JSRT->dispatchLayaGLBuffer(false);
::glGetFramebufferAttachmentParameteriv(target, attachment, pname, &m_nParameterResult);
}
else
{
LOGI("getFramebufferAttachmentParameter not supported");
}
}
/*int JSLayaGL::getRenderbufferParameter(int target, int pname)
{
JCConch::s_pConchRender->setInterruptFunc(std::bind(&JSLayaGL::_getRenderbufferParameter, this, target, pname));
return m_nParameterResult;
}
void JSLayaGL::_getRenderbufferParameter(int target, int pname)
{
::glGetRenderbufferParameteriv(target, pname, &m_nParameterResult);
}
int JSLayaGL::getTexParameter(int target, int pname)
{
JCConch::s_pConchRender->setInterruptFunc(std::bind(&JSLayaGL::_getTexParameter, this, target, pname));
return m_nParameterResult;
}
void JSLayaGL::_getTexParameter(int target, int pname)
{
::glGetTexParameteriv(target, pname, &m_nParameterResult);
}*/
int JSLayaGL::getShaderParameter(const char* src,int type,int pname)
{
std::string str_source = src;
JCConch::s_pConchRender->setInterruptFunc(std::bind(&JSLayaGL::_getShaderParameter, this, str_source, type, pname));
return m_nParameterResult;
}
void JSLayaGL::_getShaderParameter(const std::string& source,int type, int pname)
{
GLuint nShader = glCreateShader(type);
const char* strShaders[1] = { source.c_str() };
glShaderSource(nShader, 1, strShaders, NULL);
glCompileShader(nShader);
::glGetShaderiv(nShader, pname, &m_nParameterResult);
glDeleteShader(nShader);
}
void JSLayaGL::_readPixels(int x, int y, int width, int height, int format, int type)
{
if (g_kSystemConfig.m_nThreadMODE == THREAD_MODE_SINGLE)
{
JCScriptRuntime::s_JSRT->dispatchLayaGLBuffer(false);
m_nParameterResultByteArray.clear();
int bytes = 0;
int bytesPerRow = 0;
int comp = 0;
switch (format)
{
case GL_ALPHA:
comp = 1;
break;
case GL_RGB:
comp = 3;
break;
case GL_RGBA:
comp = 4;
break;
default:
LOGE("LayaGL Invalid parameter");
return;
break;
}
switch (type)
{
case GL_UNSIGNED_BYTE:
bytesPerRow = width * comp;
bytes = bytesPerRow * height;
break;
case GL_UNSIGNED_SHORT_5_6_5:
if (format != GL_RGB)
{
LOGE("LayaGL Invalid operation");
return;
}
bytesPerRow = width * 2;
bytes = bytesPerRow * height;
break;
case GL_UNSIGNED_SHORT_4_4_4_4:
case GL_UNSIGNED_SHORT_5_5_5_1:
if (format != GL_RGBA)
{
LOGE("LayaGL Invalid operation");
return;
}
bytesPerRow = width * 2;
bytes = bytesPerRow * height;
break;
case GL_FLOAT:
bytesPerRow = width * 4 * comp;;
bytes = bytesPerRow * height;
break;
default:
LOGE("LayaGL Invalid parameter");
return;
break;
}
m_nParameterResultByteArray.resize(bytes);
::glReadPixels(x, y, width, height, format, type, (void*)m_nParameterResultByteArray.data());
}
else
{
LOGI("readPixels not supported");
}
}
int JSLayaGL::checkFramebufferStatusEx(int target)
{
if (g_kSystemConfig.m_nThreadMODE == THREAD_MODE_SINGLE)
{
JCScriptRuntime::s_JSRT->dispatchLayaGLBuffer(false);
return ::glCheckFramebufferStatus(target);
}
else
{
LOGI("checkFramebufferStatus not supported");
return 0;
}
}
int JSLayaGL::getVertexAttribEx(int index, int target)
{
int result = 0;
if (g_kSystemConfig.m_nThreadMODE == THREAD_MODE_SINGLE)
{
JCScriptRuntime::s_JSRT->dispatchLayaGLBuffer(false);
glGetVertexAttribiv(index, target, &result);
}
else
{
LOGI("getVertexAttrib not supported");
}
return result;
}
JsValue JSLayaGL::getVertexAttribExfv(int index, int target)
{
static float ret[4] = { 0.0 };
m_nParameterResultArray.clear();
if (g_kSystemConfig.m_nThreadMODE == THREAD_MODE_SINGLE)
{
JCScriptRuntime::s_JSRT->dispatchLayaGLBuffer(false);
glGetVertexAttribfv(index, target, ret);
for (int i = 0; i < 4; i++)
{
m_nParameterResultArray.push_back(ret[i]);
}
}
else
{
LOGI("getVertexAttrib not supported");
}
return __JsArray<float>::ToJsArray(m_nParameterResultArray);
}
int JSLayaGL::getVertexAttribOffset(int index, int pname)
{
void* result = nullptr;
if (g_kSystemConfig.m_nThreadMODE == THREAD_MODE_SINGLE)
{
JCScriptRuntime::s_JSRT->dispatchLayaGLBuffer(false);
::glGetVertexAttribPointerv(index, pname, &result);
}
else
{
LOGI("getVertexAttribOffset not supported");
}
return reinterpret_cast<intptr_t>(result);
}
int JSLayaGL::getBufferParameterEx(int target, int pname)
{
if (g_kSystemConfig.m_nThreadMODE == THREAD_MODE_SINGLE)
{
JCScriptRuntime::s_JSRT->dispatchLayaGLBuffer(false);
GLint params;
::glGetBufferParameteriv(target, pname, &params);
return params;
}
else
{
LOGI("getBufferParameter not supported");
return 0;
}
}
int JSLayaGL::getRenderbufferParameterEx(int target, int pname)
{
if (g_kSystemConfig.m_nThreadMODE == THREAD_MODE_SINGLE)
{
JCScriptRuntime::s_JSRT->dispatchLayaGLBuffer(false);
GLint params;
::glGetRenderbufferParameteriv(target, pname, &params);
return params;
}
else
{
LOGI("getRenderbufferParameter not supported");
return 0;
}
}
int JSLayaGL::getTexParameterEx(int target, int pname)
{
if (g_kSystemConfig.m_nThreadMODE == THREAD_MODE_SINGLE)
{
JCScriptRuntime::s_JSRT->dispatchLayaGLBuffer(false);
GLint params;
::glGetTexParameteriv(target, pname, &params);
return params;
}
else
{
LOGI("getTexParameter not supported");
return 0;
}
}
int JSLayaGL::isEnabled(unsigned int cap)
{
if (g_kSystemConfig.m_nThreadMODE == THREAD_MODE_SINGLE)
{
JCScriptRuntime::s_JSRT->dispatchLayaGLBuffer(false);
}
int ret = (int) ::glIsEnabled(cap);
return ::glIsEnabled(cap);
}
void JSLayaGL::flushCommand()
{
if (g_kSystemConfig.m_nThreadMODE == THREAD_MODE_SINGLE)
{
JCScriptRuntime::s_JSRT->dispatchLayaGLBuffer(false);
}
else
{
LOGI("flushCommand is not supported");
}
}
void JSLayaGL::setMainContextSize(int width,int height)
{
if (g_kSystemConfig.m_nThreadMODE == THREAD_MODE_SINGLE)
{
JCConch::s_pConchRender->m_pLayaGL->m_nMainCanvasWidth = width;
JCConch::s_pConchRender->m_pLayaGL->m_nMainCanvasHeight = height;
}
else
{
JCScriptRuntime::s_JSRT->flushSharedCmdBuffer();
JCCommandEncoderBuffer* pCmd = JCScriptRuntime::s_JSRT->m_pRenderCmd;
pCmd->append(LAYA_SET_MAIN_CONTEXT_SIZE);
pCmd->append(width);
pCmd->append(height);
}
}
void JSLayaGL::exportJS()
{
JSP_GLOBAL_CLASS("layagl", JSLayaGL);
JSP_ADD_METHOD("setFrameAndSyncCountArrayBufferID", JSLayaGL::setFrameAndSyncCountArrayBufferID);
JSP_ADD_METHOD("setSyncArrayBufferID", JSLayaGL::setSyncArrayBufferID);
JSP_ADD_METHOD("setRootCommandEncoder", JSLayaGL::setRootCommandEncoder);
JSP_ADD_METHOD("getProgramParameterEx", JSLayaGL::getProgramParameterEx);
JSP_ADD_METHOD("getStringEx", JSLayaGL::getStringEx);
JSP_ADD_METHOD("getActiveAttribEx", JSLayaGL::getActiveAttribEx);
JSP_ADD_METHOD("getActiveUniformEx", JSLayaGL::getActiveUniformEx);
JSP_ADD_METHOD("getAttribLocationEx", JSLayaGL::getAttribLocationEx);
JSP_ADD_METHOD("getShaderInfoLogEx", JSLayaGL::getShaderInfoLogEx);
JSP_ADD_METHOD("getProgramInfoLogEx", JSLayaGL::getProgramInfoLogEx);
JSP_ADD_METHOD("getShaderPrecisionFormat", JSLayaGL::getShaderPrecisionFormat);
JSP_ADD_METHOD("getUniformEx", JSLayaGL::getUniformEx);
JSP_ADD_METHOD("getParameter", JSLayaGL::getParameter);
JSP_ADD_METHOD("getBooleanv", JSLayaGL::getBooleanv);
JSP_ADD_METHOD("getIntegerv", JSLayaGL::getIntegerv);
JSP_ADD_METHOD("getIntegerArrayv", JSLayaGL::getIntegerArrayv);
JSP_ADD_METHOD("getFloatv", JSLayaGL::getFloatv);
JSP_ADD_METHOD("getFloatArrayv", JSLayaGL::getFloatArrayv);
//JSP_ADD_METHOD("getBufferParameter", JSLayaGL::getBufferParameter);
JSP_ADD_METHOD("getFramebufferAttachmentParameter", JSLayaGL::getFramebufferAttachmentParameter);
//JSP_ADD_METHOD("getRenderbufferParameter", JSLayaGL::getRenderbufferParameter);
//JSP_ADD_METHOD("getTexParameter", JSLayaGL::getTexParameter);
JSP_ADD_METHOD("getShaderParameter", JSLayaGL::getShaderParameter);
JSP_ADD_METHOD("getThreadMode", JSLayaGL::getThreadMode);
JSP_ADD_METHOD("checkFramebufferStatusEx", JSLayaGL::checkFramebufferStatusEx);
JSP_ADD_METHOD("getBufferParameterEx", JSLayaGL::getBufferParameterEx);
JSP_ADD_METHOD("getRenderbufferParameterEx", JSLayaGL::getRenderbufferParameterEx);
JSP_ADD_METHOD("getTexParameterEx", JSLayaGL::getTexParameterEx);
JSP_ADD_METHOD("isEnabled", JSLayaGL::isEnabled);
JSP_ADD_METHOD("getVertexAttribEx", JSLayaGL::getVertexAttribEx);
JSP_ADD_METHOD("getVertexAttribExfv", JSLayaGL::getVertexAttribExfv);
JSP_ADD_METHOD("getVertexAttribOffset", JSLayaGL::getVertexAttribOffset);
JSP_ADD_METHOD("flushCommand", JSLayaGL::flushCommand);
JSP_ADD_METHOD("readPixels", JSLayaGL::readPixels);
JSP_ADD_METHOD("setMainContextSize", JSLayaGL::setMainContextSize);
JSP_INSTALL_GLOBAL_CLASS("layagl", JSLayaGL,this);
}
}
//------------------------------------------------------------------------------
//-----------------------------END FILE--------------------------------
@@ -0,0 +1,203 @@
/**
@file JSLayaGL.h
@brief
@author James
@version 1.0
@date 2018_5_25
*/
#ifndef __JSLayaGL_H__
#define __JSLayaGL_H__
#include "../JSInterface/JSInterface.h"
#include <RenderEx/JCGlobalValue.h>
#include <RenderEx/JCGpuProgram.h>
#include <Manager/JCArrayBufferManager.h>
/**
* @brief
*/
namespace laya
{
struct WebGLActiveInfo
{
const static GLsizei bufsize = 255;
GLsizei length;
GLint size;
GLenum type;
GLchar name[bufsize];
};
struct ShaderPrecisionFormat
{
int range[2];
int precision[1];
};
class JSLayaGL:public JsObjBase, public JSObjNode
{
public:
static JsObjClassInfo JSCLSINFO;
void exportJS();
static JSLayaGL* getInstance();
JSLayaGL();
~JSLayaGL();
void setSyncArrayBufferID(int nSyncArrayBufferID);
void setFrameAndSyncCountArrayBufferID(int nBufferID);
void setRootCommandEncoder( int nCommandEncoderID );
public:
int getAttribLocationEx(const char* vs, const char* ps, const char* define,const char* sName);
JsValue getShaderPrecisionFormat(int shaderType, int precisionType);
JsValue getUniformEx(const char* locationName);
int getParameter(int pname);
bool getBooleanv(int pname);
int getIntegerv(int pname);
JsValue getIntegerArrayv(int pname);
float getFloatv(int pname);
JsValue getFloatArrayv(int pname);
JsValue readPixels(int x, int y, int width, int height, int format, int type);
void setCurrentContext(int nContextID);
int getThreadMode();
public:
int getProgramParameterEx(const char* vs, const char* ps, const char* define, int type);
JsValue getActiveAttribEx(const char* vs, const char* ps, const char* define, int nIndex);
JsValue getActiveUniformEx(const char* vs, const char* ps, const char* define, int nIndex);
const char* getStringEx(unsigned int name);
const char* getShaderInfoLogEx(const char* source,int type);
const char* getProgramInfoLogEx(const char* vs, const char* ps, const char* define);
//int getBufferParameter(int target, int pname);
int getFramebufferAttachmentParameter(int target, int attachement, int pname);
//int getRenderbufferParameter(int target, int pname);
//int getTexParameter(int target, int pname);
int getShaderParameter(const char* src, int type,int pname);
int checkFramebufferStatusEx(int target);
int getVertexAttribEx(int index, int target);
JsValue getVertexAttribExfv(int index, int target);
int getVertexAttribOffset(int index, int target);
int getBufferParameterEx(int target, int pname);
int getRenderbufferParameterEx(int target, int pname);
int getTexParameterEx(int target, int pname);
int isEnabled(unsigned int cap);
void flushCommand();
void setMainContextSize(int width, int height);
private:
void _getStringEx(unsigned int name);
void _getProgramParameterEx(const std::string& vs, const std::string& ps, const std::string& define, int type);
void _getActiveAttribEx(const std::string& vs, const std::string& ps, const std::string& define, int nIndex);
void _getActiveUniformEx(const std::string& vs, const std::string& ps, const std::string& define, int nIndex);
void _getAttribLocationEx(const std::string& vs, const std::string& ps, const std::string& define, const std::string& name);
void _getShaderPrecisionFormat(int shaderType, int precisionType);
void _getUniformEx(const std::string& locationName);
void _getParameter(int pname);
void _getBooleanv(int pname);
void _getIntegerv(int pname);
void _getIntegerArrayv(int pname);
void _getFloatv(int pname);
void _getFloatArrayv(int pname);
void _createShader(const std::string& vs, const std::string& ps, const std::string& define);
void _getShaderInfoLog(const std::string& source,int type);
void _getProgramInfoLog(const std::string& vs, const std::string& ps, const std::string& define);
//void _getBufferParameter(int target, int pname);
void _getFramebufferAttachmentParameter(int target, int attachement, int pname);
//void _getRenderbufferParameter(int target, int pname);
//void _getTexParameter(int target, int pname);
void _getShaderParameter(const std::string& source, int type, int pname);
void _readPixels(int x, int y, int width, int height, int format, int type);
public:
static JSLayaGL* s_pLayaGL;
JCGlobalValue* m_pValueTemplate;
int m_nSyncToRenderABListID;
int m_nFrameAndSyncCountABListID;
int m_nRootCommandEncoderID;
JCArrayBufferManager::ArrayBufferContent* m_pRootCommandEncoder;
int m_nFrameCount;
int m_nSyncArrayBufferCount;
int m_nParameterResult;
float m_nParameterResultFloat;
GLboolean m_nParameterResultBool;
std::vector<float> m_nParameterResultArray;
std::vector<uint8_t> m_nParameterResultByteArray;
private:
int m_nAttribLocation;
int m_nProgramParameter;
ShaderPrecisionFormat* m_pShaderPrecisionFormat;
WebGLActiveInfo* m_pShaderActiveInfo;
JCGpuProgramTemplate* m_pShaderTemplate;
JCGpuProgram* m_pGpuProgram;
std::string m_sShaderVS;
std::string m_sShaderPS;
std::string m_sShaderDefine;
std::string m_sErrorInfo;
std::string m_sGLString;
};
}
//------------------------------------------------------------------------------
#endif //__JSLayaGL_H__
//-----------------------------END FILE--------------------------------
@@ -0,0 +1,124 @@
/**
@file JSNotify.cpp
@brief
@author James
@version 1.0
@date 2015_9_26
*/
//包含头文件
#include "JSNotify.h"
#include "util/Log.h"
#include "util/JCMemorySurvey.h"
#ifdef ANDROID
#include <jni.h>
#include "../../CToJavaBridge.h"
#elif __APPLE__
#include "../../CToObjectC.h"
#endif
namespace laya
{
ADDJSCLSINFO(JSNotify, JSObjNode);
JSNotify* JSNotify::ms_pNotify = NULL;
//------------------------------------------------------------------------------
JSNotify* JSNotify::GetInstance()
{
if( ms_pNotify == NULL )
{
ms_pNotify = new JSNotify();
}
return ms_pNotify;
}
//------------------------------------------------------------------------------
JSNotify::JSNotify()
{
}
//------------------------------------------------------------------------------
JSNotify::~JSNotify()
{
ms_pNotify = NULL;
}
//------------------------------------------------------------------------------
void JSNotify::setRepeatNotify( int p_nID,int p_nStartTime,int p_nRepeatType,const char* p_sTickerText,const char* p_sTitleText,const char* p_sDesc )
{
LOGI("JSNotify::setRepeatNotify id=%d,startTime=%ld,type=%d,tickerText=%s,titleText=%s,desc=%s",p_nID,p_nStartTime,p_nRepeatType,p_sTickerText,p_sTitleText,p_sDesc );
#ifdef ANDROID
std::vector<intptr_t> params;
params.push_back(p_nID);
params.push_back((long)p_nStartTime);
params.push_back(p_nRepeatType);
params.push_back((long)p_sTickerText);
params.push_back((long)p_sTitleText);
params.push_back((long)p_sDesc);
CToJavaBridge::JavaRet kRet;
CToJavaBridge::GetInstance()->callMethod("laya.game.Notifycation.LayaNotifyManager", "setRepeatingNotify", p_nID, p_nStartTime,p_nRepeatType,p_sTickerText, p_sTitleText, p_sDesc, kRet);
#elif __APPLE__
CToObjectCSetRepeatNotify( p_nID,p_nStartTime,p_nRepeatType,p_sTickerText,p_sTickerText,p_sDesc );
#elif WIN32
#endif
}
//------------------------------------------------------------------------------
void JSNotify::setOnceNotify( int p_nID,int p_nStartTime,const char* p_sTickerText,const char* p_sTitleText,const char* p_sDesc )
{
LOGI("JSNotify::setOnceNotify id=%d,startTime=%ld,tickerText=%s,titleText=%s,desc=%s",p_nID,p_nStartTime,p_sTickerText,p_sTitleText,p_sDesc );
#ifdef ANDROID
std::vector<intptr_t> params;
params.push_back(p_nID);
params.push_back((long)p_nStartTime);
params.push_back((long)p_sTickerText);
params.push_back((long)p_sTitleText);
params.push_back((long)p_sDesc);
CToJavaBridge::JavaRet kRet;
CToJavaBridge::GetInstance()->callMethod("layaair.game.Notifycation.LayaNotifyManager", "setOnceNotify", p_nID,p_nStartTime,p_sTickerText,p_sTitleText,p_sDesc,kRet);
#elif __APPLE__
CToObjectCSetOnceNotify( p_nID,p_nStartTime,p_sTickerText,p_sTitleText,p_sDesc );
#elif WIN32
#endif
}
//------------------------------------------------------------------------------
void JSNotify::deleteOnceNotify( int p_nID )
{
LOGI("JSNotify::deleteOnceNotify id=%d",p_nID );
#ifdef ANDROID
CToJavaBridge::JavaRet kRet;
CToJavaBridge::GetInstance()->callMethod("layaair.game.Notifycation.LayaNotifyManager", "removeNotify", p_nID, kRet);
#elif __APPLE__
CToObjectCDeleteOnceNotify( p_nID );
#elif WIN32
#endif
}
//------------------------------------------------------------------------------
void JSNotify::deleteAllNotify()
{
LOGI("JSNotify::deleteAllNotify" );
#ifdef ANDROID
CToJavaBridge::JavaRet kRet;
CToJavaBridge::GetInstance()->callMethod("layaair.game.Notifycation.LayaNotifyManager", "removeAllNotify", kRet);
#elif __APPLE__
CToObjectCDeleteAllNotify();
#elif WIN32
#endif
}
//------------------------------------------------------------------------------
void JSNotify::exportJS()
{
JSP_GLOBAL_CLASS("conchNotify", JSNotify);
JSP_ADD_METHOD("setRepeatNotify", JSNotify::setRepeatNotify);
JSP_ADD_METHOD("setOnceNotify", JSNotify::setOnceNotify);
JSP_ADD_METHOD("deleteOnceNotify", JSNotify::deleteOnceNotify);
JSP_ADD_METHOD("deleteAllNotify", JSNotify::deleteAllNotify);
JSP_INSTALL_GLOBAL_CLASS("conchNotify", JSNotify, JSNotify::GetInstance());
}
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//-----------------------------END FILE--------------------------------
@@ -0,0 +1,59 @@
/**
@file JSNotify.h
@brief
@author James
@version 1.0
@date 2015_9_26
*/
#ifndef __JSNotify_H__
#define __JSNotify_H__
//包含头文件
#include <stdio.h>
#include <string>
#include "../JSInterface/JSInterface.h"
/**
* @brief
*/
namespace laya
{
class JSNotify :public JsObjBase, public JSObjNode
{
public:
static JsObjClassInfo JSCLSINFO;
static void exportJS();
static JSNotify* GetInstance();
JSNotify();
~JSNotify();
public:
//设置重复的消息
//type 0是年 1是月 2是日 3是时 4是分 5是秒
void setRepeatNotify( int p_nID,int p_nStartTime,int p_nRepeatType,const char* p_sTickerText,const char* p_sTitleText,const char* p_sDesc );
//设置只提示一次的消息
void setOnceNotify( int p_nID,int p_nStartTime,const char* p_sTickerText,const char* p_sTitleText,const char* p_sDesc );
//删除某一个消息和定时器
void deleteOnceNotify( int p_nID );
//只删除全部消息,但是保留定时器
void deleteAllNotify();
public:
static JSNotify* ms_pNotify;
};
}
#endif //__JSNotify_H__
//-----------------------------END FILE--------------------------------
@@ -0,0 +1,432 @@
/**
@file JSRuntime.cpp
@brief
@author James
@version 1.0
@date 2016_5_13
*/
#include "JSRuntime.h"
#include "util/JCCrypto.h"
#include "downloadMgr/JCDownloadMgr.h"
#include "../../JCConch.h"
#include <downloadCache/JCFileSource.h>
#ifdef __APPLE__
#include "jsc/JSWebGLPlus.h"
#include "../../CToObjectC.h"
#else
#include "v8/JSWebGLPlus.h"
#endif
#ifdef ANDROID
#include "../../CToJavaBridge.h"
#endif
#include "../../JCSystemConfig.h"
#include "JSInput.h"
#include "JSConchConfig.h"
#include <imageLib/JCImageRW.h>
#include "JSLayaGL.h"
//------------------------------------------------------------------------------
namespace laya
{
ADDJSCLSINFO(JSRuntime, JSObjNode);
JSRuntime::JSRuntime()
{
m_pScrpitRuntime = JCScriptRuntime::s_JSRT;
}
JSRuntime::~JSRuntime()
{
m_pScrpitRuntime = NULL;
}
void JSRuntime::setOnFrameFunction(JSValueAsParam p_pFunction)
{
m_pScrpitRuntime->m_pJSOnFrameFunction.set(onframeid, this, p_pFunction);
}
void JSRuntime::setOnDrawFunction(JSValueAsParam p_pFunction)
{
m_pScrpitRuntime->m_pJSOnDrawFunction.set(ondrawid, this, p_pFunction);
}
void JSRuntime::setOnResizeFunction(JSValueAsParam p_onresize)
{
m_pScrpitRuntime->m_pJSOnResizeFunction.set(onresizeid, this, p_onresize);
}
void JSRuntime::setOnBlurFunction(JSValueAsParam p_pFunction)
{
m_pScrpitRuntime->m_pJSOnBlurFunction.set(onblurid, this, p_pFunction);
}
void JSRuntime::setOnFocusFunction(JSValueAsParam p_pFunction)
{
m_pScrpitRuntime->m_pJSOnFocusFunction.set(onfocusid, this, p_pFunction);
}
void JSRuntime::setGetWorldTransformFunction(JSValueAsParam p_pFunction)
{
m_pScrpitRuntime->m_bJSBulletGetWorldTransformHandle.set(bulletgetid, this, p_pFunction);
}
void JSRuntime::setSetWorldTransformFunction(JSValueAsParam p_pFunction)
{
m_pScrpitRuntime->m_bJSBulletSetWorldTransformHandle.set(bulletsetid, this, p_pFunction);
}
void JSRuntime::setBuffer(JSValueAsParam pArrayBuffer)
{
char* pArrayBufferPtr = NULL;
int nABLen = 0;
bool bIsArrayBuffer = extractJSAB(pArrayBuffer, pArrayBufferPtr, nABLen);
if (bIsArrayBuffer)
{
m_pScrpitRuntime->m_pOtherBufferSharedWidthJS = pArrayBufferPtr;
}
else {
LOGE("JSRuntime::setCmdBuffer param is not an ArrayBuffer!");
}
}
void JSRuntime::setHref(JSValueAsParam p_sHref)
{
const char* sBuffer = NULL;
if (JsObjHandle::tryGetStr(p_sHref, (char**)&sBuffer))
{
if (sBuffer && strlen(sBuffer) > 0)
{
if (!sBuffer)
return;
std::string url = m_pScrpitRuntime->m_pUrl->resolve(sBuffer);
g_kSystemConfig.m_strStartURL = url;
g_kSystemConfig.m_strStartURL.at(0) = g_kSystemConfig.m_strStartURL.at(0);
JCDownloadMgr* pdm = JCDownloadMgr::getInstance();
if (pdm)
{
pdm->resetFinalReplacePath();
pdm->resetDownloadTail();
pdm->resetDownloadReplaceExt();
}
m_pScrpitRuntime->m_pUrl->parse(url.c_str());
std::string tempurl = m_pScrpitRuntime->m_pUrl->m_Host;
JCEncrypt::getpassCode(tempurl);
std::string ss = m_pScrpitRuntime->m_pUrl->m_Host;
int n = ss.find(':');
if (n>0)
ss.at(n) = '.';
std::string cookiefile = JSConchConfig::getInstance()->getLocalStoragePath() + ss + "_curlcookie.txt";
pdm->setCookieFile(cookiefile.c_str());
#ifdef ANDROID
CToJavaBridge::JavaRet kRet;
CToJavaBridge::GetInstance()->callMethod(CToJavaBridge::JavaClass.c_str(), "setHrefToJava", url.c_str(), kRet);
#endif
}
}
}
void JSRuntime::setMouseEvtFunction(JSValueAsParam p_pFunction)
{
m_pScrpitRuntime->m_pJSMouseEvtFunction.set(onmouseevtid, this, p_pFunction);
}
void JSRuntime::setTouchEvtFunction(JSValueAsParam p_pFunction)
{
m_pScrpitRuntime->m_pJSTouchEvtFunction.set(ontouchevtid, this, p_pFunction);
}
void JSRuntime::setDeviceMotionEvtFunction(JSValueAsParam p_pFunction)
{
m_pScrpitRuntime->m_pJSDeviceMotionEvtFunction.set(ondevicemotionevtid, this, p_pFunction);
}
void JSRuntime::setKeyEvtFunction(JSValueAsParam p_pFunction)
{
m_pScrpitRuntime->m_pJSKeyEvtFunction.set(onkeyevtid, this, p_pFunction);
}
void JSRuntime::setNetworkEvtFunction(JSValueAsParam p_pFunction)
{
m_pScrpitRuntime->m_pJSNetworkEvtFunction.set(onnetworkevt, this, p_pFunction);
}
void JSRuntime::setOnBackPressedFunction(JSValueAsParam p_pFunction)
{
std::lock_guard<std::mutex> lock(m_pScrpitRuntime->m_OnBackPressedMutex);
m_pScrpitRuntime->m_bJSOnBackPressedFunctionSet = true;
m_pScrpitRuntime->m_pJSOnBackPressedFunction.set(onbackpressed, this, p_pFunction);
}
void JSRuntime::captureScreen(JSValueAsParam p_pFunction)
{
m_pScrpitRuntime->m_pJSOnceOtherEvtFuction.set(onotherevtid, this, p_pFunction);
#ifdef ANDROID
CToJavaBridge::JavaRet kRet;
CToJavaBridge::GetInstance()->callMethod(CToJavaBridge::JavaClass.c_str(), "captureScreen", kRet);
#elif __APPLE__
CToObjectCCaptureScreen();
#endif
}
const char* JSRuntime::getCachePath()
{
return JCConch::s_pConch->m_sCachePath.c_str();
}
unsigned char* _readAssetAlloc(int sz, void* pUserData)
{
auto ret = new unsigned char[sz];
*(unsigned char**)pUserData = ret;
return ret;
}
JsValue JSRuntime::readFileFromAsset(const char* file, const char* encode)
{
if (!m_pScrpitRuntime->m_pAssetsRes)
{
return JSP_TO_JS_NULL;
}
int sz = 0;
unsigned char* pBuff = NULL;
if (m_pScrpitRuntime->m_pAssetsRes->loadFileContent(file, _readAssetAlloc, &pBuff, sz))
{
if (strcmp(encode, "utf8") == 0)
{
std::string str;
str.assign((char*)pBuff, sz);
delete[] pBuff;
return JSP_TO_JS_STR(str.c_str());
}
else
{
//TODO 写一个不用自己保留的AB
JsValue ab = createJSAB((char*)pBuff, sz);
//JSArrayBuffer* pab = JSArrayBuffer::create(sz);
//memcpy(pab->getPtr(), pBuff, sz);
delete[] pBuff;
//return (pab->toLocal());;
return ab;
}
}
return JSP_TO_JS_NULL;
}
void JSRuntime::setScreenWakeLock(bool p_bWakeLock)
{
#ifdef __APPLE__
CToObjectCSetScreenWakeLock(p_bWakeLock);
#elif ANDROID
CToJavaBridge::JavaRet kRet;
CToJavaBridge::GetInstance()->callMethod(CToJavaBridge::JavaClass.c_str(), "setScreenWakeLock", p_bWakeLock, kRet);
#elif WIN32
#endif
}
void JSRuntime::setSensorAble(bool p_bSensorAble)
{
#ifdef __APPLE__
CToObjectCSetSensorAble(p_bSensorAble);
#elif ANDROID
CToJavaBridge::JavaRet kRet;
CToJavaBridge::GetInstance()->callMethod(CToJavaBridge::JavaClass.c_str(), "setSensorAble", p_bSensorAble, kRet);
#elif WIN32
#endif
}
JsValue JSRuntime::strTobufer(const char* s)
{
return createJSABAligned((char*)s, (strlen(s)+1));
}
const char* JSRuntime::getPresetUrl()
{
return g_kSystemConfig.m_strStartURL.c_str();
}
void JSRuntime::printCorpseImages()
{
JCImageManager* pImageManger = JCConch::s_pConchRender->m_pImageManager;
if (pImageManger == NULL) return;
std::string sFilePath = JCConch::s_pConch->m_strLocalStoragePath;
sFilePath += "/imagesLog.txt";
pImageManger->printCorpseImages(sFilePath.c_str());
}
const char* JSRuntime::callMethod(int objid,bool isSyn,const char*clsName, const char* methodName, const char* paramStr)
{
#ifdef ANDROID
CToJavaBridge::JavaRet kRet;
if (CToJavaBridge::GetInstance()->callMethodRefection(objid, isSyn, clsName, methodName, paramStr, kRet))
{
m_strReturn = CToJavaBridge::GetInstance()->getJavaString(kRet.pJNI, kRet.strRet);
LOGI("JSRuntime::callMethod %s %s %s", m_strReturn.c_str(), clsName , methodName);
return m_strReturn.c_str();
}
return "";
#elif WIN32
#elif __APPLE__
m_strReturn = CToObjectCCallMethod( objid, isSyn, clsName, methodName,paramStr);
LOGI("JSRuntime::callMethod %s", m_strReturn.c_str());
return m_strReturn.c_str();
#endif
return "";
}
bool JSRuntime::saveAsPng(JSValueAsParam pArrayBufferArgs, int w, int h, const char* p_pszFile)
{
char* pArrayBuffer = NULL;
int nArrayBufferSize = 0;
bool bIsArrayBuffer = extractJSAB(pArrayBufferArgs, pArrayBuffer, nArrayBufferSize);
if (bIsArrayBuffer)
{
return laya::saveAsPng(pArrayBuffer, w, h, p_pszFile);
}
return false;
}
bool JSRuntime::saveAsJpeg(JSValueAsParam pArrayBufferArgs, int w, int h, const char* p_pszFile)
{
char* pArrayBuffer = NULL;
int nArrayBufferSize = 0;
bool bIsArrayBuffer = extractJSAB(pArrayBufferArgs, pArrayBuffer, nArrayBufferSize);
if (bIsArrayBuffer)
{
ImageBaseInfo info;
info.m_nBpp = 32;
info.m_nWidth = w;
info.m_nHeight = h;
return laya::saveAsJpeg(pArrayBuffer, info, p_pszFile);
}
return false;
}
JsValue JSRuntime::convertBitmapToPng(JSValueAsParam pArrayBufferArgs, int w, int h)
{
char* pArrayBuffer = NULL;
int nArrayBufferSize = 0;
bool bIsArrayBuffer = extractJSAB(pArrayBufferArgs, pArrayBuffer, nArrayBufferSize);
if (bIsArrayBuffer)
{
std::pair<unsigned char*, unsigned long> ret = laya::convertBitmapToPng((const char*)pArrayBuffer, w, h, 8);
if (ret.first != nullptr)
return createJSAB((char*)ret.first, ret.second);
}
return JSP_TO_JS_NULL;
}
JsValue JSRuntime::convertBitmapToJpeg(JSValueAsParam pArrayBufferArgs, int w, int h)
{
char* pArrayBuffer = NULL;
int nArrayBufferSize = 0;
bool bIsArrayBuffer = extractJSAB(pArrayBufferArgs, pArrayBuffer, nArrayBufferSize);
if (bIsArrayBuffer)
{
std::pair<unsigned char*, unsigned long> ret = laya::convertBitmapToJpeg((const char*)pArrayBuffer, w, h, 32);
if (ret.first != nullptr)
return createJSAB((char*)ret.first, ret.second);
}
return JSP_TO_JS_NULL;
}
void JSRuntime::setExternalLinkEx(const char* sUrl,int x, int y, int w, int h, bool bCloseWebview)
{
#ifdef ANDROID
CToJavaBridge::JavaRet ret;
CToJavaBridge::GetInstance()->callMethod(CToJavaBridge::JavaClass.c_str(), "setExternalLink", sUrl,x,y,w,h, bCloseWebview?1:0,ret);
#elif __APPLE__
CToObjectCSetExternalLink( sUrl,x,y,w,h, bCloseWebview);
#elif WIN32
#endif
}
void JSRuntime::setExternalLink(const char* sUrl)
{
#ifdef ANDROID
CToJavaBridge::JavaRet ret;
CToJavaBridge::GetInstance()->callMethod(CToJavaBridge::JavaClass.c_str(), "setExternalLink", sUrl, 0, 0, 0, 0,1,ret);
#elif __APPLE__
CToObjectCSetExternalLink(sUrl, 0, 0, 0, 0, true);
#elif WIN32
#endif
}
void JSRuntime::closeExternalLink()
{
#ifdef ANDROID
CToJavaBridge::JavaRet ret;
CToJavaBridge::GetInstance()->callMethod(CToJavaBridge::JavaClass.c_str(), "closeExternalLink", ret);
#elif __APPLE__
CToObjectCCloseExternalLink();
#elif WIN32
#endif
}
void JSRuntime::callWebviewJS(const char* sFunctionName, const char* sJsonParam, const char* sCallbackFunction)
{
LOGI("JSRuntime::callWebviewJS functionName=%s,sJsonParam=%s,sCallbackFunction=%s", sFunctionName, sJsonParam, sCallbackFunction );
#ifdef ANDROID
CToJavaBridge::JavaRet ret;
CToJavaBridge::GetInstance()->callMethod(CToJavaBridge::JavaClass.c_str(), "callWebViewJS", sFunctionName, sJsonParam, sCallbackFunction, ret);
#elif __APPLE__
CToObjectCCallWebviewJS(sFunctionName, sJsonParam, sCallbackFunction);
#elif WIN32
#endif
}
void JSRuntime::hideWebview()
{
#ifdef ANDROID
CToJavaBridge::JavaRet ret;
CToJavaBridge::GetInstance()->callMethod(CToJavaBridge::JavaClass.c_str(), "hideExternalLink", ret);
#elif __APPLE__
CToObjectCHideWebView();
#elif WIN32
#endif
}
void JSRuntime::showWebView()
{
#ifdef ANDROID
CToJavaBridge::JavaRet ret;
CToJavaBridge::GetInstance()->callMethod(CToJavaBridge::JavaClass.c_str(), "showExternalLink", ret);
#elif __APPLE__
CToObjectCShowWebView();
#elif WIN32
#endif
}
void JSRuntime::exit()
{
#ifdef ANDROID
CToJavaBridge::JavaRet ret;
CToJavaBridge::GetInstance()->callMethod(CToJavaBridge::JavaClass.c_str(), "exit", ret);
#elif __APPLE__
#elif WIN32
#endif
}
bool JSRuntime::updateArrayBufferRef(int nID, bool bSyncToRender, JSValueAsParam pArrayBuffer)
{
return JSWebGLPlus::getInstance()->updateArrayBufferRef(nID, bSyncToRender, pArrayBuffer);
}
void JSRuntime::exportJS()
{
JSP_GLOBAL_CLASS("conch", JSRuntime);
JSP_ADD_METHOD("setGetWorldTransformFunction", JSRuntime::setGetWorldTransformFunction);
JSP_ADD_METHOD("setSetWorldTransformFunction", JSRuntime::setSetWorldTransformFunction);
JSP_ADD_METHOD("setOnFrame", JSRuntime::setOnFrameFunction);
JSP_ADD_METHOD("setOnDraw", JSRuntime::setOnDrawFunction);
JSP_ADD_METHOD("setOnResize", JSRuntime::setOnResizeFunction);
JSP_ADD_METHOD("setOnBlur", JSRuntime::setOnBlurFunction);
JSP_ADD_METHOD("setOnFocus", JSRuntime::setOnFocusFunction);
JSP_ADD_METHOD("setHref", JSRuntime::setHref);
JSP_ADD_METHOD("setMouseEvtFunction", JSRuntime::setMouseEvtFunction);
JSP_ADD_METHOD("setKeyEvtFunction", JSRuntime::setKeyEvtFunction);
JSP_ADD_METHOD("setTouchEvtFunction", JSRuntime::setTouchEvtFunction);
JSP_ADD_METHOD("setDeviceMotionEvtFunction", JSRuntime::setDeviceMotionEvtFunction);
JSP_ADD_METHOD("setNetworkEvtFunction", JSRuntime::setNetworkEvtFunction);
JSP_ADD_METHOD("setOnBackPressedFunction", JSRuntime::setOnBackPressedFunction);
JSP_ADD_METHOD("setBuffer", JSRuntime::setBuffer);
JSP_ADD_PROPERTY_RO(presetUrl, JSRuntime,getPresetUrl);
JSP_ADD_METHOD("setScreenWakeLock", JSRuntime::setScreenWakeLock);
JSP_ADD_METHOD("setSensorAble", JSRuntime::setSensorAble);
JSP_ADD_METHOD("readFileFromAsset", JSRuntime::readFileFromAsset);
JSP_ADD_METHOD("getCachePath", JSRuntime::getCachePath);
JSP_ADD_METHOD("strTobufer", JSRuntime::strTobufer);
JSP_ADD_METHOD("callMethod", JSRuntime::callMethod);
JSP_ADD_METHOD("printCorpseImages", JSRuntime::printCorpseImages);
JSP_ADD_METHOD("setExternalLink", JSRuntime::setExternalLink);
JSP_ADD_METHOD("setExternalLinkEx", JSRuntime::setExternalLinkEx);
JSP_ADD_METHOD("closeExternalLink", JSRuntime::closeExternalLink);
JSP_ADD_METHOD("hideWebview", JSRuntime::hideWebview);
JSP_ADD_METHOD("showWebview", JSRuntime::showWebView);
JSP_ADD_METHOD("captureScreen", JSRuntime::captureScreen);
JSP_ADD_METHOD("saveAsPng", JSRuntime::saveAsPng);
JSP_ADD_METHOD("saveAsJpeg", JSRuntime::saveAsJpeg);
JSP_ADD_METHOD("convertBitmapToPng", JSRuntime::convertBitmapToPng);
JSP_ADD_METHOD("convertBitmapToJpeg", JSRuntime::convertBitmapToJpeg);
JSP_ADD_METHOD("callWebviewJS", JSRuntime::callWebviewJS);
JSP_ADD_METHOD("updateArrayBufferRef", JSRuntime::updateArrayBufferRef);
JSP_ADD_METHOD("exit", JSRuntime::exit);
JSP_INSTALL_GLOBAL_CLASS("conch", JSRuntime, this );
}
}
//------------------------------------------------------------------------------
//-----------------------------END FILE--------------------------------
@@ -0,0 +1,123 @@
/**
@file JSRuntime.h
@brief
@author James
@version 1.0
@date 2016_5_13
*/
#ifndef __JSRuntime_H__
#define __JSRuntime_H__
#include <stdio.h>
#include "../JSInterface/JSInterface.h"
#include "../../JCScriptRuntime.h"
/**
* @brief
*/
namespace laya
{
class JSRuntime : public JsObjBase, public JSObjNode
{
public:
enum
{
onframeid, ondrawid, onresizeid, ontouchevtid,ondevicemotionevtid, onkeyevtid, onmouseevtid, oninvalidglid,onotherevtid,onnetworkevt,onbackpressed,onblurid,onfocusid, bulletsetid, bulletgetid
};
static JsObjClassInfo JSCLSINFO;
void exportJS();
JSRuntime();
~JSRuntime();
public:
void setOnFrameFunction( JSValueAsParam p_pFunction );
void setOnDrawFunction(JSValueAsParam p_pFunction);
void setOnResizeFunction(JSValueAsParam p_onresize);
void setOnBlurFunction(JSValueAsParam p_pFunction);
void setOnFocusFunction(JSValueAsParam p_pFunction);
void setHref(JSValueAsParam p_sHref);
void setMouseEvtFunction(JSValueAsParam p_pFunction);
void setTouchEvtFunction(JSValueAsParam p_pFunction);
void setDeviceMotionEvtFunction(JSValueAsParam p_pFunction);
void captureScreen(JSValueAsParam p_pFunction);
void setKeyEvtFunction(JSValueAsParam p_pFunction);
void setNetworkEvtFunction(JSValueAsParam p_pFunction);
void setOnBackPressedFunction(JSValueAsParam p_pFunction);
void setScreenWakeLock(bool p_bWakeLock);
void setSensorAble(bool p_bSensorAble);
void setBuffer(JSValueAsParam pArrayBuffer);
bool saveAsPng(JSValueAsParam pArrayBufferArgs, int w, int h, const char* p_pszFile);
bool saveAsJpeg(JSValueAsParam pArrayBufferArgs, int w, int h, const char* p_pszFile);
JsValue convertBitmapToPng(JSValueAsParam pArrayBufferArgs, int w, int h);
JsValue convertBitmapToJpeg(JSValueAsParam pArrayBufferArgs, int w, int h);
void setGetWorldTransformFunction(JSValueAsParam p_pFunction);
void setSetWorldTransformFunction(JSValueAsParam p_pFunction);
public:
JsValue readFileFromAsset(const char* file, const char* encode);
JsValue strTobufer(const char* s);
const char* callMethod(int objid,bool isSyn,const char*clsName, const char* methodName, const char* paramStr);
const char* getCachePath();
const char* getPresetUrl();
void printCorpseImages();
void setExternalLink(const char* sUrl);
void setExternalLinkEx( const char* sUrl,int x,int y,int w,int h,bool bCloseWebview );
void closeExternalLink();
void callWebviewJS( const char* sFunctionName,const char* sJsonParam,const char* sCallbackFunction );
void hideWebview();
void showWebView();
void exit();
bool updateArrayBufferRef(int nID, bool bSyncToRender, JSValueAsParam pArrayBuffer);
public:
JCScriptRuntime* m_pScrpitRuntime;
std::string m_strReturn;
};
}
//------------------------------------------------------------------------------
#endif //__JSRuntime_H__
//-----------------------------END FILE--------------------------------
@@ -0,0 +1,51 @@
/**
@file JSShaderActiveInfo.cpp
@brief
@author James
@version 1.0
@date 2018_3_27
*/
#include "JSShaderActiveInfo.h"
namespace laya
{
ADDJSCLSINFO(JSShaderActiveInfo, JSObjNode);
//------------------------------------------------------------------------------
JSShaderActiveInfo::JSShaderActiveInfo()
{
m_nType = m_nSize = 0;
AdjustAmountOfExternalAllocatedMemory( 64 );
JCMemorySurvey::GetInstance()->newClass( "JSShaderActiveInfo",64,this );
}
//------------------------------------------------------------------------------
JSShaderActiveInfo::~JSShaderActiveInfo()
{
JCMemorySurvey::GetInstance()->releaseClass( "JSShaderActiveInfo",this );
}
//------------------------------------------------------------------------------
int JSShaderActiveInfo::getType()
{
return m_nType;
}
int JSShaderActiveInfo::getSize()
{
return m_nSize;
}
const char* JSShaderActiveInfo::getName()
{
return m_sName.c_str();
}
void JSShaderActiveInfo::exportJS()
{
JSP_CLASS("shaderActiveInfo", JSShaderActiveInfo);
JSP_ADD_PROPERTY_RO(type, JSShaderActiveInfo, getType);
JSP_ADD_PROPERTY_RO(size, JSShaderActiveInfo, getSize);
JSP_ADD_PROPERTY_RO(name, JSShaderActiveInfo, getName);
JSP_INSTALL_CLASS("shaderActiveInfo", JSShaderActiveInfo);
}
}
//------------------------------------------------------------------------------
//-----------------------------END FILE--------------------------------

Some files were not shown because too many files have changed in this diff Show More