#include <ppapi/cpp/url_request_info.h>
#include <ppapi/cpp/dev/scriptable_object_deprecated.h>
#include <ppapi/cpp/var.h>
+#include <pthread.h>
#include <cassert>
#include <cmath>
#include <limits>
#include <sstream>
#include <iostream>
+#include <list>
#include "_mod.h"
#include "geturl_handler.h"
#include "boost/shared_ptr.hpp"
#include "boost/format.hpp"
+#include "zlib.h"
namespace {
+ const int kPthreadMutexSuccess = 0;
// XM ファイルのロード
const char* const kLoadXmFile = "loadXmFile";
// XM ファイルの再生コマンド文字列
const char* const kPlaySoundId = "playSound";
// XM ファイルの停止コマンド文字列
const char* const kStopSoundId = "stopSound";
-
-// システムにリクエストするサンプルカウント数
+ // メインスレッド以外のログを取得する
+ const char* const kGetLogId = "getLog";
+ //
+ const char* const kCheckLogId = "checkLog";
+ // システムにリクエストするサンプルカウント数
const uint32_t kSampleFrameCount = 4096u;
// 現在サポートしているのはステレオオーディオのみである。
const uint32_t kChannels = 2u;
} // namespace
namespace xm_player {
-class XmPlayerInstance;
+// A small helper RAII class that implementes a scoped pthread_mutex lock.
+class ScopedMutexLock {
+ public:
+ explicit ScopedMutexLock(pthread_mutex_t* mutex) : mutex_(mutex) {
+ if (pthread_mutex_lock(mutex_) != kPthreadMutexSuccess) {
+ mutex_ = NULL;
+ }
+ }
+ ~ScopedMutexLock() {
+ if (mutex_)
+ pthread_mutex_unlock(mutex_);
+ }
+ bool is_valid() const {
+ return mutex_ != NULL;
+ }
+ private:
+ pthread_mutex_t* mutex_; // Weak reference.
+};
+
+ class XmPlayerInstance;
// このクラスはNaClモジュールのためのスクリプティング・インターフェースである。
// HasMethodメソッドはXmPlayerオブジェクトのメソッドが呼び出され、実行される前にブラウザによって呼び出される。
// (詳細はxm_player.html内のmoduleDidLoad()関数を見ること。)
public:
explicit XmPlayerInstance(PP_Instance instance)
: pp::Instance(instance), scriptable_object_(NULL),
- sample_frame_count_(kSampleFrameCount) , mod_( MOD__Create()){}
+ sample_frame_count_(kSampleFrameCount) , mod_( MOD__Create(this))
+ {
+ pthread_mutex_init(&mutex_, NULL);
+ }
virtual ~XmPlayerInstance()
{
MOD__Destruct(mod_);
virtual pp::Var GetInstanceObject() {
scriptable_object_ =
new XmPlayerScriptableObject(*this);
+
return pp::Var(this, scriptable_object_);
}
if(MOD__LoadSong(mod_,&(load_data_[0]),load_data_.size()) > 0 ){
MOD__InitPlay(mod_);
audio_.StartPlayback();
- pp::Var window = this->GetWindowObject();
- // calls JavaScript function reportResult(url, result, success)
- // defined in geturl.html.
- pp::Var exception;
- window.Call("reportResult", std::string("play()"), std::string("Play Start!!"), true, &exception);
+ SendLog("started.");
} else {
- pp::Var window = this->GetWindowObject();
- // calls JavaScript function reportResult(url, result, success)
- // defined in geturl.html.
- pp::Var exception;
- window.Call("reportResult", std::string("play()"), std::string("Load Error"), false, &exception);
+ SendLog("Load Error.");
};
}
void stop()
{
audio_.StopPlayback();
+ SendLog("stopped.");
}
std::vector<char> & GetLoadData(){return load_data_;}
+ void WriteLog(const char * log)
+ {
+ ScopedMutexLock lock(&mutex_);
+ log_.push_back(log);
+ }
+
+ bool CheckLog()
+ {
+ return !log_.empty();
+ }
+
+ std::string GetLog()
+ {
+ if(log_.empty())
+ {
+ return "";
+ }
+ std::string ret(log_.front());
+ {
+ ScopedMutexLock lock(&mutex_);
+ log_.pop_front();
+ }
+ return ret;
+ };
+ void SendLog(const std::string& log)
+ {
+ pp::Var window(GetWindowObject());
+ pp::Var exception;
+ window.Call("reportLog",log, &exception);
+ }
private:
static void XmPlayerCallback(void* samples, size_t buffer_size, void* data) {
XmPlayerInstance* xm_player_instance =
// MOD構造体へのポインタ
::MOD * mod_;
std::vector<char> load_data_;
+ std::list<std::string> log_;
+ pthread_mutex_t mutex_;
};
// The Module class. The browser calls the CreateInstance() method to create
} else if(method_name == kLoadXmFile ){
if ((args.size() >= 1) && args[0].is_string()) {
std::string url = args[0].AsString();
- printf("GetURLScriptableObject::Call('%s'', '%s'')\n",
- method_name.c_str(),
- url.c_str());
- fflush(stdout);
+ player_.SendLog((boost::format("GetURLScriptableObject::Call('%s'', '%s'')\n") %
+ method_name %
+ url).str());
return pp::Var(LoadXmFile(url));
} else {
*exception = std::string("") + method_name;
}
+ } else if(method_name == kGetLogId) {
+ return pp::Var(player_.GetLog());
+ } else if(method_name == kCheckLogId) {
+ return pp::Var(player_.CheckLog());
} else {
*exception = std::string("No method named ") + method_name;
}
}
const std::string method_name = method.AsString();
const bool has_method = method_name == kPlaySoundId ||
- method_name == kStopSoundId || method_name == kLoadXmFile;
+ method_name == kStopSoundId || method_name == kLoadXmFile ||
+ method_name == kGetLogId || method_name == kCheckLogId
+ ;
return has_method;
}
}
} // namespace xm_player
+void LogMsg (void* instance,const char* format,...)
+{
+ va_list ap;
+ va_start(ap,format);
+ char buf[4096];
+ vsnprintf(buf,sizeof(buf),format,ap);
+ va_end(ap);
+
+ //pp::Instance * inst = pp::Module::Get()->InstanceForPPInstance(instance);
+ xm_player::XmPlayerInstance * inst = reinterpret_cast<xm_player::XmPlayerInstance*>(instance);
+ inst->WriteLog(buf);
+ // pp::Var window(inst->GetWindowObject());
+ //window.is_int();
+ //pp::Var exception;
+ //window.Call("reportLog",std::string(buf), &exception);
+};
+
+
// Factory function called by the browser when the module is first loaded.
// The browser keeps a singleton of this module. It calls the
// CreateInstance() method on the object you return to make instances. There
return new xm_player::XmPlayerModule();
}
} // namespace pp
+
+