OLD | NEW |
| (Empty) |
1 // Copyright (c) 2011 The Native Client SDK Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can | |
3 // be found in the LICENSE file. | |
4 | |
5 /// @file | |
6 /// This example demonstrates loading, running and scripting a very simple NaCl | |
7 /// module. To load the NaCl module, the browser first looks for the | |
8 /// CreateModule() factory method (at the end of this file). It calls | |
9 /// CreateModule() once to load the module code from your .nexe. After the | |
10 /// .nexe code is loaded, CreateModule() is not called again. | |
11 /// | |
12 /// Once the .nexe code is loaded, the browser then calls the | |
13 /// HexGameModule::CreateInstance() | |
14 /// method on the object returned by CreateModule(). It calls CreateInstance() | |
15 /// each time it encounters an <embed> tag that references your NaCl module. | |
16 /// | |
17 | |
18 // C headers | |
19 #include <string.h> | |
20 | |
21 // C++ headers | |
22 #include <algorithm> | |
23 #include <cassert> | |
24 #include <cstdio> | |
25 #include <cstdlib> | |
26 #include <ctime> | |
27 #include <iostream> | |
28 #include <iterator> | |
29 #include <map> | |
30 #include <set> | |
31 #include <sstream> | |
32 #include <string> | |
33 #include <vector> | |
34 | |
35 #include "ppapi/cpp/completion_callback.h" | |
36 #include "ppapi/cpp/instance.h" | |
37 #include "ppapi/cpp/module.h" | |
38 #include "ppapi/cpp/var.h" | |
39 | |
40 #include "shared_queue.h" | |
41 #include "thread_condition.h" | |
42 | |
43 | |
44 namespace hexgame { | |
45 | |
46 struct UserMove { | |
47 UserMove(int c, int r) : column_(c), row_(r) {} | |
48 int column_; | |
49 int row_; | |
50 }; | |
51 void UpdateCallback(void* data, int32_t /*result*/); | |
52 | |
53 /// The Instance class. One of these exists for each instance of your NaCl | |
54 /// module on the web page. The browser will ask the Module object to create | |
55 /// a new Instance for each occurrence of the <embed> tag that has these | |
56 /// attributes: | |
57 /// <pre> | |
58 /// type="application/x-ppapi-nacl-srpc" | |
59 /// nexes="ARM: hello_world_arm.nexe | |
60 /// x86-32: hello_world_x86_32.nexe | |
61 /// x86-64: hello_world_x86_64.nexe" | |
62 /// </pre> | |
63 /// The Instance can return a subclass of pp::Instance. When the | |
64 /// browser encounters JavaScript that wants to access the Instance, it calls | |
65 /// the GetInstanceObject() method. | |
66 class HexGameInstance : public pp::Instance { | |
67 public: | |
68 explicit HexGameInstance(PP_Instance instance) : | |
69 pp::Instance(instance), compute_pi_thread_(0), cond_true_(false), | |
70 computer_wins_(false), user_wins_(false), last_move_was_invalid_(false), | |
71 game_loop_ready_(false), sent_game_loop_ready_(false) {} | |
72 virtual ~HexGameInstance() {} | |
73 | |
74 /// Called by the browser to handle the postMessage() call in Javascript. | |
75 /// Detects which method is being called from the message contents, and | |
76 /// calls the appropriate function. Posts the result back to the browser | |
77 /// asynchronously. | |
78 /// @param[in] var_message The message posted by the browser. | |
79 /// Currently, the only message is USERMOVE followed by row and then | |
80 /// by column. | |
81 virtual void HandleMessage(const pp::Var& var_message); | |
82 | |
83 virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]); | |
84 | |
85 // Return an event from the thread-safe queue, waiting for a new event | |
86 // to occur if the queue is empty. Set |was_queue_cancelled| to indicate | |
87 // whether the queue was cancelled. If it was cancelled, then the | |
88 const UserMove GetEventFromQueue(bool *was_queue_cancelled); | |
89 | |
90 void WaitForUserMove(uint32_t* user_col, uint32_t* user_row); | |
91 void GameOver(); | |
92 void SendStatusToBrowser(); | |
93 void SetComputerMove(uint32_t col, uint32_t row); | |
94 | |
95 // This indicates the game loop has initialized and is ready | |
96 // for the UI | |
97 void SetGameLoopReady() { game_loop_ready_ = true;} | |
98 | |
99 void SetComputerWins() { computer_wins_ = true;} | |
100 void SetUserWins() { user_wins_ = true;} | |
101 void SetValidMove() { last_move_was_invalid_ = false; } | |
102 void SetInvalidMove() { last_move_was_invalid_ = true; } | |
103 | |
104 private: | |
105 pthread_t compute_pi_thread_; | |
106 c_salt::threading::ThreadCondition thread_condition_; | |
107 bool cond_true_; | |
108 | |
109 LockingQueue<UserMove> event_queue_; | |
110 | |
111 uint32_t user_column_, user_row_; | |
112 uint32_t computer_column_, computer_row_; | |
113 bool computer_wins_; | |
114 bool user_wins_; | |
115 bool last_move_was_invalid_; | |
116 bool game_loop_ready_; | |
117 bool sent_game_loop_ready_; | |
118 }; | |
119 | |
120 /// The Module class. The browser calls the CreateInstance() method to create | |
121 /// an instance of you NaCl module on the web page. The browser creates a new | |
122 /// instance for each <embed> tag with | |
123 /// <code>type="application/x-ppapi-nacl-srpc"</code>. | |
124 class HexGameModule : public pp::Module { | |
125 public: | |
126 HexGameModule() : pp::Module() {} | |
127 virtual ~HexGameModule() {} | |
128 | |
129 /// Create and return a HexGameInstance object. | |
130 /// @param instance [in] a handle to a plug-in instance. | |
131 /// @return a newly created HexGameInstance. | |
132 /// @note The browser is responsible for calling @a delete when done. | |
133 virtual pp::Instance* CreateInstance(PP_Instance instance) { | |
134 return new HexGameInstance(instance); | |
135 } | |
136 }; | |
137 | |
138 } // namespace | |
139 | |
OLD | NEW |