Index: experimental/flocking_geese/nacl_app/flocking_geese_app.cc |
diff --git a/experimental/flocking_geese/nacl_app/flocking_geese_app.cc b/experimental/flocking_geese/nacl_app/flocking_geese_app.cc |
deleted file mode 100644 |
index b09ad9f2535ea5fa771eb610673c8e721620135c..0000000000000000000000000000000000000000 |
--- a/experimental/flocking_geese/nacl_app/flocking_geese_app.cc |
+++ /dev/null |
@@ -1,297 +0,0 @@ |
-// Copyright (c) 2011 The Native Client Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-#include "flocking_geese_app.h" |
- |
-#include <algorithm> |
-#include <sstream> |
-#include <string> |
-#include "nacl_app/scoped_pixel_lock.h" |
-#include "ppapi/c/pp_errors.h" |
-#include "ppapi/cpp/completion_callback.h" |
-#include "ppapi/cpp/module.h" |
-#include "threading/scoped_mutex_lock.h" |
-#include "url_io/url_request.h" |
-#include "url_io/web_resource_loader.h" |
- |
-namespace { |
-// Input method and parameter Ids. These correspond to C++ calls. |
-const char* const kResetFlockMethodId = "resetFlock"; |
-const char* const kRunSimulationMethodId = "runSimulation"; |
-const char* const kPauseSimulationMethodId = "pauseSimulation"; |
-const char* const kSetAttractorLocMethodId = "setAttractorLocation"; |
- |
-// Output method and parameter Ids. These correspond to methods in the |
-// browser. |
-const char* const kSetSimulationInfoMethodId = "setSimulationInfo"; |
-const char* const kFrameRateParamId = "frameRate"; |
- |
-const int kSimulationTickInterval = 10; // Measured in msec. |
-const uint32_t kBackgroundColor = 0xFFFFFFFF; // Opaque white. |
- |
-// Return the value of parameter named |param_name| from |parameters|. If |
-// |param_name| doesn't exist, then return an empty string. |
-std::string GetParameterNamed( |
- const std::string& param_name, |
- const scripting::MethodParameter& parameters) { |
- scripting::MethodParameter::const_iterator i = |
- parameters.find(param_name); |
- if (i == parameters.end()) { |
- return ""; |
- } |
- return i->second; |
-} |
- |
-// Return the int32_t equivalent of |str|. All the usual C++ rounding rules |
-// apply. |
-int32_t StringAsInt32(const std::string& str) { |
- std::istringstream cvt_stream(str); |
- double double_val; |
- cvt_stream >> double_val; |
- return static_cast<int32_t>(double_val); |
-} |
- |
-// Called from the browser when the delay time has elapsed. This routine |
-// runs a simulation update, then reschedules itself to run the next |
-// simulation tick. |
-void SimulationTickCallback(void* data, int32_t result) { |
- flocking_geese::FlockingGeeseApp* geese_app = |
- static_cast<flocking_geese::FlockingGeeseApp*>(data); |
- // Flush the graphics so far and post the current frame rate. |
- geese_app->PostSimulationInfo(); |
- geese_app->Update(); |
- if (geese_app->is_running()) { |
- pp::Module::Get()->core()->CallOnMainThread( |
- kSimulationTickInterval, |
- pp::CompletionCallback(&SimulationTickCallback, data), |
- PP_OK); |
- } |
-} |
- |
-// Called from the browser when the 2D graphics have been flushed out to the |
-// device. |
-void FlushCallback(void* data, int32_t result) { |
- static_cast<flocking_geese::FlockingGeeseApp*>(data)-> |
- set_flush_pending(false); |
-} |
-} // namespace |
- |
-using scripting::ScriptingBridge; |
- |
-namespace flocking_geese { |
- |
-FlockingGeeseApp::FlockingGeeseApp(PP_Instance instance) |
- : pp::Instance(instance), |
- graphics_2d_context_(NULL), |
- flush_pending_(false), |
- view_changed_size_(true) { |
-} |
- |
-FlockingGeeseApp::~FlockingGeeseApp() { |
- flock_simulation_.set_is_simulation_running(false); |
- DestroyContext(); |
-} |
- |
-bool FlockingGeeseApp::Init(uint32_t /* argc */, |
- const char* /* argn */[], |
- const char* /* argv */[]) { |
- // Add all the methods to the scripting bridge. |
- ScriptingBridge::SharedMethodCallbackExecutor |
- reset_flock_method(new scripting::MethodCallback<FlockingGeeseApp>( |
- this, &FlockingGeeseApp::ResetFlock)); |
- scripting_bridge_.AddMethodNamed(kResetFlockMethodId, reset_flock_method); |
- |
- ScriptingBridge::SharedMethodCallbackExecutor |
- run_sim_method(new scripting::MethodCallback<FlockingGeeseApp>( |
- this, &FlockingGeeseApp::RunSimulation)); |
- scripting_bridge_.AddMethodNamed(kRunSimulationMethodId, run_sim_method); |
- |
- ScriptingBridge::SharedMethodCallbackExecutor |
- pause_sim_method(new scripting::MethodCallback<FlockingGeeseApp>( |
- this, &FlockingGeeseApp::PauseSimulation)); |
- scripting_bridge_.AddMethodNamed(kPauseSimulationMethodId, pause_sim_method); |
- |
- ScriptingBridge::SharedMethodCallbackExecutor |
- set_attractor_method(new scripting::MethodCallback<FlockingGeeseApp>( |
- this, &FlockingGeeseApp::SetAttractorLocation)); |
- scripting_bridge_.AddMethodNamed(kSetAttractorLocMethodId, |
- set_attractor_method); |
- |
- // Load the goose sprite. |sprite_loader| is deleted by its delegate when |
- // the download is complete (or gets an error). The PNG data is checked for |
- // validity at each Update(); when the PNG data has all arrived, the sprite |
- // can be used for drawing. |
- url_io::WebResourceLoader* sprite_loader = |
- new url_io::WebResourceLoader(this, &png_loader_); |
- url_io::URLRequest request("images/Flock32_Green.png"); |
- sprite_loader->LoadURL(request); |
- |
- flock_simulation_.StartSimulation(); |
- return true; |
-} |
- |
-void FlockingGeeseApp::DidChangeView(const pp::Rect& position, |
- const pp::Rect& /* clip */) { |
- if (position.size().width() == width() && |
- position.size().height() == height()) |
- return; // Size didn't change, no need to update anything. |
- // Indicate that all the buffers need to be resized at the next Update() |
- // call. |
- view_changed_size_ = true; |
- view_size_ = position.size(); |
- // Make sure the buffers get changed if the simulation isn't running. |
- if (!is_running()) |
- Update(); |
-} |
- |
-void FlockingGeeseApp::HandleMessage(const pp::Var& var_message) { |
- if (!var_message.is_string()) |
- return; |
- scripting_bridge_.InvokeMethod(var_message.AsString()); |
-} |
- |
-void FlockingGeeseApp::ResetFlock( |
- const scripting::ScriptingBridge& bridge, |
- const scripting::MethodParameter& parameters) { |
- std::string flock_size_str = GetParameterNamed("size", parameters); |
- if (flock_size_str.length()) { |
- Flock::SimulationMode sim_mode = flock_simulation_.simulation_mode(); |
- flock_simulation_.set_simulation_mode(flocking_geese::Flock::kPaused); |
- size_t flock_size = static_cast<size_t>(StringAsInt32(flock_size_str)); |
- Vector2 initialLocation(view_size_.width(), view_size_.height()); |
- initialLocation.Scale(0.5); |
- flock_simulation_.ResetFlock(flock_size, initialLocation); |
- flock_simulation_.set_simulation_mode(sim_mode); |
- } |
-} |
- |
-void FlockingGeeseApp::RunSimulation( |
- const scripting::ScriptingBridge& bridge, |
- const scripting::MethodParameter& parameters) { |
- flock_simulation_.set_simulation_mode(flocking_geese::Flock::kRunning); |
- // Schedule a simulation tick to get things going. |
- pp::Module::Get()->core()->CallOnMainThread( |
- kSimulationTickInterval, |
- pp::CompletionCallback(&SimulationTickCallback, this), |
- PP_OK); |
-} |
- |
-void FlockingGeeseApp::PauseSimulation( |
- const scripting::ScriptingBridge& bridge, |
- const scripting::MethodParameter& parameters) { |
- flock_simulation_.set_simulation_mode(flocking_geese::Flock::kPaused); |
-} |
- |
-void FlockingGeeseApp::SetAttractorLocation( |
- const scripting::ScriptingBridge& bridge, |
- const scripting::MethodParameter& parameters) { |
- std::string loc_x_str = GetParameterNamed("x", parameters); |
- std::string loc_y_str = GetParameterNamed("y", parameters); |
- if (loc_x_str.length() && loc_y_str.length()) { |
- Vector2 attractor_loc(StringAsInt32(loc_x_str), StringAsInt32(loc_y_str)); |
- flock_simulation_.SetAttractorAtIndex(attractor_loc, 0); |
- } |
-} |
- |
-void FlockingGeeseApp::PostSimulationInfo() { |
- double frame_rate = flock_simulation_.FrameRate(); |
- std::ostringstream method_invocation(std::ostringstream::out); |
- method_invocation << kSetSimulationInfoMethodId << " "; |
- method_invocation << kFrameRateParamId << ":" << frame_rate; |
- pp::Var var_message(method_invocation.str()); |
- PostMessage(var_message); |
-} |
- |
-void FlockingGeeseApp::Update() { |
- if (flush_pending()) |
- return; // Don't attempt to flush if one is pending. |
- |
- // See if the goose sprite is ready to be used. |
- if (png_loader_.is_valid() && !flock_simulation_.has_goose_sprite()) { |
- pp::Size pixel_buffer_size = png_loader_.png_image_size(); |
- uint32_t* pixel_buffer = |
- static_cast<uint32_t*>(malloc(pixel_buffer_size.width() * |
- pixel_buffer_size.height() * |
- sizeof(uint32_t))); |
- png_loader_.FillPixelBuffer(pixel_buffer); |
- flock_simulation_.set_goose_sprite( |
- new Sprite(pixel_buffer, png_loader_.png_image_size(), 0)); |
- } |
- |
- if (view_changed_size_) { |
- // Delete the old pixel buffer and create a new one. |
- // Pause the simulation before changing all the buffer sizes. |
- Flock::SimulationMode sim_mode = flock_simulation_.simulation_mode(); |
- flock_simulation_.set_simulation_mode(flocking_geese::Flock::kPaused); |
- // Create a new device context with the new size. |
- // Note: DestroyContext() releases the simulation's copy of the shared |
- // pixel buffer. *This has to happen before the reset() below!* If the |
- // simulation's copy of hte shared pointer is released last, then the |
- // underlying ImageData is released off the main thread, which is not |
- // supported in Pepper. |
- DestroyContext(); |
- CreateContext(view_size_); |
- threading::ScopedMutexLock scoped_mutex( |
- flock_simulation_.simulation_mutex()); |
- if (!scoped_mutex.is_valid()) |
- // This potentially leaves the simulation in a paused state, but getting |
- // here means something is very wrong and the simulation probably can't |
- // run anyways. |
- return; |
- if (graphics_2d_context_ != NULL) { |
- shared_pixel_buffer_.reset( |
- new LockingImageData(this, |
- PP_IMAGEDATAFORMAT_BGRA_PREMUL, |
- graphics_2d_context_->size(), |
- false)); |
- set_flush_pending(false); |
- // Ok to get a non-locked version because the simulation is guraranteed |
- // to be paused here. |
- uint32_t* pixels = shared_pixel_buffer_->PixelBufferNoLock(); |
- if (pixels) { |
- const size_t size = width() * height(); |
- std::fill(pixels, pixels + size, kBackgroundColor); |
- } |
- flock_simulation_.Resize(pp::Size(width(), height())); |
- flock_simulation_.set_pixel_buffer(shared_pixel_buffer_); |
- flock_simulation_.set_simulation_mode(sim_mode); |
- } |
- view_changed_size_ = false; |
- } |
- flock_simulation_.Render(); |
- FlushPixelBuffer(); |
-} |
- |
-void FlockingGeeseApp::CreateContext(const pp::Size& size) { |
- if (IsContextValid()) |
- return; |
- graphics_2d_context_ = new pp::Graphics2D(this, size, false); |
- if (!BindGraphics(*graphics_2d_context_)) { |
- PostMessage("Couldn't bind the device context"); |
- } |
-} |
- |
-void FlockingGeeseApp::DestroyContext() { |
- threading::ScopedMutexLock scoped_mutex(flock_simulation_.simulation_mutex()); |
- if (!scoped_mutex.is_valid()) { |
- return; |
- } |
- ScopedPixelLock scoped_pixel_lock(shared_pixel_buffer_); |
- shared_pixel_buffer_.reset(); |
- flock_simulation_.set_pixel_buffer(shared_pixel_buffer_); |
- if (!IsContextValid()) |
- return; |
- delete graphics_2d_context_; |
- graphics_2d_context_ = NULL; |
-} |
- |
-void FlockingGeeseApp::FlushPixelBuffer() { |
- if (!IsContextValid() || shared_pixel_buffer_ == NULL) |
- return; |
- set_flush_pending(true); |
- graphics_2d_context_->PaintImageData(*shared_pixel_buffer_, pp::Point()); |
- graphics_2d_context_->Flush(pp::CompletionCallback(&FlushCallback, this)); |
-} |
-} // namespace flocking_geese |
- |