├── .gitignore ├── README.md ├── client ├── application.dart ├── application.html ├── game_pad.dart ├── game_pad_view.dart ├── images │ ├── a.png │ ├── b.png │ ├── background.png │ ├── controller.png │ ├── dart.png │ ├── left_thumb.png │ ├── player_1.png │ ├── player_2.png │ ├── player_3.png │ ├── player_4.png │ ├── right_thumb.png │ ├── status.png │ ├── x.png │ └── y.png ├── style.css └── ui_elements.dart ├── server ├── DartEmbed.sln ├── DartEmbed.vcxproj ├── DartEmbed.vcxproj.filters ├── DartEmbed │ ├── GamePad.hpp │ ├── Isolate.hpp │ └── VirtualMachine.hpp ├── lib │ ├── Debug │ │ ├── libdart_aux.lib │ │ ├── libdart_builtin.lib │ │ ├── libdart_export.lib │ │ ├── libdart_lib.lib │ │ ├── libdart_vm.lib │ │ ├── libdouble_conversion.lib │ │ └── libjscre.lib │ └── Release │ │ ├── libdart_aux.lib │ │ ├── libdart_builtin.lib │ │ ├── libdart_export.lib │ │ ├── libdart_lib.lib │ │ ├── libdart_vm.lib │ │ ├── libdouble_conversion.lib │ │ └── libjscre.lib ├── server.dart └── src │ ├── Arguments.hpp │ ├── BuiltinLibraries.cpp │ ├── BuiltinLibraries.hpp │ ├── CoreLibrary.cpp │ ├── EmbedLibraries.hpp │ ├── GamePad.cpp │ ├── IOLibrary.cpp │ ├── InputLibrary.cpp │ ├── Isolate.cpp │ ├── NativeResolution.hpp │ ├── PlatformWindows.hpp │ ├── ScriptLibrary.cpp │ ├── ScriptLibrary.hpp │ ├── dart_api.h │ ├── isolate_data.h │ └── main.cpp └── test ├── game_pad.dart └── test_server.dart /.gitignore: -------------------------------------------------------------------------------- 1 | # Visual Studio Files 2 | *.sdf 3 | *.suo 4 | *.user 5 | 6 | # Visual Studio Directories 7 | server/Debug 8 | server/Release 9 | ipch 10 | 11 | # Eclipse Files 12 | .children 13 | .project 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | DartEmbeddingDemo 2 | ================= 3 | 4 | Example of embedding Dart in a windows application -------------------------------------------------------------------------------- /client/application.dart: -------------------------------------------------------------------------------- 1 | /** 2 | * Dart Embedding Example 3 | * 4 | * --------------------------------------------------------------------- 5 | * 6 | * Copyright (c) 2012 Don Olmstead 7 | * 8 | * This software is provided 'as-is', without any express or implied 9 | * warranty. In no event will the authors be held liable for any damages 10 | * arising from the use of this software. 11 | * 12 | * Permission is granted to anyone to use this software for any purpose, 13 | * including commercial applications, and to alter it and redistribute it 14 | * freely, subject to the following restrictions: 15 | * 16 | * 1. The origin of this software must not be misrepresented; you must not 17 | * claim that you wrote the original software. If you use this software 18 | * in a product, an acknowledgment in the product documentation would be 19 | * appreciated but is not required. 20 | * 21 | * 2. Altered source versions must be plainly marked as such, and must not be 22 | * misrepresented as being the original software. 23 | * 24 | * 3. This notice may not be removed or altered from any source 25 | * distribution. 26 | */ 27 | 28 | #import('dart:html'); 29 | #import('dart:json'); 30 | #source('game_pad.dart'); 31 | #source('game_pad_view.dart'); 32 | #source('ui_elements.dart'); 33 | 34 | class Application 35 | { 36 | /// Whether the server has been connected to. 37 | bool _connected; 38 | /// Error message 39 | ErrorMessage _errorMessage; 40 | /// Element containing the url to connect to. 41 | InputElement _url; 42 | /// Button to initiate the server connection. 43 | InputElement _connectButton; 44 | /// Status indicator for the server connection. 45 | ConnectionStatusIndicator _statusIndicator; 46 | /// The currently selected tab. 47 | Element _selectedTab; 48 | /// Canvas that the game pad's state is displayed on. 49 | GamePadView _gamePadCanvas; 50 | /// Vibration controls 51 | VibrationControls _vibrationControls; 52 | 53 | //--------------------------------------------------------------------- 54 | // Initialization 55 | //--------------------------------------------------------------------- 56 | 57 | Application() 58 | { 59 | _connected = false; 60 | 61 | // Create the error message 62 | _errorMessage = new ErrorMessage('#errorMessage'); 63 | 64 | // Setup the gamepad canvas 65 | _gamePadCanvas = new GamePadView('#gamepad'); 66 | 67 | // Setup the tabbed UI 68 | _selectedTab = document.query('#player1'); 69 | _setupTab('#player1', 0); 70 | _setupTab('#player2', 1); 71 | _setupTab('#player3', 2); 72 | _setupTab('#player4', 3); 73 | 74 | // Setup the connection button 75 | _connectButton = document.query('#connect'); 76 | _connectButton.on.click.add(_onButtonClicked); 77 | _url = document.query('#url'); 78 | 79 | // Setup the status indicator 80 | _statusIndicator = new ConnectionStatusIndicator('#status'); 81 | 82 | // Setup the vibration controls 83 | _vibrationControls = new VibrationControls('#leftMotor', '#rightMotor'); 84 | } 85 | 86 | void _setupTab(String id, int index) 87 | { 88 | Element tab = document.query(id); 89 | 90 | tab.on.click.add((e) { 91 | // Remove the selected class 92 | _selectedTab.classes.remove('selected'); 93 | 94 | // Set the tab as selected 95 | tab.classes.add('selected'); 96 | _selectedTab = tab; 97 | 98 | // Notify that the tab was clicked 99 | _onTabClicked(index); 100 | }); 101 | } 102 | 103 | //--------------------------------------------------------------------- 104 | // Update methods 105 | //--------------------------------------------------------------------- 106 | 107 | void update() 108 | { 109 | _gamePadCanvas.update(); 110 | } 111 | 112 | //--------------------------------------------------------------------- 113 | // Connection methods 114 | //--------------------------------------------------------------------- 115 | 116 | /** 117 | * Callback to initiate/terminate the server connection. 118 | */ 119 | void _onButtonClicked(_) 120 | { 121 | if (_connected) 122 | { 123 | // Close the connection 124 | // UI will be updated in the close callbck 125 | GamePad.disconnectFromServer(); 126 | } 127 | else 128 | { 129 | // Initiate the connection 130 | GamePad.connectToServer(_url.value, _onConnectionOpened, _onConnectionClosed); 131 | 132 | // Update the UI 133 | _onConnectionInitiated(); 134 | } 135 | } 136 | 137 | /** 138 | * Callback for when the server connection is initiated. 139 | */ 140 | void _onConnectionInitiated() 141 | { 142 | // Disble the button 143 | _connectButton.disabled = true; 144 | 145 | // Hide the error message 146 | _errorMessage.hideError(); 147 | 148 | // Disble the url field 149 | _url.disabled = true; 150 | 151 | // Change the status indicator 152 | _statusIndicator.status = ConnectionStatus.Connecting; 153 | } 154 | 155 | /** 156 | * Callback for when the server connection is opened. 157 | */ 158 | void _onConnectionOpened(_) 159 | { 160 | // Connection was opened 161 | _connected = true; 162 | 163 | // Change the button to disconnect 164 | _connectButton.disabled = false; 165 | _connectButton.value = 'Disconnect'; 166 | _connectButton.classes.clear(); 167 | _connectButton.classes.add('disconnect'); 168 | 169 | // Change the status indicator 170 | _statusIndicator.status = ConnectionStatus.Connected; 171 | 172 | // Enable vibration controls 173 | _vibrationControls.enabled = true; 174 | } 175 | 176 | /** 177 | * Callback for when the server connection is closed. 178 | */ 179 | void _onConnectionClosed(CloseEvent e) 180 | { 181 | // Check for an abnomal close 182 | if (e.code == 1006) 183 | { 184 | String message = _connected ? "Server connection was lost" : "Could not connect to server"; 185 | 186 | _errorMessage.showError(message); 187 | } 188 | 189 | // Connection was closed 190 | _connected = false; 191 | 192 | // Enable the url field 193 | _url.disabled = false; 194 | 195 | // Change the button to connect 196 | _connectButton.disabled = false; 197 | _connectButton.value = 'Connect'; 198 | _connectButton.classes.clear(); 199 | _connectButton.classes.add('connect'); 200 | 201 | // Change the status indicator 202 | _statusIndicator.status = ConnectionStatus.Disconnected; 203 | 204 | // Disable vibration controls 205 | _vibrationControls.reset(); 206 | _vibrationControls.enabled = false; 207 | } 208 | 209 | //--------------------------------------------------------------------- 210 | // Tab methods 211 | //--------------------------------------------------------------------- 212 | 213 | /** 214 | * Callback for when a tab is selected. 215 | */ 216 | void _onTabClicked(int index) 217 | { 218 | _gamePadCanvas.playerIndex = index; 219 | _vibrationControls.playerIndex = index; 220 | } 221 | } 222 | 223 | /// The application 224 | Application _application; 225 | 226 | /** 227 | * Updates the canvas. 228 | */ 229 | bool update(int time) 230 | { 231 | _application.update(); 232 | 233 | window.requestAnimationFrame(update); 234 | } 235 | 236 | void main() 237 | { 238 | // Setup the gamepad class 239 | GamePad.onInitialize(); 240 | 241 | // Setup the application 242 | _application = new Application(); 243 | 244 | // Start the canvas animation 245 | window.requestAnimationFrame(update); 246 | } 247 | -------------------------------------------------------------------------------- /client/application.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Dart Embedding Example: Game Pad 7 | 8 | 9 | 10 | 11 | 12 |
Could not connect
13 |
14 | 15 |
16 | 17 |
18 |
19 |
20 | 26 |
27 |
28 |
29 |
30 |
31 | 32 |
33 |
Show raw values
34 | 38 | 42 | 47 | 52 |
53 |
54 |
Vibration
55 |
56 |
57 |
Left Motor: 0.000
58 | 59 |
60 |
61 |
Right Motor: 0.000
62 | 63 |
64 |
65 |
66 | 70 |
71 |
72 |
73 | 74 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /client/game_pad.dart: -------------------------------------------------------------------------------- 1 | /** 2 | * Dart Embedding Example 3 | * 4 | * --------------------------------------------------------------------- 5 | * 6 | * Copyright (c) 2012 Don Olmstead 7 | * 8 | * This software is provided 'as-is', without any express or implied 9 | * warranty. In no event will the authors be held liable for any damages 10 | * arising from the use of this software. 11 | * 12 | * Permission is granted to anyone to use this software for any purpose, 13 | * including commercial applications, and to alter it and redistribute it 14 | * freely, subject to the following restrictions: 15 | * 16 | * 1. The origin of this software must not be misrepresented; you must not 17 | * claim that you wrote the original software. If you use this software 18 | * in a product, an acknowledgment in the product documentation would be 19 | * appreciated but is not required. 20 | * 21 | * 2. Altered source versions must be plainly marked as such, and must not be 22 | * misrepresented as being the original software. 23 | * 24 | * 3. This notice may not be removed or altered from any source 25 | * distribution. 26 | */ 27 | 28 | class Vector2D implements Point 29 | { 30 | num x; 31 | num y; 32 | 33 | Vector2D(this.x, this.y); 34 | 35 | void cloneTo(Vector2D copy) 36 | { 37 | copy.x = x; 38 | copy.y = y; 39 | } 40 | 41 | void setValues(num xValue, num yValue) 42 | { 43 | x = xValue; 44 | y = yValue; 45 | } 46 | } 47 | 48 | class GamePadState 49 | { 50 | static final int _dPadUp = 1 << 0; 51 | static final int _dPadDown = 1 << 1; 52 | static final int _dPadLeft = 1 << 2; 53 | static final int _dPadRight = 1 << 3; 54 | static final int _start = 1 << 4; 55 | static final int _back = 1 << 5; 56 | static final int _leftThumb = 1 << 6; 57 | static final int _rightThumb = 1 << 7; 58 | static final int _leftShoulder = 1 << 8; 59 | static final int _rightShoulder = 1 << 9; 60 | static final int _aButton = 1 << 12; 61 | static final int _bButton = 1 << 13; 62 | static final int _xButton = 1 << 14; 63 | static final int _yButton = 1 << 15; 64 | 65 | /// Whether the controller is connected 66 | bool _connected; 67 | /// The state of the left thumbstick 68 | Vector2D _leftThumbstick; 69 | /// The state of the right thumbstick 70 | Vector2D _rightThumbstick; 71 | /// The state of the left trigger 72 | double _leftTrigger; 73 | /// The state of the right trigger 74 | double _rightTrigger; 75 | /// The state of the buttons 76 | int _buttons; 77 | 78 | GamePadState() 79 | : _connected = false 80 | , _leftThumbstick = new Vector2D(0, 0) 81 | , _rightThumbstick = new Vector2D(0, 0) 82 | , _leftTrigger = 0.0 83 | , _rightTrigger = 0.0 84 | , _buttons = 0; 85 | 86 | bool get isConnected => _connected; 87 | bool get up => _isFlagSet(_dPadUp); 88 | bool get down => _isFlagSet(_dPadDown); 89 | bool get left => _isFlagSet(_dPadLeft); 90 | bool get right => _isFlagSet(_dPadRight); 91 | bool get back => _isFlagSet(_back); 92 | bool get start => _isFlagSet(_start); 93 | bool get leftShoulder => _isFlagSet(_leftShoulder); 94 | bool get rightShoulder => _isFlagSet(_rightShoulder); 95 | bool get leftStick => _isFlagSet(_leftThumb); 96 | bool get rightStick => _isFlagSet(_rightThumb); 97 | bool get x => _isFlagSet(_xButton); 98 | bool get y => _isFlagSet(_yButton); 99 | bool get a => _isFlagSet(_aButton); 100 | bool get b => _isFlagSet(_bButton); 101 | 102 | double get leftTrigger => _leftTrigger; 103 | double get rightTrigger => _rightTrigger; 104 | Vector2D get leftThumbstick => _leftThumbstick; 105 | Vector2D get rightThumbstick => _rightThumbstick; 106 | 107 | void cloneTo(GamePadState state) 108 | { 109 | state._connected = _connected; 110 | state._buttons = _buttons; 111 | state._leftTrigger = _leftTrigger; 112 | state._rightTrigger = _rightTrigger; 113 | 114 | _leftThumbstick.cloneTo(state._leftThumbstick); 115 | _rightThumbstick.cloneTo(state._rightThumbstick); 116 | } 117 | 118 | void reset() 119 | { 120 | _connected = false; 121 | _buttons = 0; 122 | _leftTrigger = 0.0; 123 | _rightTrigger = 0.0; 124 | 125 | _leftThumbstick.setValues(0.0, 0.0); 126 | _rightThumbstick.setValues(0.0, 0.0); 127 | } 128 | 129 | bool _isFlagSet(int flag) 130 | { 131 | return (_buttons & flag) == flag; 132 | } 133 | } 134 | 135 | class GamePad 136 | { 137 | /// The port to connect on 138 | static final int _port = 8000; 139 | /// Socket connection to the server 140 | static WebSocket _connection; 141 | /// Whether the connection has been made 142 | static bool _connected; 143 | /// List of game pads 144 | static List _gamePads; 145 | /// The last requested player index 146 | static int _playerIndex; 147 | 148 | static bool get isConnected => _connected; 149 | 150 | static void onInitialize() 151 | { 152 | _gamePads = new List(); 153 | _gamePads.add(new GamePadState()); 154 | _gamePads.add(new GamePadState()); 155 | _gamePads.add(new GamePadState()); 156 | _gamePads.add(new GamePadState()); 157 | 158 | _connected = false; 159 | _playerIndex = -1; 160 | } 161 | 162 | static void getState(int index, GamePadState state) 163 | { 164 | if ((_connection != null) && (_connected)) 165 | { 166 | // See if a new index is being requested 167 | // If so notify the server 168 | if (_playerIndex != index) 169 | { 170 | String message = '{ "type": "index", "index": $index }'; 171 | 172 | _connection.send(message); 173 | 174 | _playerIndex = index; 175 | } 176 | } 177 | 178 | _gamePads[index].cloneTo(state); 179 | } 180 | 181 | static void setVibration(int index, double leftMotor, double rightMotor) 182 | { 183 | if ((_connection != null) && (_connected)) 184 | { 185 | String message = '{ "type": "vibration", "index": $index, "leftMotor": $leftMotor, "rightMotor": $rightMotor }'; 186 | 187 | _connection.send(message); 188 | } 189 | } 190 | 191 | static void connectToServer(String ip, EventListener onOpen, EventListener onClose) 192 | { 193 | if (_connection != null) 194 | disconnectFromServer; 195 | 196 | // Setup the connection 197 | _connection = new WebSocket('ws://$ip:$_port/ws'); 198 | 199 | // Connect to the open event 200 | _connection.on.open.add((e) { 201 | print("Connected!"); 202 | _connected = true; 203 | }); 204 | 205 | _connection.on.open.add(onOpen); 206 | 207 | // Connect to the close event 208 | _connection.on.close.add((CloseEvent e) { 209 | print("Disconnected! ${e.code} ${e.reason}"); 210 | _connected = false; 211 | _playerIndex = -1; 212 | 213 | for (GamePadState gamePad in _gamePads) 214 | gamePad.reset(); 215 | }); 216 | 217 | _connection.on.close.add(onClose); 218 | 219 | // Receive the game pad updates 220 | _connection.on.message.add((MessageEvent e) { 221 | _receiveMessage(e.data); 222 | }); 223 | } 224 | 225 | static void disconnectFromServer() 226 | { 227 | if (_connection != null) 228 | { 229 | _connection.close(); 230 | _connection = null; 231 | } 232 | } 233 | 234 | static void _receiveMessage(String message) 235 | { 236 | Map json = JSON.parse(message); 237 | 238 | int index = json['index']; 239 | GamePadState gamePad = _gamePads[index]; 240 | 241 | gamePad._connected = json['connected']; 242 | gamePad._leftTrigger = json['leftTrigger']; 243 | gamePad._rightTrigger = json['rightTrigger']; 244 | gamePad._buttons = json['buttons']; 245 | 246 | num x; 247 | num y; 248 | Map thumbstick; 249 | 250 | thumbstick = json['leftThumbstick']; 251 | x = thumbstick['x']; 252 | y = thumbstick['y']; 253 | gamePad._leftThumbstick.setValues(x, y); 254 | 255 | thumbstick = json['rightThumbstick']; 256 | x = thumbstick['x']; 257 | y = thumbstick['y']; 258 | gamePad._rightThumbstick.setValues(x, y); 259 | } 260 | } 261 | -------------------------------------------------------------------------------- /client/game_pad_view.dart: -------------------------------------------------------------------------------- 1 | /** 2 | * Dart Embedding Example 3 | * 4 | * --------------------------------------------------------------------- 5 | * 6 | * Copyright (c) 2012 Don Olmstead 7 | * 8 | * This software is provided 'as-is', without any express or implied 9 | * warranty. In no event will the authors be held liable for any damages 10 | * arising from the use of this software. 11 | * 12 | * Permission is granted to anyone to use this software for any purpose, 13 | * including commercial applications, and to alter it and redistribute it 14 | * freely, subject to the following restrictions: 15 | * 16 | * 1. The origin of this software must not be misrepresented; you must not 17 | * claim that you wrote the original software. If you use this software 18 | * in a product, an acknowledgment in the product documentation would be 19 | * appreciated but is not required. 20 | * 21 | * 2. Altered source versions must be plainly marked as such, and must not be 22 | * misrepresented as being the original software. 23 | * 24 | * 3. This notice may not be removed or altered from any source 25 | * distribution. 26 | */ 27 | 28 | class Point2D implements Point 29 | { 30 | /// The x position 31 | final num x; 32 | /// The y position 33 | final num y; 34 | 35 | const Point2D(num this.x, num this.y); 36 | } 37 | 38 | class GamePadView 39 | { 40 | //--------------------------------------------------------------------- 41 | // Class variables 42 | //--------------------------------------------------------------------- 43 | 44 | /// Position of the XBox 360 controller 45 | static final Point2D _controllerPosition = const Point2D(50, 10); 46 | /// Position of the XBox button 47 | static final Point2D _xBoxButtonPosition = const Point2D(351, 107); 48 | /// Position of the X button 49 | static final Point2D _xButtonPosition = const Point2D(542, 123); 50 | /// Position of the Y button 51 | static final Point2D _yButtonPosition = const Point2D(604, 60); 52 | /// Position of the A button 53 | static final Point2D _aButtonPosition = const Point2D(604, 186); 54 | /// Position of the B button 55 | static final Point2D _bButtonPosition = const Point2D(666, 122); 56 | /// Position of the start button 57 | static final Point2D _startButtonPosition = const Point2D(487, 154); 58 | /// Position of the back button 59 | static final Point2D _backButtonPosition = const Point2D(318, 154); 60 | /// Position of the left shoulder button 61 | static final Point2D _leftShoulderButtonPosition = const Point2D(166, 22); 62 | /// Position of the right shoulder button 63 | static final Point2D _rightShoulderButtonPosition = const Point2D(641, 22); 64 | /// Position of the d-pad up button 65 | static final Point2D _dPadUpButtonPosition = const Point2D(278, 249); 66 | /// Position of the d-pad down button 67 | static final Point2D _dPadDownButtonPosition = const Point2D(278, 338); 68 | /// Position of the d-pad left button 69 | static final Point2D _dPadLeftButtonPosition = const Point2D(232, 292); 70 | /// Position of the d-pad right button 71 | static final Point2D _dPadRightButtonPosition = const Point2D(323, 292); 72 | /// Position of the left thumbstick 73 | static final Point2D _leftThumbstickCenter = const Point2D(166, 151.5); 74 | /// Position of the right thumbstick 75 | static final Point2D _rightThumbstickCenter = const Point2D(514, 294.5); 76 | /// The radius of the thumbstick 77 | static final double _thumbstickRadius = 25.0; 78 | 79 | /// Position of the left trigger meter 80 | static final Point2D _leftTriggerMeterPosition = const Point2D(22, 110); 81 | /// Position of the right trigger meter 82 | static final Point2D _rightTriggerMeterPosition = const Point2D(849, 110); 83 | /// The border color for the meter 84 | static final String _meterStrokeStyle = 'rgba(255, 255, 255, 1.0)'; 85 | /// The meter color 86 | static final String _meterFillStyle = 'rgba(191, 191, 191, 1.0)'; 87 | /// The border thickness of the meter 88 | static final double _meterBorderThickness = 2.0; 89 | /// The width of the meter 90 | static final double _meterWidth = 29.0; 91 | /// The height of the meter 92 | static final double _meterHeight = 204.0; 93 | 94 | /// The color to use when drawing circles 95 | static final String _circleFillStyle = 'rgba(251, 239, 42, 0.75)'; 96 | 97 | //--------------------------------------------------------------------- 98 | // Member variables 99 | //--------------------------------------------------------------------- 100 | 101 | /// The canvas element 102 | CanvasElement _canvas; 103 | /// The rendering context 104 | CanvasRenderingContext2D _context; 105 | /// The index of the player being displayed 106 | int _playerIndex; 107 | /// State of the gamepad 108 | GamePadState _gamePadState; 109 | 110 | //--------------------------------------------------------------------- 111 | // Image variables 112 | //--------------------------------------------------------------------- 113 | 114 | /// Image of the XBox 360 controller 115 | ImageElement _controllerImage; 116 | /// Image of the left thumbstick 117 | ImageElement _leftThumbstickImage; 118 | /// Image of the right thumbstick 119 | ImageElement _rightThumbstickImage; 120 | /// Images for the player's connection 121 | List _playerImages; 122 | /// Image of the X button 123 | ImageElement _xButtonImage; 124 | /// Image of the Y button 125 | ImageElement _yButtonImage; 126 | /// Image of the A button 127 | ImageElement _aButtonImage; 128 | /// Image of the B button 129 | ImageElement _bButtonImage; 130 | 131 | //--------------------------------------------------------------------- 132 | // Overlay variables 133 | //--------------------------------------------------------------------- 134 | 135 | /// Container for the left trigger value. 136 | Element _leftTriggerElement; 137 | /// Value for the left trigger. 138 | Element _leftTriggerValue; 139 | /// Container for the right trigger value. 140 | Element _rightTriggerElement; 141 | /// Value for the right trigger. 142 | Element _rightTriggerValue; 143 | /// Container for the left thumbstick values. 144 | Element _leftThumbstickElement; 145 | /// X value for the left thumbstick. 146 | Element _leftThumbstickXValue; 147 | /// Y value for the left thumbstick. 148 | Element _leftThumbstickYValue; 149 | /// Container for the right thumbstick values. 150 | Element _rightThumbstickElement; 151 | /// X value for the right thumbstick. 152 | Element _rightThumbstickXValue; 153 | /// Y value for the right thumbstick. 154 | Element _rightThumbstickYValue; 155 | 156 | //--------------------------------------------------------------------- 157 | // Initialization 158 | //--------------------------------------------------------------------- 159 | 160 | GamePadView(String id) 161 | { 162 | _playerIndex = 0; 163 | _gamePadState = new GamePadState(); 164 | 165 | _canvas = document.query(id) as CanvasElement; 166 | assert(_canvas != null); 167 | 168 | _context = _canvas.getContext('2d'); 169 | assert(_context != null); 170 | 171 | _setupImages(); 172 | _setupOverlay(); 173 | } 174 | 175 | /** 176 | * Setup the game pad images. 177 | */ 178 | void _setupImages() 179 | { 180 | // Load the images 181 | _controllerImage = _loadImage('images/controller.png'); 182 | _leftThumbstickImage = _loadImage('images/left_thumb.png'); 183 | _rightThumbstickImage = _loadImage('images/right_thumb.png'); 184 | 185 | _xButtonImage = _loadImage('images/x.png'); 186 | _yButtonImage = _loadImage('images/y.png'); 187 | _aButtonImage = _loadImage('images/a.png'); 188 | _bButtonImage = _loadImage('images/b.png'); 189 | 190 | _playerImages = new List(); 191 | _playerImages.add(_loadImage('images/player_1.png')); 192 | _playerImages.add(_loadImage('images/player_2.png')); 193 | _playerImages.add(_loadImage('images/player_3.png')); 194 | _playerImages.add(_loadImage('images/player_4.png')); 195 | } 196 | 197 | /** 198 | * Setup the overlay. 199 | */ 200 | void _setupOverlay() 201 | { 202 | // Setup the trigger views 203 | _leftTriggerElement = document.query('#leftTrigger'); 204 | _rightTriggerElement = document.query('#rightTrigger'); 205 | 206 | _leftTriggerValue = _leftTriggerElement.query('.triggerValue'); 207 | _rightTriggerValue = _rightTriggerElement.query('.triggerValue'); 208 | 209 | // Setup the thumbstick views 210 | _leftThumbstickElement = document.query('#leftThumbstick'); 211 | _rightThumbstickElement = document.query('#rightThumbstick'); 212 | 213 | _leftThumbstickXValue = _leftThumbstickElement.query('.xValue'); 214 | _leftThumbstickYValue = _leftThumbstickElement.query('.yValue'); 215 | 216 | _rightThumbstickXValue = _rightThumbstickElement.query('.xValue'); 217 | _rightThumbstickYValue = _rightThumbstickElement.query('.yValue'); 218 | 219 | // Hook into the checkbox 220 | _setupCheckbox(); 221 | } 222 | 223 | void _setupCheckbox() 224 | { 225 | InputElement checkbox = document.query('#toggleValues'); 226 | 227 | checkbox.on.change.add((e) { 228 | String visible = checkbox.checked ? 'visible' : 'hidden'; 229 | 230 | _leftTriggerElement.style.visibility = visible; 231 | _rightTriggerElement.style.visibility = visible; 232 | 233 | _leftThumbstickElement.style.visibility = visible; 234 | _rightThumbstickElement.style.visibility = visible; 235 | }); 236 | } 237 | 238 | //--------------------------------------------------------------------- 239 | // Properties 240 | //--------------------------------------------------------------------- 241 | 242 | int get playerIndex => _playerIndex; 243 | set playerIndex(int value) { _playerIndex = value; } 244 | 245 | //--------------------------------------------------------------------- 246 | // Update methods 247 | //--------------------------------------------------------------------- 248 | 249 | void update() 250 | { 251 | // Get the game pad 252 | GamePad.getState(_playerIndex, _gamePadState); 253 | 254 | // Update the overlay 255 | _updateTriggerValues(_leftTriggerValue, _gamePadState.leftTrigger); 256 | _updateTriggerValues(_rightTriggerValue, _gamePadState.rightTrigger); 257 | 258 | _updateThumbstickValues(_leftThumbstickXValue, _leftThumbstickYValue, _gamePadState.leftThumbstick); 259 | _updateThumbstickValues(_rightThumbstickXValue, _rightThumbstickYValue, _gamePadState.rightThumbstick); 260 | 261 | // Draw the canvas 262 | draw(); 263 | } 264 | 265 | void _updateTriggerValues(Element element, double value) 266 | { 267 | element.innerHTML = value.toStringAsFixed(3); 268 | } 269 | 270 | void _updateThumbstickValues(Element xElement, Element yElement, Point value) 271 | { 272 | xElement.innerHTML = value.x.toStringAsFixed(3); 273 | yElement.innerHTML = value.y.toStringAsFixed(3); 274 | } 275 | 276 | //--------------------------------------------------------------------- 277 | // Drawing methods 278 | //--------------------------------------------------------------------- 279 | 280 | void draw() 281 | { 282 | _context.clearRect(0, 0, _canvas.width, _canvas.height); 283 | 284 | // Draw the game pad 285 | _context.drawImage(_controllerImage, _controllerPosition.x, _controllerPosition.y); 286 | 287 | // See if the game pad is connected 288 | if (_gamePadState.isConnected) 289 | { 290 | // Draw the connected image 291 | _drawImage(_playerImages[_playerIndex], _xBoxButtonPosition); 292 | 293 | // Draw the button images 294 | if (_gamePadState.x) 295 | _drawImage(_xButtonImage, _xButtonPosition); 296 | if (_gamePadState.y) 297 | _drawImage(_yButtonImage, _yButtonPosition); 298 | if (_gamePadState.a) 299 | _drawImage(_aButtonImage, _aButtonPosition); 300 | if (_gamePadState.b) 301 | _drawImage(_bButtonImage, _bButtonPosition); 302 | 303 | // Draw the start/back circles 304 | if (_gamePadState.start) 305 | _drawCircle(12, _startButtonPosition); 306 | if (_gamePadState.back) 307 | _drawCircle(12, _backButtonPosition); 308 | 309 | // Draw the shoulder circles 310 | if (_gamePadState.leftShoulder) 311 | _drawCircle(12, _leftShoulderButtonPosition); 312 | if (_gamePadState.rightShoulder) 313 | _drawCircle(12, _rightShoulderButtonPosition); 314 | 315 | // Draw the D-Pad circles 316 | if (_gamePadState.up) 317 | _drawCircle(12, _dPadUpButtonPosition); 318 | if (_gamePadState.down) 319 | _drawCircle(12, _dPadDownButtonPosition); 320 | if (_gamePadState.left) 321 | _drawCircle(12, _dPadLeftButtonPosition); 322 | if (_gamePadState.right) 323 | _drawCircle(12, _dPadRightButtonPosition); 324 | } 325 | 326 | // Draw meters showing the triggers 327 | _drawTriggerMeter(_leftTriggerMeterPosition, _gamePadState.leftTrigger); 328 | _drawTriggerMeter(_rightTriggerMeterPosition, _gamePadState.rightTrigger); 329 | 330 | // Draw thumbsticks 331 | _drawThumbstick(_leftThumbstickImage, _gamePadState.leftThumbstick, _leftThumbstickCenter, _gamePadState.leftStick); 332 | _drawThumbstick(_rightThumbstickImage, _gamePadState.rightThumbstick, _rightThumbstickCenter, _gamePadState.rightStick); 333 | } 334 | 335 | void _drawImage(ImageElement image, Point position) 336 | { 337 | num x = _controllerPosition.x + position.x; 338 | num y = _controllerPosition.y + position.y; 339 | 340 | _context.drawImage(image, x, y); 341 | } 342 | 343 | void _drawCircle(int radius, Point position) 344 | { 345 | _drawCircleAt(radius, position.x, position.y); 346 | } 347 | 348 | void _drawCircleAt(int radius, num x, num y) 349 | { 350 | x += _controllerPosition.x; 351 | y += _controllerPosition.y; 352 | 353 | _context.strokeStyle = _circleFillStyle; 354 | _context.fillStyle = _circleFillStyle; 355 | _context.beginPath(); 356 | _context.arc(x, y, radius, 0, 6.28318530718, true); // Math.PI seems to have disappeared 357 | _context.closePath(); 358 | _context.fill(); 359 | } 360 | 361 | void _drawThumbstick(ImageElement image, Point value, Point center, bool pressed) 362 | { 363 | num centerX = ( value.x * _thumbstickRadius) + center.x + _controllerPosition.x; 364 | num centerY = (-value.y * _thumbstickRadius) + center.y + _controllerPosition.y; 365 | 366 | num imageX = centerX - (image.width * 0.5); 367 | num imageY = centerY - (image.height * 0.5); 368 | 369 | _context.drawImage(image, imageX, imageY); 370 | 371 | if (pressed) 372 | _drawCircleAt(12, centerX - _controllerPosition.x, centerY - _controllerPosition.y); 373 | } 374 | 375 | void _drawTriggerMeter(Point position, num fill) 376 | { 377 | // Draw the outline 378 | _context.strokeStyle = _meterStrokeStyle; 379 | _context.lineWidth = _meterBorderThickness; 380 | 381 | _context.strokeRect(position.x, position.y, _meterWidth, _meterHeight); 382 | 383 | // Draw the filled meter 384 | if (fill > 0.0) 385 | { 386 | num totalBorderThickness = 2.0 * _meterBorderThickness; 387 | num width = _meterWidth - totalBorderThickness; 388 | num meterHeight = _meterHeight - totalBorderThickness; 389 | num height = fill * meterHeight; 390 | 391 | num x = position.x + _meterBorderThickness; 392 | num y = position.y + _meterBorderThickness + (meterHeight - height); 393 | 394 | _context.strokeStyle = _meterFillStyle; 395 | _context.fillStyle = _meterFillStyle; 396 | _context.fillRect(x, y, width, height); 397 | } 398 | } 399 | 400 | //--------------------------------------------------------------------- 401 | // Image loading 402 | //--------------------------------------------------------------------- 403 | 404 | static ImageElement _loadImage(String source) 405 | { 406 | ImageElement image = new ImageElement(); 407 | image.src = source; 408 | 409 | return image; 410 | } 411 | } 412 | -------------------------------------------------------------------------------- /client/images/a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/donny-dont/DartEmbeddingDemo/42a9634ca377b344cde5fc2baa3b830aad9d276e/client/images/a.png -------------------------------------------------------------------------------- /client/images/b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/donny-dont/DartEmbeddingDemo/42a9634ca377b344cde5fc2baa3b830aad9d276e/client/images/b.png -------------------------------------------------------------------------------- /client/images/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/donny-dont/DartEmbeddingDemo/42a9634ca377b344cde5fc2baa3b830aad9d276e/client/images/background.png -------------------------------------------------------------------------------- /client/images/controller.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/donny-dont/DartEmbeddingDemo/42a9634ca377b344cde5fc2baa3b830aad9d276e/client/images/controller.png -------------------------------------------------------------------------------- /client/images/dart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/donny-dont/DartEmbeddingDemo/42a9634ca377b344cde5fc2baa3b830aad9d276e/client/images/dart.png -------------------------------------------------------------------------------- /client/images/left_thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/donny-dont/DartEmbeddingDemo/42a9634ca377b344cde5fc2baa3b830aad9d276e/client/images/left_thumb.png -------------------------------------------------------------------------------- /client/images/player_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/donny-dont/DartEmbeddingDemo/42a9634ca377b344cde5fc2baa3b830aad9d276e/client/images/player_1.png -------------------------------------------------------------------------------- /client/images/player_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/donny-dont/DartEmbeddingDemo/42a9634ca377b344cde5fc2baa3b830aad9d276e/client/images/player_2.png -------------------------------------------------------------------------------- /client/images/player_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/donny-dont/DartEmbeddingDemo/42a9634ca377b344cde5fc2baa3b830aad9d276e/client/images/player_3.png -------------------------------------------------------------------------------- /client/images/player_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/donny-dont/DartEmbeddingDemo/42a9634ca377b344cde5fc2baa3b830aad9d276e/client/images/player_4.png -------------------------------------------------------------------------------- /client/images/right_thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/donny-dont/DartEmbeddingDemo/42a9634ca377b344cde5fc2baa3b830aad9d276e/client/images/right_thumb.png -------------------------------------------------------------------------------- /client/images/status.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/donny-dont/DartEmbeddingDemo/42a9634ca377b344cde5fc2baa3b830aad9d276e/client/images/status.png -------------------------------------------------------------------------------- /client/images/x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/donny-dont/DartEmbeddingDemo/42a9634ca377b344cde5fc2baa3b830aad9d276e/client/images/x.png -------------------------------------------------------------------------------- /client/images/y.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/donny-dont/DartEmbeddingDemo/42a9634ca377b344cde5fc2baa3b830aad9d276e/client/images/y.png -------------------------------------------------------------------------------- /client/style.css: -------------------------------------------------------------------------------- 1 | body 2 | { 3 | background:url(./images/background.png) top left; 4 | color:#EEE; 5 | margin:0px; 6 | padding:10px; 7 | font-family:Nobile, Arial, Helvetica, sans-serif; 8 | font-size: 12px; 9 | } 10 | 11 | .clear 12 | { 13 | clear:both; 14 | } 15 | 16 | .bordered 17 | { 18 | border:1px dashed #666; 19 | } 20 | 21 | /** 22 | * Error message drop down 23 | */ 24 | 25 | #errorMessage 26 | { 27 | position:fixed; 28 | top:-39px; 29 | margin:0px auto; 30 | width:300px; 31 | height:35px; 32 | background:#EEE; 33 | border-radius:0 0 5px 5px; 34 | border:2px solid #FF111C; 35 | left:0px; 36 | right:0px; 37 | text-align:center; 38 | font-size:24px; 39 | color:#FF111C; 40 | z-index:100; 41 | font-family:Oswald, Georgia, 'Times New Roman', Times, serif; 42 | } 43 | 44 | @-webkit-keyframes show 45 | { 46 | 0% {top:-39px;} 47 | 25% {top:-2px;} 48 | 75% {top:-2px;} 49 | 100% {top:-39px;} 50 | } 51 | 52 | /** 53 | * Main page wrapper, centers the page. 54 | */ 55 | 56 | #page 57 | { 58 | width:916px; 59 | margin:0px auto; 60 | } 61 | 62 | /** 63 | * Header elements. 64 | */ 65 | 66 | #header 67 | { 68 | float:left; 69 | font-family:Oswald, Georgia, 'Times New Roman', Times, serif; 70 | font-size:32px; 71 | } 72 | 73 | /** 74 | * Server connection form. 75 | */ 76 | 77 | #connection 78 | { 79 | padding:8px 0; 80 | float:right; 81 | } 82 | 83 | input[type="text"] 84 | { 85 | font-family:Nobile, Arial, Helvetica, sans-serif; 86 | font-size:16px; 87 | padding:0 10px 2px 10px; 88 | background:#EEE; 89 | border:solid 1px #EDEDED; 90 | width:140px; 91 | outline:none; 92 | margin:0 4px 0 0 93 | } 94 | 95 | input[type="text"]:focus 96 | { 97 | border:solid 1px #22A509; 98 | } 99 | 100 | #wrapper 101 | { 102 | background-color:#2E2E2E; 103 | border-radius:0 0 15px 15px; 104 | padding:8px; 105 | } 106 | 107 | /** 108 | * Connect/disconnect button 109 | */ 110 | 111 | input[type="button"] 112 | { 113 | background-color:#EEE; 114 | border:1px solid #DEDEDE; 115 | width:100px; 116 | font-family:Oswald, Georgia, 'Times New Roman', Times, serif; 117 | font-size:16px; 118 | text-decoration:none; 119 | cursor:pointer; 120 | vertical-align:bottom; 121 | height:29px; 122 | } 123 | 124 | input[type="button"].connect 125 | { 126 | color:#22A509; 127 | } 128 | 129 | input[type="button"].connect:hover 130 | { 131 | background:#DCEFD7; 132 | border:1px solid #22A509; 133 | color:#22A509; 134 | } 135 | 136 | input[type="button"].connect:active 137 | { 138 | background-color:#22A509; 139 | border:1px solid #22A509; 140 | color:#DDD; 141 | } 142 | 143 | input[type="button"].disconnect 144 | { 145 | color:#FF111C; 146 | } 147 | 148 | input[type="button"].disconnect:hover 149 | { 150 | color:#FF111C; 151 | background:#FFD7D9; 152 | border:1px solid #FF111C; 153 | } 154 | 155 | input[type="button"].disconnect:active 156 | { 157 | background-color:#FF111C; 158 | border:1px solid #FF111C; 159 | color:#DDD; 160 | } 161 | 162 | /** 163 | * Connection status indicator. 164 | */ 165 | 166 | #status 167 | { 168 | width:24px; 169 | height:24px; 170 | background:url(images/status.png) no-repeat; 171 | float:right; 172 | margin:12px 5px 0 0; 173 | } 174 | 175 | #status.disconnected 176 | { 177 | background-position-x:0px; 178 | } 179 | 180 | #status.connecting 181 | { 182 | background-position-x:-24px; 183 | } 184 | 185 | #status.connected 186 | { 187 | background-position-x:-48px; 188 | } 189 | 190 | /** 191 | * Player selection tabs. 192 | */ 193 | 194 | .tab 195 | { 196 | float:left; 197 | list-style:none; 198 | padding:0; 199 | margin:16px 0 0 0; 200 | line-height:24px; 201 | } 202 | 203 | .tab li 204 | { 205 | margin:0 3px 0 0; 206 | padding:0 10px; 207 | border:1px solid #4E4E4E; 208 | border-radius:5px 5px 0 0; 209 | background:#4E4E4E; 210 | display: inline-block; 211 | } 212 | 213 | .tab li.selected 214 | { 215 | border:1px solid #2E2E2E; 216 | border-radius:5px 5px 0 0; 217 | background:#2E2E2E; 218 | } 219 | 220 | .tab li:hover 221 | { 222 | cursor:pointer; 223 | } 224 | 225 | /** 226 | * Canvas showing the game pad. 227 | */ 228 | 229 | #gamepadWrapper 230 | { 231 | position:relative; 232 | height:578px; 233 | } 234 | 235 | canvas 236 | { 237 | position:absolute; 238 | left:0; 239 | top:0; 240 | padding:0; 241 | } 242 | 243 | #overlay 244 | { 245 | position:absolute; 246 | left:0; 247 | top:0; 248 | padding:0; 249 | width:100%; 250 | z-index:2; 251 | } 252 | 253 | #showValues 254 | { 255 | position:absolute; 256 | right:0px; 257 | top:16px; 258 | padding:0 6px 0 0; 259 | background:#666; 260 | border-radius:6px 0 0 6px; 261 | border-left:1px solid #333; 262 | border-top:1px solid #333; 263 | border-bottom:1px solid #333; 264 | } 265 | 266 | input[type="checkbox"] 267 | { 268 | margin:3px 3px 3px 8px; 269 | vertical-align:bottom; 270 | } 271 | 272 | .thumbstick 273 | { 274 | position:absolute; 275 | background:#666; 276 | padding:4px; 277 | border-radius:4px; 278 | border:1px solid #333; 279 | width:100px; 280 | } 281 | 282 | .trigger 283 | { 284 | position:absolute; 285 | background:#666; 286 | padding:2px; 287 | border-radius:4px; 288 | border:1px solid #333; 289 | width:50px; 290 | } 291 | 292 | .valueHeader 293 | { 294 | text-align:center; 295 | font-family:Oswald, Georgia, 'Times New Roman', Times, serif; 296 | border-bottom:1px solid #EEE; 297 | } 298 | 299 | .thumbstickValue 300 | { 301 | margin:0px 32px; 302 | width:100%; 303 | } 304 | 305 | .triggerValue 306 | { 307 | text-align:center; 308 | } 309 | 310 | #leftThumbstick 311 | { 312 | left:200px; 313 | top:450px; 314 | } 315 | 316 | #rightThumbstick 317 | { 318 | right:200px; 319 | top:450px; 320 | } 321 | 322 | #leftTrigger 323 | { 324 | left:8px; 325 | top:320px; 326 | } 327 | 328 | #rightTrigger 329 | { 330 | right:8px; 331 | top:320px; 332 | } 333 | 334 | /** 335 | * Sliders for vibration control. 336 | */ 337 | 338 | .motor 339 | { 340 | width:440px; 341 | padding:4px; 342 | } 343 | 344 | input[type="range"] 345 | { 346 | width:440px; 347 | margin:0px; 348 | } 349 | 350 | #leftMotor 351 | { 352 | float:left; 353 | } 354 | 355 | #rightMotor 356 | { 357 | float:right; 358 | } 359 | 360 | /** 361 | * Footer area. 362 | */ 363 | 364 | #footer 365 | { 366 | padding:4px 20px; 367 | height:60px; 368 | } 369 | 370 | #copyright 371 | { 372 | float:left; 373 | text-align:left; 374 | margin-top:20px; 375 | } 376 | 377 | #dart-logo 378 | { 379 | float:right; 380 | width:115px; 381 | height:50px; 382 | background-image:url('images/dart.png'); 383 | } 384 | -------------------------------------------------------------------------------- /client/ui_elements.dart: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Status of the server connection. 4 | */ 5 | class ConnectionStatus 6 | { 7 | /// Connected to the server. 8 | static final ConnectionStatus Connected = const ConnectionStatus(0); 9 | /// Connecting to the server. 10 | static final ConnectionStatus Connecting = const ConnectionStatus(1); 11 | /// Disconnected from the server. 12 | static final ConnectionStatus Disconnected = const ConnectionStatus(2); 13 | 14 | final int value; 15 | 16 | const ConnectionStatus(int this.value); 17 | } 18 | 19 | /** 20 | * Visual indicator of the server connection. 21 | */ 22 | class ConnectionStatusIndicator 23 | { 24 | /// Element displaying the status. 25 | Element _element; 26 | /// Current status. 27 | ConnectionStatus _status; 28 | 29 | /** 30 | * Creates an instance of the ConnectionStatusIndicator class. 31 | */ 32 | ConnectionStatusIndicator(String id) 33 | { 34 | _element = document.query(id); 35 | status = ConnectionStatus.Disconnected; 36 | } 37 | 38 | /** 39 | * The status of the server connection. 40 | */ 41 | ConnectionStatus get status => _status; 42 | set status(ConnectionStatus value) 43 | { 44 | _status = value; 45 | 46 | if (_status == ConnectionStatus.Connected) 47 | _setStyle('connected'); 48 | else if (_status == ConnectionStatus.Connecting) 49 | _setStyle('connecting'); 50 | else 51 | _setStyle('disconnected'); 52 | } 53 | 54 | void _setStyle(String style) 55 | { 56 | _element.classes.clear(); 57 | _element.classes.add(style); 58 | } 59 | } 60 | 61 | /** 62 | * Error message for connection issues. 63 | */ 64 | class ErrorMessage 65 | { 66 | /// Element displaying the message. 67 | Element _element; 68 | 69 | /** 70 | * Create an instance of the ErrorMessage class. 71 | */ 72 | ErrorMessage(String id) 73 | { 74 | _element = document.query(id); 75 | } 76 | 77 | /** 78 | * Displays the error [message]. 79 | */ 80 | void showError(String message) 81 | { 82 | _element.innerHTML = message; 83 | 84 | _element.style.animation = 'show 2s'; 85 | } 86 | 87 | /** 88 | * Hides the error message. 89 | * 90 | * This will immediately remove the error message. 91 | */ 92 | void hideError() 93 | { 94 | _element.style.animation = ''; 95 | } 96 | } 97 | 98 | /** 99 | * Controller vibration controls 100 | */ 101 | class VibrationControls 102 | { 103 | /// Maximum value of the slider 104 | static double _maxValue = 65535.0; 105 | 106 | /// Left motor element 107 | Element _leftMotorElement; 108 | /// Right motor element 109 | Element _rightMotorElement; 110 | /// Left motor input element 111 | InputElement _leftMotorInputElement; 112 | /// Right motor input element 113 | InputElement _rightMotorInputElement; 114 | /// Left motor values 115 | List _leftMotorValues; 116 | /// Right motor values 117 | List _rightMotorValues; 118 | 119 | /// The index of the player being displayed 120 | int _playerIndex; 121 | 122 | VibrationControls(String leftId, String rightId) 123 | { 124 | _playerIndex = 0; 125 | 126 | // Setup the left motor 127 | Element leftMotorRoot = document.query(leftId); 128 | _leftMotorElement = leftMotorRoot.query('.motorValue'); 129 | _leftMotorInputElement = leftMotorRoot.query('input'); 130 | 131 | _leftMotorValues = [ 0.0, 0.0, 0.0, 0.0 ]; 132 | 133 | _setupCallback(_leftMotorInputElement, _leftMotorElement, _leftMotorValues); 134 | 135 | // Setup the right motor 136 | Element rightMotorRoot = document.query(rightId); 137 | _rightMotorElement = rightMotorRoot.query('.motorValue'); 138 | _rightMotorInputElement = rightMotorRoot.query('input'); 139 | 140 | _rightMotorValues = [ 0.0, 0.0, 0.0, 0.0 ]; 141 | 142 | _setupCallback(_rightMotorInputElement, _rightMotorElement, _rightMotorValues); 143 | } 144 | 145 | set enabled(bool value) 146 | { 147 | bool disabled = !value; 148 | 149 | _leftMotorInputElement.disabled = disabled; 150 | _rightMotorInputElement.disabled = disabled; 151 | } 152 | 153 | int get playerIndex => _playerIndex; 154 | set playerIndex(int value) 155 | { 156 | _playerIndex = value; 157 | 158 | _updateView(); 159 | } 160 | 161 | 162 | void reset() 163 | { 164 | _leftMotorValues[0] = 0.0; 165 | _leftMotorValues[1] = 0.0; 166 | _leftMotorValues[2] = 0.0; 167 | _leftMotorValues[3] = 0.0; 168 | 169 | _rightMotorValues[0] = 0.0; 170 | _rightMotorValues[1] = 0.0; 171 | _rightMotorValues[2] = 0.0; 172 | _rightMotorValues[3] = 0.0; 173 | 174 | _updateView(); 175 | } 176 | 177 | void _updateView() 178 | { 179 | double leftMotor = _leftMotorValues[_playerIndex]; 180 | double rightMotor = _rightMotorValues[_playerIndex]; 181 | 182 | _leftMotorElement.innerHTML = leftMotor.toStringAsFixed(3); 183 | _rightMotorElement.innerHTML = rightMotor.toStringAsFixed(3); 184 | 185 | _leftMotorInputElement.valueAsNumber = leftMotor * _maxValue; 186 | _rightMotorInputElement.valueAsNumber = rightMotor * _maxValue; 187 | } 188 | 189 | void _setupCallback(InputElement input, Element display, List list) 190 | { 191 | input.on.change.add((e) { 192 | // Store information 193 | double value = input.valueAsNumber / _maxValue; 194 | list[_playerIndex] = value; 195 | 196 | display.innerHTML = value.toStringAsFixed(3); 197 | 198 | // Notify that a value has changed 199 | _onValueChanged(); 200 | }); 201 | } 202 | 203 | void _onValueChanged() 204 | { 205 | double leftMotor = _leftMotorValues[_playerIndex]; 206 | double rightMotor = _rightMotorValues[_playerIndex]; 207 | 208 | GamePad.setVibration(_playerIndex, leftMotor, rightMotor); 209 | } 210 | } 211 | -------------------------------------------------------------------------------- /server/DartEmbed.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 11.00 3 | # Visual Studio 2010 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DartEmbed", "DartEmbed.vcxproj", "{BCF473E1-6D4E-48CC-8186-08740A376921}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|Win32 = Debug|Win32 9 | Release|Win32 = Release|Win32 10 | EndGlobalSection 11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 | {BCF473E1-6D4E-48CC-8186-08740A376921}.Debug|Win32.ActiveCfg = Debug|Win32 13 | {BCF473E1-6D4E-48CC-8186-08740A376921}.Debug|Win32.Build.0 = Debug|Win32 14 | {BCF473E1-6D4E-48CC-8186-08740A376921}.Release|Win32.ActiveCfg = Release|Win32 15 | {BCF473E1-6D4E-48CC-8186-08740A376921}.Release|Win32.Build.0 = Release|Win32 16 | EndGlobalSection 17 | GlobalSection(SolutionProperties) = preSolution 18 | HideSolutionNode = FALSE 19 | EndGlobalSection 20 | EndGlobal 21 | -------------------------------------------------------------------------------- /server/DartEmbed.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | {BCF473E1-6D4E-48CC-8186-08740A376921} 38 | Win32Proj 39 | DartEmbed 40 | 41 | 42 | 43 | Application 44 | true 45 | MultiByte 46 | 47 | 48 | Application 49 | false 50 | true 51 | MultiByte 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | true 65 | 66 | 67 | false 68 | 69 | 70 | 71 | 72 | 73 | Level3 74 | Disabled 75 | WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) 76 | .\ 77 | 78 | 79 | Console 80 | true 81 | mainCRTStartup 82 | XInput.lib;ws2_32.lib;Rpcrt4.lib;libdart_aux.lib;libdart_builtin.lib;libdart_export.lib;libdart_lib.lib;libdart_vm.lib;libdouble_conversion.lib;libjscre.lib;%(AdditionalDependencies) 83 | lib\Debug 84 | 85 | 86 | 87 | 88 | Level3 89 | 90 | 91 | MaxSpeed 92 | true 93 | true 94 | WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) 95 | .\ 96 | 97 | 98 | Console 99 | true 100 | true 101 | true 102 | mainCRTStartup 103 | XInput.lib;ws2_32.lib;Rpcrt4.lib;libdart_aux.lib;libdart_builtin.lib;libdart_export.lib;libdart_lib.lib;libdart_vm.lib;libdouble_conversion.lib;libjscre.lib;%(AdditionalDependencies) 104 | lib\Release 105 | 106 | 107 | 108 | 109 | 110 | -------------------------------------------------------------------------------- /server/DartEmbed.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {ecc92523-6c2e-47b2-929c-427fdf222f07} 6 | 7 | 8 | {da9ad88d-de55-4bfd-a602-142fc1807d1e} 9 | 10 | 11 | 12 | 13 | src 14 | 15 | 16 | src 17 | 18 | 19 | src 20 | 21 | 22 | src 23 | 24 | 25 | src 26 | 27 | 28 | src 29 | 30 | 31 | DartEmbed 32 | 33 | 34 | DartEmbed 35 | 36 | 37 | DartEmbed 38 | 39 | 40 | src 41 | 42 | 43 | src 44 | 45 | 46 | 47 | 48 | src 49 | 50 | 51 | src 52 | 53 | 54 | src 55 | 56 | 57 | src 58 | 59 | 60 | src 61 | 62 | 63 | src 64 | 65 | 66 | src 67 | 68 | 69 | src 70 | 71 | 72 | -------------------------------------------------------------------------------- /server/DartEmbed/GamePad.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * \file GamePad.hpp 3 | * 4 | * \section COPYRIGHT 5 | * 6 | * Dart Embedding Example 7 | * 8 | * --------------------------------------------------------------------- 9 | * 10 | * Copyright (c) 2012 Don Olmstead 11 | * 12 | * This software is provided 'as-is', without any express or implied 13 | * warranty. In no event will the authors be held liable for any damages 14 | * arising from the use of this software. 15 | * 16 | * Permission is granted to anyone to use this software for any purpose, 17 | * including commercial applications, and to alter it and redistribute it 18 | * freely, subject to the following restrictions: 19 | * 20 | * 1. The origin of this software must not be misrepresented; you must not 21 | * claim that you wrote the original software. If you use this software 22 | * in a product, an acknowledgment in the product documentation would be 23 | * appreciated but is not required. 24 | * 25 | * 2. Altered source versions must be plainly marked as such, and must not be 26 | * misrepresented as being the original software. 27 | * 28 | * 3. This notice may not be removed or altered from any source 29 | * distribution. 30 | */ 31 | 32 | #ifndef DART_EMBED_GAME_PAD_HPP_INCLUDED 33 | #define DART_EMBED_GAME_PAD_HPP_INCLUDED 34 | 35 | #include 36 | 37 | namespace DartEmbed 38 | { 39 | /** 40 | * Specifies the game controller associated with a player. 41 | */ 42 | namespace PlayerIndex 43 | { 44 | /// An enumerated type 45 | enum Enum 46 | { 47 | /// The first controller 48 | One, 49 | /// The second controller 50 | Two, 51 | /// The third controller 52 | Three, 53 | /// The fourth controller 54 | Four, 55 | /// The number of enumerations 56 | Size 57 | } ; // end enum Enum 58 | } // end namespace PlayerIndex 59 | 60 | /** 61 | * Represents information about the state of an Xbox 360 Controller. 62 | */ 63 | class GamePadState 64 | { 65 | //---------------------------------------------------------------------- 66 | // Construction 67 | //---------------------------------------------------------------------- 68 | 69 | public: 70 | 71 | /** 72 | * Creates an instance of the GamePadState class. 73 | */ 74 | GamePadState(); 75 | 76 | /** 77 | * Initializes an instance of the GamePadState class. 78 | * 79 | * \param copy The instance to copy. 80 | */ 81 | GamePadState(const GamePadState& copy); 82 | 83 | //---------------------------------------------------------------------- 84 | // Assignment 85 | //---------------------------------------------------------------------- 86 | 87 | public: 88 | 89 | /** 90 | * Copies the values from the given instance. 91 | * 92 | * \param copy The instance to copy. 93 | */ 94 | GamePadState& operator= (const GamePadState& copy); 95 | 96 | //---------------------------------------------------------------------- 97 | // Properties 98 | //---------------------------------------------------------------------- 99 | 100 | public: 101 | 102 | inline bool isConnected() const 103 | { 104 | return _connected; 105 | } 106 | 107 | void setConnected(bool value) 108 | { 109 | _connected = value; 110 | } 111 | 112 | inline float getLeftTrigger() const 113 | { 114 | return _leftTrigger; 115 | } 116 | 117 | inline float getRightTrigger() const 118 | { 119 | return _rightTrigger; 120 | } 121 | 122 | inline std::int32_t getPacketNumber() const 123 | { 124 | return _packetNumber; 125 | } 126 | 127 | inline void setPacketNumber(std::int32_t value) 128 | { 129 | _packetNumber = value; 130 | } 131 | 132 | inline float getLeftThumbstickX() const 133 | { 134 | return _leftThumbstickX; 135 | } 136 | 137 | inline void setLeftThumbstickX(float value) 138 | { 139 | _leftThumbstickX = value; 140 | } 141 | 142 | inline float getLeftThumbstickY() const 143 | { 144 | return _leftThumbstickY; 145 | } 146 | 147 | inline void setLeftThumbstickY(float value) 148 | { 149 | _leftThumbstickY = value; 150 | } 151 | 152 | inline float getRightThumbstickX() const 153 | { 154 | return _rightThumbstickX; 155 | } 156 | 157 | inline void setRightThumbstickX(float value) 158 | { 159 | _rightThumbstickX = value; 160 | } 161 | 162 | inline float getRightThumbstickY() const 163 | { 164 | return _rightThumbstickY; 165 | } 166 | 167 | inline void setRightThumbstickY(float value) 168 | { 169 | _rightThumbstickY = value; 170 | } 171 | 172 | inline void setLeftTrigger(float value) 173 | { 174 | _leftTrigger = value; 175 | } 176 | 177 | inline void setRightTrigger(float value) 178 | { 179 | _rightTrigger = value; 180 | } 181 | 182 | inline std::int32_t getButtons() const 183 | { 184 | return _buttons; 185 | } 186 | 187 | inline void setButtons(std::int32_t value) 188 | { 189 | _buttons = value; 190 | } 191 | 192 | //---------------------------------------------------------------------- 193 | // Member variables 194 | //---------------------------------------------------------------------- 195 | 196 | private: 197 | 198 | /// Whether the controller is connected 199 | bool _connected; 200 | /** 201 | * The packet number for the controller. 202 | * 203 | * Whenever the state changes the packet number is changed. 204 | * If the packet number hasn't changed then the values don't 205 | * need to be copied again. 206 | */ 207 | std::int32_t _packetNumber; 208 | /// Left thumbstick X value 209 | float _leftThumbstickX; 210 | /// Left thumbstick Y value 211 | float _leftThumbstickY; 212 | /// Right thumbstick X value 213 | float _rightThumbstickX; 214 | /// Right thumbstick Y value 215 | float _rightThumbstickY; 216 | /// Left trigger value 217 | float _leftTrigger; 218 | /// Right trigger value 219 | float _rightTrigger; 220 | /// Button state 221 | std::int32_t _buttons; 222 | } ; // end class GamePadState 223 | 224 | /** 225 | * Allows retrieval of user interaction with an Xbox 360 controller. 226 | */ 227 | namespace GamePad 228 | { 229 | /** 230 | * Gets the current state of a game pad controller. 231 | * 232 | * \returns The current state of a game pad controller. 233 | */ 234 | const GamePadState& getState(PlayerIndex::Enum player); 235 | 236 | /** 237 | * Sets the virbration motor speeds of an Xbox 360 controller. 238 | * 239 | * \param leftMotor The speed of the low-frequency left motor. 240 | * \param rightMoto The speed of the high-frequency right motor. 241 | */ 242 | void setVibration(PlayerIndex::Enum player, const float leftMotor, const float rightMotor); 243 | } // end namespace GamePad 244 | } 245 | 246 | #endif // end DART_EMBED_GAME_PAD_HPP_INCLUDED 247 | -------------------------------------------------------------------------------- /server/DartEmbed/Isolate.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * \file Isolate.hpp 3 | * 4 | * \section COPYRIGHT 5 | * 6 | * Dart Embedding Example 7 | * 8 | * --------------------------------------------------------------------- 9 | * 10 | * Copyright (c) 2012 Don Olmstead 11 | * 12 | * This software is provided 'as-is', without any express or implied 13 | * warranty. In no event will the authors be held liable for any damages 14 | * arising from the use of this software. 15 | * 16 | * Permission is granted to anyone to use this software for any purpose, 17 | * including commercial applications, and to alter it and redistribute it 18 | * freely, subject to the following restrictions: 19 | * 20 | * 1. The origin of this software must not be misrepresented; you must not 21 | * claim that you wrote the original software. If you use this software 22 | * in a product, an acknowledgment in the product documentation would be 23 | * appreciated but is not required. 24 | * 25 | * 2. Altered source versions must be plainly marked as such, and must not be 26 | * misrepresented as being the original software. 27 | * 28 | * 3. This notice may not be removed or altered from any source 29 | * distribution. 30 | */ 31 | 32 | #ifndef DART_EMBED_ISOLATE_HPP_INCLUDED 33 | #define DART_EMBED_ISOLATE_HPP_INCLUDED 34 | 35 | #include 36 | 37 | namespace DartEmbed 38 | { 39 | class Isolate 40 | { 41 | //--------------------------------------------------------------------- 42 | // Creation/Destruction 43 | //--------------------------------------------------------------------- 44 | 45 | private: 46 | 47 | /** 48 | * Creates an instance of the Isolate class. 49 | */ 50 | Isolate( 51 | Dart_Isolate isolate, 52 | Dart_Handle library, 53 | Isolate* parent 54 | ); 55 | 56 | public: 57 | 58 | /** 59 | * Destroys the current Isolate. 60 | */ 61 | ~Isolate(); 62 | 63 | //--------------------------------------------------------------------- 64 | // Properties 65 | //--------------------------------------------------------------------- 66 | 67 | public: 68 | 69 | /** 70 | * Retrieves the parent of the isolate. 71 | * 72 | * The parent points to the isolate that started this 73 | * isolate instance. 74 | */ 75 | inline Isolate* getParent() const 76 | { 77 | return _parent; 78 | } 79 | 80 | public: 81 | 82 | /** 83 | * Invokes a function within the isolate. 84 | * 85 | * \param name The name of the function to invoke. 86 | */ 87 | void invokeFunction(const char* name); 88 | 89 | /** 90 | * Creates an isolate from a script. 91 | * 92 | * \param path The path to the script. 93 | */ 94 | static Isolate* loadScript(const char* path); 95 | 96 | //--------------------------------------------------------------------- 97 | // Static methods 98 | // 99 | // Used to spawn isolates within the VM. 100 | //--------------------------------------------------------------------- 101 | 102 | private: 103 | 104 | /** 105 | * Creates an isolate from the given script. 106 | * 107 | * \param scriptUri The URI to the script. 108 | * \param main The entry point to the isolate. 109 | * \param resolveScript Whether the script needs resoltion to a uri. 110 | * \param callbackData Pointer to the parent isolate. 111 | * \param error A pointer to an error message. 112 | */ 113 | static Isolate* createIsolate( 114 | const char* scriptUri, 115 | const char* main, 116 | bool resolveScript, 117 | void* data, 118 | char** error); 119 | 120 | /** 121 | * Callback for when an isolate is created. 122 | * 123 | * This is only called when an isolate is created within a script. It 124 | * will not be called when creating an isolate manually. 125 | * 126 | * \param scriptUri The URI to the script. 127 | * \param main The entry point to the isolate. 128 | * \param callbackData Pointer to the parent isolate. 129 | * \param error A pointer to an error message. 130 | */ 131 | static bool isolateCreateCallback( 132 | const char* scriptUri, 133 | const char* main, 134 | void* callbackData, 135 | char** error); 136 | 137 | /** 138 | * Callback for when an isolate is shut down. 139 | * 140 | * This is only called when an isolate that was created within a script 141 | * was shutdown. 142 | * 143 | * \param callbackData A pointer to the isolate data. 144 | */ 145 | static void isolateShutdownCallback(void* callbackData); 146 | 147 | //--------------------------------------------------------------------- 148 | // Member variables 149 | //--------------------------------------------------------------------- 150 | 151 | private: 152 | 153 | friend class VirtualMachine; 154 | 155 | /// The isolate handle 156 | Dart_Isolate _isolate; 157 | /// The library held in the isolate 158 | Dart_Handle _library; 159 | /// The parent of the isolate 160 | Isolate* _parent; 161 | } ; 162 | } // end namespace Dart 163 | 164 | #endif // end DART_EMBED_ISOLATE_HPP_INCLUDED 165 | -------------------------------------------------------------------------------- /server/DartEmbed/VirtualMachine.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * \file VirtualMachine.hpp 3 | * 4 | * \section COPYRIGHT 5 | * 6 | * Dart Embedding Example 7 | * 8 | * --------------------------------------------------------------------- 9 | * 10 | * Copyright (c) 2012 Don Olmstead 11 | * 12 | * This software is provided 'as-is', without any express or implied 13 | * warranty. In no event will the authors be held liable for any damages 14 | * arising from the use of this software. 15 | * 16 | * Permission is granted to anyone to use this software for any purpose, 17 | * including commercial applications, and to alter it and redistribute it 18 | * freely, subject to the following restrictions: 19 | * 20 | * 1. The origin of this software must not be misrepresented; you must not 21 | * claim that you wrote the original software. If you use this software 22 | * in a product, an acknowledgment in the product documentation would be 23 | * appreciated but is not required. 24 | * 25 | * 2. Altered source versions must be plainly marked as such, and must not be 26 | * misrepresented as being the original software. 27 | * 28 | * 3. This notice may not be removed or altered from any source 29 | * distribution. 30 | */ 31 | 32 | #ifndef DART_EMBED_VIRTUAL_MACHINE_HPP_INCLUDED 33 | #define DART_EMBED_VIRTUAL_MACHINE_HPP_INCLUDED 34 | 35 | #include 36 | #include 37 | 38 | //--------------------------------------------------------------------- 39 | // Forward declarations for Dart types 40 | //--------------------------------------------------------------------- 41 | 42 | /// Reference to a Dart isolate 43 | typedef struct _Dart_Isolate* Dart_Isolate; 44 | /// Reference to a Dart object 45 | typedef struct _Dart_Handle* Dart_Handle; 46 | /// Native arguments for Dart 47 | typedef struct _Dart_NativeArguments* Dart_NativeArguments; 48 | /// Glue for communication between Dart and C/C++ 49 | typedef void (*Dart_NativeFunction)(Dart_NativeArguments arguments); 50 | /// Resolves a name from a string into a Dart_NativeFunction 51 | typedef Dart_NativeFunction (*Dart_NativeEntryResolver)(Dart_Handle name, int num_of_arguments); 52 | /// Initialization routines for a library 53 | typedef void (*Dart_LibraryInitializer)(Dart_Handle library); 54 | 55 | namespace DartEmbed 56 | { 57 | /** 58 | * Embedded Dart virtual machine. 59 | */ 60 | class VirtualMachine 61 | { 62 | public: 63 | /** 64 | * Attempts to initialize the virtual machine. 65 | * 66 | * \returns true if the virtual machine was initialized; false otherwise. 67 | */ 68 | static bool initialize(); 69 | 70 | /** 71 | * Terminates the virtual machine. 72 | * 73 | * Halts any currently running isolates. 74 | */ 75 | static void terminate(); 76 | 77 | /** 78 | * Loads a script library into the virtual machine. 79 | * 80 | * \param name The name of the library. 81 | * \param source The source code for the library. 82 | * \param nativeResolver The native resolver for the library. 83 | * \param initializer Function to call that will provide any initialization for the library. 84 | */ 85 | static void loadScriptLibrary( 86 | const char* name, 87 | const char* source, 88 | Dart_NativeEntryResolver nativeResolver = 0, 89 | Dart_LibraryInitializer initializer = 0 90 | ); 91 | 92 | /** 93 | * Queries the number of isolates currently running. 94 | * 95 | * \returns The number of isolates currently running. 96 | */ 97 | static std::size_t getNumberOfIsolates(); 98 | 99 | private: 100 | 101 | VirtualMachine() { } 102 | } ; // end namespace VirtualMachine 103 | } // end namespace DartEmbed 104 | 105 | #endif // end DART_EMBED_VIRTUAL_MACHINE_HPP_INCLUDED 106 | -------------------------------------------------------------------------------- /server/lib/Debug/libdart_aux.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/donny-dont/DartEmbeddingDemo/42a9634ca377b344cde5fc2baa3b830aad9d276e/server/lib/Debug/libdart_aux.lib -------------------------------------------------------------------------------- /server/lib/Debug/libdart_builtin.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/donny-dont/DartEmbeddingDemo/42a9634ca377b344cde5fc2baa3b830aad9d276e/server/lib/Debug/libdart_builtin.lib -------------------------------------------------------------------------------- /server/lib/Debug/libdart_export.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/donny-dont/DartEmbeddingDemo/42a9634ca377b344cde5fc2baa3b830aad9d276e/server/lib/Debug/libdart_export.lib -------------------------------------------------------------------------------- /server/lib/Debug/libdart_lib.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/donny-dont/DartEmbeddingDemo/42a9634ca377b344cde5fc2baa3b830aad9d276e/server/lib/Debug/libdart_lib.lib -------------------------------------------------------------------------------- /server/lib/Debug/libdart_vm.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/donny-dont/DartEmbeddingDemo/42a9634ca377b344cde5fc2baa3b830aad9d276e/server/lib/Debug/libdart_vm.lib -------------------------------------------------------------------------------- /server/lib/Debug/libdouble_conversion.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/donny-dont/DartEmbeddingDemo/42a9634ca377b344cde5fc2baa3b830aad9d276e/server/lib/Debug/libdouble_conversion.lib -------------------------------------------------------------------------------- /server/lib/Debug/libjscre.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/donny-dont/DartEmbeddingDemo/42a9634ca377b344cde5fc2baa3b830aad9d276e/server/lib/Debug/libjscre.lib -------------------------------------------------------------------------------- /server/lib/Release/libdart_aux.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/donny-dont/DartEmbeddingDemo/42a9634ca377b344cde5fc2baa3b830aad9d276e/server/lib/Release/libdart_aux.lib -------------------------------------------------------------------------------- /server/lib/Release/libdart_builtin.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/donny-dont/DartEmbeddingDemo/42a9634ca377b344cde5fc2baa3b830aad9d276e/server/lib/Release/libdart_builtin.lib -------------------------------------------------------------------------------- /server/lib/Release/libdart_export.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/donny-dont/DartEmbeddingDemo/42a9634ca377b344cde5fc2baa3b830aad9d276e/server/lib/Release/libdart_export.lib -------------------------------------------------------------------------------- /server/lib/Release/libdart_lib.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/donny-dont/DartEmbeddingDemo/42a9634ca377b344cde5fc2baa3b830aad9d276e/server/lib/Release/libdart_lib.lib -------------------------------------------------------------------------------- /server/lib/Release/libdart_vm.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/donny-dont/DartEmbeddingDemo/42a9634ca377b344cde5fc2baa3b830aad9d276e/server/lib/Release/libdart_vm.lib -------------------------------------------------------------------------------- /server/lib/Release/libdouble_conversion.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/donny-dont/DartEmbeddingDemo/42a9634ca377b344cde5fc2baa3b830aad9d276e/server/lib/Release/libdouble_conversion.lib -------------------------------------------------------------------------------- /server/lib/Release/libjscre.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/donny-dont/DartEmbeddingDemo/42a9634ca377b344cde5fc2baa3b830aad9d276e/server/lib/Release/libjscre.lib -------------------------------------------------------------------------------- /server/server.dart: -------------------------------------------------------------------------------- 1 | /** 2 | * Dart Embedding Example 3 | * 4 | * --------------------------------------------------------------------- 5 | * 6 | * Copyright (c) 2012 Don Olmstead 7 | * 8 | * This software is provided 'as-is', without any express or implied 9 | * warranty. In no event will the authors be held liable for any damages 10 | * arising from the use of this software. 11 | * 12 | * Permission is granted to anyone to use this software for any purpose, 13 | * including commercial applications, and to alter it and redistribute it 14 | * freely, subject to the following restrictions: 15 | * 16 | * 1. The origin of this software must not be misrepresented; you must not 17 | * claim that you wrote the original software. If you use this software 18 | * in a product, an acknowledgment in the product documentation would be 19 | * appreciated but is not required. 20 | * 21 | * 2. Altered source versions must be plainly marked as such, and must not be 22 | * misrepresented as being the original software. 23 | * 24 | * 3. This notice may not be removed or altered from any source 25 | * distribution. 26 | */ 27 | 28 | #import('dart:io'); 29 | #import('dart:json'); 30 | #import('dart:isolate'); 31 | #import('embed:input'); 32 | 33 | String gamePadStateMessage(int index, GamePadState gamePad) 34 | { 35 | return 36 | """ 37 | { 38 | "index": ${index}, 39 | "connected": ${gamePad.isConnected}, 40 | "leftThumbstick": { 41 | "x": ${gamePad.leftThumbstickX}, 42 | "y": ${gamePad.leftThumbstickY} 43 | }, 44 | "rightThumbstick": { 45 | "x": ${gamePad.rightThumbstickX}, 46 | "y": ${gamePad.rightThumbstickY} 47 | }, 48 | "leftTrigger": ${gamePad.leftTrigger}, 49 | "rightTrigger": ${gamePad.rightTrigger}, 50 | "buttons": ${gamePad.buttons} 51 | } 52 | """; 53 | } 54 | 55 | void _handleConnection(WebSocketConnection connection) 56 | { 57 | print('New connection'); 58 | bool connected = true; 59 | GamePadState gamePad = new GamePadState(); 60 | int playerIndex = 0; 61 | 62 | connection.onMessage = (message) { 63 | // Parse the message 64 | Map parsed = JSON.parse(message); 65 | 66 | // Get the standard values 67 | String type = parsed['type']; 68 | int index = parsed['index']; 69 | 70 | if (type == 'index') 71 | { 72 | // Start sending this game pad data 73 | playerIndex = index; 74 | 75 | print('Request $index'); 76 | } 77 | else if (type == 'vibration') 78 | { 79 | double leftMotor = parsed['leftMotor']; 80 | double rightMotor = parsed['rightMotor']; 81 | 82 | print('Vibration $index: left $leftMotor right $rightMotor'); 83 | GamePad.setVibration(index, leftMotor, rightMotor); 84 | } 85 | }; 86 | 87 | connection.onClosed = (int status, String reason) { 88 | print('Closed with $status for $reason'); 89 | connected = false; 90 | }; 91 | 92 | connection.onError = (e) { 93 | print('Error was $e'); 94 | connected = false; 95 | }; 96 | 97 | // Emulate a 60fps application 98 | Timer timer = new Timer.repeating(16, (e) { 99 | if (connected) 100 | { 101 | GamePad.getState(playerIndex, gamePad); 102 | connection.send(gamePadStateMessage(playerIndex, gamePad)); 103 | } 104 | else 105 | { 106 | e.cancel(); 107 | } 108 | }); 109 | } 110 | 111 | void _startServer(String host, int port) 112 | { 113 | // Create the websockets server 114 | HttpServer server = new HttpServer(); 115 | WebSocketHandler wsHandler = new WebSocketHandler(); 116 | server.addRequestHandler((req) => req.path == '/ws', wsHandler.onRequest); 117 | 118 | wsHandler.onOpen = _handleConnection; 119 | 120 | print('Starting server ${host}:${port}'); 121 | server.listen(host, port); 122 | } 123 | 124 | void main() 125 | { 126 | // Load configuration 127 | Path path = new Path('config.json'); 128 | File file = new File.fromPath(path); 129 | Future configuration = file.readAsText(Encoding.ASCII); 130 | 131 | configuration.onComplete((result) { 132 | // Set defaults 133 | String host = '127.0.0.1'; 134 | int port = 8000; 135 | 136 | if (result.hasValue) 137 | { 138 | Map config = JSON.parse(result.value); 139 | host = config['host']; 140 | port = config['port']; 141 | } 142 | else 143 | { 144 | print('config.json not found using defaults'); 145 | } 146 | 147 | _startServer(host, port); 148 | }); 149 | } 150 | -------------------------------------------------------------------------------- /server/src/Arguments.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * \file Arguments.hpp 3 | * 4 | * \section COPYRIGHT 5 | * 6 | * Dart Embedding Example 7 | * 8 | * --------------------------------------------------------------------- 9 | * 10 | * Copyright (c) 2012 Don Olmstead 11 | * 12 | * This software is provided 'as-is', without any express or implied 13 | * warranty. In no event will the authors be held liable for any damages 14 | * arising from the use of this software. 15 | * 16 | * Permission is granted to anyone to use this software for any purpose, 17 | * including commercial applications, and to alter it and redistribute it 18 | * freely, subject to the following restrictions: 19 | * 20 | * 1. The origin of this software must not be misrepresented; you must not 21 | * claim that you wrote the original software. If you use this software 22 | * in a product, an acknowledgment in the product documentation would be 23 | * appreciated but is not required. 24 | * 25 | * 2. Altered source versions must be plainly marked as such, and must not be 26 | * misrepresented as being the original software. 27 | * 28 | * 3. This notice may not be removed or altered from any source 29 | * distribution. 30 | */ 31 | 32 | #ifndef DART_EMBED_ARGUMENTS_HPP_INCLUDED 33 | #define DART_EMBED_ARGUMENTS_HPP_INCLUDED 34 | 35 | #include "dart_api.h" 36 | #include 37 | 38 | namespace DartEmbed 39 | { 40 | template 41 | void getNativeField(Dart_NativeArguments args, int index, T** value) 42 | { 43 | Dart_Handle handle = Dart_GetNativeArgument(args, index); 44 | 45 | assert(Dart_IsInstance(handle)); 46 | 47 | std::intptr_t ptr; 48 | Dart_GetNativeInstanceField(handle, 0, &ptr); 49 | 50 | *value = reinterpret_cast(ptr); 51 | } 52 | 53 | //---------------------------------------------------------------------- 54 | 55 | template 56 | void getValue(Dart_NativeArguments args, int index, T* value); 57 | 58 | //---------------------------------------------------------------------- 59 | 60 | template <> 61 | inline void getValue(Dart_NativeArguments args, int index, std::int32_t* value) 62 | { 63 | Dart_Handle handle = Dart_GetNativeArgument(args, index); 64 | 65 | assert(Dart_IsInteger(handle)); 66 | 67 | std::int64_t temp; 68 | Dart_IntegerToInt64(handle, &temp); 69 | 70 | *value = static_cast(temp); 71 | } 72 | 73 | //---------------------------------------------------------------------- 74 | 75 | template <> 76 | inline void getValue(Dart_NativeArguments args, int index, float* value) 77 | { 78 | Dart_Handle handle = Dart_GetNativeArgument(args, index); 79 | 80 | assert(Dart_IsDouble(handle)); 81 | 82 | double temp; 83 | Dart_DoubleValue(handle, &temp); 84 | 85 | *value = static_cast(temp); 86 | } 87 | 88 | //---------------------------------------------------------------------- 89 | 90 | template <> 91 | inline void getValue(Dart_NativeArguments args, int index, double* value) 92 | { 93 | Dart_Handle handle = Dart_GetNativeArgument(args, index); 94 | 95 | assert(Dart_IsDouble(handle)); 96 | 97 | Dart_DoubleValue(handle, value); 98 | } 99 | } // end namespace DartEmbed 100 | 101 | #endif // end DART_EMBED_ARGUMENTS_HPP_INCLUDED 102 | -------------------------------------------------------------------------------- /server/src/BuiltinLibraries.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * \file BuiltinLibraries.cpp 3 | * 4 | * \section COPYRIGHT 5 | * 6 | * Dart Embedding Example 7 | * 8 | * --------------------------------------------------------------------- 9 | * 10 | * Copyright (c) 2012 Don Olmstead 11 | * 12 | * This software is provided 'as-is', without any express or implied 13 | * warranty. In no event will the authors be held liable for any damages 14 | * arising from the use of this software. 15 | * 16 | * Permission is granted to anyone to use this software for any purpose, 17 | * including commercial applications, and to alter it and redistribute it 18 | * freely, subject to the following restrictions: 19 | * 20 | * 1. The origin of this software must not be misrepresented; you must not 21 | * claim that you wrote the original software. If you use this software 22 | * in a product, an acknowledgment in the product documentation would be 23 | * appreciated but is not required. 24 | * 25 | * 2. Altered source versions must be plainly marked as such, and must not be 26 | * misrepresented as being the original software. 27 | * 28 | * 3. This notice may not be removed or altered from any source 29 | * distribution. 30 | */ 31 | 32 | #include "BuiltinLibraries.hpp" 33 | #include "ScriptLibrary.hpp" 34 | using namespace DartEmbed; 35 | 36 | //--------------------------------------------------------------------- 37 | // Loads the builtin Dart libraries 38 | // 39 | // Currently there is no way to query the source for the builtin 40 | // libraries. Should probably be an extern value or an aux library 41 | // should provide a hook into it. 42 | // 43 | // The application is compiled into the snapshot so these values 44 | // are set to null. 45 | //--------------------------------------------------------------------- 46 | 47 | //--------------------------------------------------------------------- 48 | 49 | ScriptLibrary* BuiltinLibraries::createJsonLibrary() 50 | { 51 | return new ScriptLibrary("dart:json", 0); 52 | } 53 | 54 | //--------------------------------------------------------------------- 55 | 56 | ScriptLibrary* BuiltinLibraries::createUriLibrary() 57 | { 58 | return new ScriptLibrary("dart:uri", 0); 59 | } 60 | 61 | //--------------------------------------------------------------------- 62 | 63 | ScriptLibrary* BuiltinLibraries::createCryptoLibrary() 64 | { 65 | return new ScriptLibrary("dart:crypto", 0); 66 | } 67 | 68 | //--------------------------------------------------------------------- 69 | 70 | ScriptLibrary* BuiltinLibraries::createUtfLibrary() 71 | { 72 | return new ScriptLibrary("dart:utf", 0); 73 | } 74 | -------------------------------------------------------------------------------- /server/src/BuiltinLibraries.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * \file BuiltinLibraries.hpp 3 | * 4 | * \section COPYRIGHT 5 | * 6 | * Dart Embedding Example 7 | * 8 | * --------------------------------------------------------------------- 9 | * 10 | * Copyright (c) 2012 Don Olmstead 11 | * 12 | * This software is provided 'as-is', without any express or implied 13 | * warranty. In no event will the authors be held liable for any damages 14 | * arising from the use of this software. 15 | * 16 | * Permission is granted to anyone to use this software for any purpose, 17 | * including commercial applications, and to alter it and redistribute it 18 | * freely, subject to the following restrictions: 19 | * 20 | * 1. The origin of this software must not be misrepresented; you must not 21 | * claim that you wrote the original software. If you use this software 22 | * in a product, an acknowledgment in the product documentation would be 23 | * appreciated but is not required. 24 | * 25 | * 2. Altered source versions must be plainly marked as such, and must not be 26 | * misrepresented as being the original software. 27 | * 28 | * 3. This notice may not be removed or altered from any source 29 | * distribution. 30 | */ 31 | 32 | #ifndef DART_EMBED_BUILTIN_LIBRARIES_HPP_INCLUDED 33 | #define DART_EMBED_BUILTIN_LIBRARIES_HPP_INCLUDED 34 | 35 | //--------------------------------------------------------------------- 36 | // Defines taken from builtin.h 37 | // 38 | // Used to reference the native entries within the VM. 39 | //--------------------------------------------------------------------- 40 | 41 | #define FUNCTION_NAME(name) Builtin_##name 42 | #define DECLARE_FUNCTION(name, count) \ 43 | extern void FUNCTION_NAME(name)(Dart_NativeArguments args); 44 | 45 | namespace DartEmbed 46 | { 47 | //--------------------------------------------------------------------- 48 | // Forward declarations 49 | //--------------------------------------------------------------------- 50 | 51 | class ScriptLibrary; 52 | 53 | /** 54 | * Creates the libraries bundled with Dart. 55 | */ 56 | namespace BuiltinLibraries 57 | { 58 | /** 59 | * Creates the dart:builtin library. 60 | * 61 | * \returns The dart:builtin library. 62 | */ 63 | ScriptLibrary* createCoreLibrary(); 64 | 65 | /** 66 | * Creates the dart:io library. 67 | * 68 | * \returns The dart:io library. 69 | */ 70 | ScriptLibrary* createIOLibrary(); 71 | 72 | /** 73 | * Creates the dart:json library. 74 | * 75 | * \returns The dart:json library. 76 | */ 77 | ScriptLibrary* createJsonLibrary(); 78 | 79 | /** 80 | * Creates the dart:uri library. 81 | * 82 | * \returns The dart:uri library. 83 | */ 84 | ScriptLibrary* createUriLibrary(); 85 | 86 | /** 87 | * Creates the dart:crypto library. 88 | * 89 | * \returns The dart:crypto library. 90 | */ 91 | ScriptLibrary* createCryptoLibrary(); 92 | 93 | /** 94 | * Creates the dart:utf library. 95 | * 96 | * \returns The dart:utf library. 97 | */ 98 | ScriptLibrary* createUtfLibrary(); 99 | 100 | /** 101 | * Creates the embed:input library. 102 | * 103 | * \returns The embed:input library. 104 | */ 105 | ScriptLibrary* createInputLibrary(); 106 | } // end namespace BuitlinLibraries 107 | } // end namespace DartEmbed 108 | 109 | #endif // end DART_EMBED_BUILTIN_LIBRARIES_HPP_INCLUDED 110 | -------------------------------------------------------------------------------- /server/src/CoreLibrary.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * \file CoreLibrary.cpp 3 | * 4 | * \section COPYRIGHT 5 | * 6 | * Dart Embedding Example 7 | * 8 | * --------------------------------------------------------------------- 9 | * 10 | * Copyright (c) 2012 Don Olmstead 11 | * 12 | * This software is provided 'as-is', without any express or implied 13 | * warranty. In no event will the authors be held liable for any damages 14 | * arising from the use of this software. 15 | * 16 | * Permission is granted to anyone to use this software for any purpose, 17 | * including commercial applications, and to alter it and redistribute it 18 | * freely, subject to the following restrictions: 19 | * 20 | * 1. The origin of this software must not be misrepresented; you must not 21 | * claim that you wrote the original software. If you use this software 22 | * in a product, an acknowledgment in the product documentation would be 23 | * appreciated but is not required. 24 | * 25 | * 2. Altered source versions must be plainly marked as such, and must not be 26 | * misrepresented as being the original software. 27 | * 28 | * 3. This notice may not be removed or altered from any source 29 | * distribution. 30 | */ 31 | 32 | #include "BuiltinLibraries.hpp" 33 | #include "ScriptLibrary.hpp" 34 | #include "NativeResolution.hpp" 35 | using namespace DartEmbed; 36 | 37 | //--------------------------------------------------------------------- 38 | // Native functions 39 | //--------------------------------------------------------------------- 40 | 41 | DECLARE_FUNCTION(Exit, 1) 42 | DECLARE_FUNCTION(Logger_PrintString, 1) 43 | 44 | namespace 45 | { 46 | /// Whether the library has been initialized 47 | bool __libraryInitialized = false; 48 | /// Native entries for the core library 49 | NativeEntry __coreNativeEntries[3]; 50 | 51 | /** 52 | * Sets up the native entries for the core library. 53 | */ 54 | void __setupCoreLibrary() 55 | { 56 | if (!__libraryInitialized) 57 | { 58 | // There aren't enough entries to warrant the class/function 59 | // lookup mechanism. Just setup the native entries 60 | setNativeEntry(&__coreNativeEntries[0], "Exit", FUNCTION_NAME(Exit), 1); 61 | setNativeEntry(&__coreNativeEntries[1], "Logger_PrintString", FUNCTION_NAME(Logger_PrintString), 1); 62 | // Set the sentinal value 63 | setNativeEntry(&__coreNativeEntries[2], "", 0, 0); 64 | } 65 | 66 | __libraryInitialized = true; 67 | } 68 | 69 | /** 70 | * Native resolver for the core library. 71 | * 72 | * \param name The name of the function to invoke. 73 | * \param argumentCount The number of arguments. 74 | */ 75 | Dart_NativeFunction __coreLibraryResolver(Dart_Handle name, int argumentCount) 76 | { 77 | const char* nativeFunctionName = 0; 78 | Dart_Handle result = Dart_StringToCString(name, &nativeFunctionName); 79 | 80 | assert(nativeFunctionName); 81 | 82 | std::int32_t hash = fnv1aHash(nativeFunctionName); 83 | 84 | NativeEntry* functionEntry = __coreNativeEntries; 85 | 86 | while (functionEntry->function != 0) 87 | { 88 | if (functionEntry->hash == hash) 89 | { 90 | assert(functionEntry->argumentCount == argumentCount); 91 | return functionEntry->function; 92 | } 93 | 94 | functionEntry++; 95 | } 96 | 97 | return 0; 98 | } 99 | } // end anonymous namespace 100 | 101 | //--------------------------------------------------------------------- 102 | 103 | ScriptLibrary* BuiltinLibraries::createCoreLibrary() 104 | { 105 | // Setup the native entries 106 | __setupCoreLibrary(); 107 | 108 | // The library source is compiled in along with the snapshot. 109 | // Native entries are present within the library so a resolver needs to be set. 110 | // IO initializer allows some functions to be called before the library is used. 111 | return new ScriptLibrary("dart:builtin", 0, __coreLibraryResolver); 112 | } 113 | -------------------------------------------------------------------------------- /server/src/EmbedLibraries.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * \file EmbedLibraries.hpp 3 | * 4 | * \section COPYRIGHT 5 | * 6 | * Dart Embedding Example 7 | * 8 | * --------------------------------------------------------------------- 9 | * 10 | * Copyright (c) 2012 Don Olmstead 11 | * 12 | * This software is provided 'as-is', without any express or implied 13 | * warranty. In no event will the authors be held liable for any damages 14 | * arising from the use of this software. 15 | * 16 | * Permission is granted to anyone to use this software for any purpose, 17 | * including commercial applications, and to alter it and redistribute it 18 | * freely, subject to the following restrictions: 19 | * 20 | * 1. The origin of this software must not be misrepresented; you must not 21 | * claim that you wrote the original software. If you use this software 22 | * in a product, an acknowledgment in the product documentation would be 23 | * appreciated but is not required. 24 | * 25 | * 2. Altered source versions must be plainly marked as such, and must not be 26 | * misrepresented as being the original software. 27 | * 28 | * 3. This notice may not be removed or altered from any source 29 | * distribution. 30 | */ 31 | 32 | #ifndef DART_EMBED_EMBED_LIBRARIES_HPP_INCLUDED 33 | #define DART_EMBED_EMEBD_LIBRARIES_HPP_INCLUDED 34 | 35 | namespace DartEmbed 36 | { 37 | /** 38 | * Creates the libraries embeded within the application. 39 | */ 40 | namespace EmbedLibraries 41 | { 42 | /** 43 | * Loads the input library. 44 | */ 45 | void createInputLibrary(); 46 | } // end namespace EmbedLibraries 47 | } // end namespace DartEmbed 48 | 49 | #endif // end DART_EMEBED_EMBED_LIBRARIES_HPP_INCLUDED 50 | -------------------------------------------------------------------------------- /server/src/GamePad.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * \file GamePad.hpp 3 | * 4 | * \section COPYRIGHT 5 | * 6 | * Dart Embedding Example 7 | * 8 | * --------------------------------------------------------------------- 9 | * 10 | * Copyright (c) 2012 Don Olmstead 11 | * 12 | * This software is provided 'as-is', without any express or implied 13 | * warranty. In no event will the authors be held liable for any damages 14 | * arising from the use of this software. 15 | * 16 | * Permission is granted to anyone to use this software for any purpose, 17 | * including commercial applications, and to alter it and redistribute it 18 | * freely, subject to the following restrictions: 19 | * 20 | * 1. The origin of this software must not be misrepresented; you must not 21 | * claim that you wrote the original software. If you use this software 22 | * in a product, an acknowledgment in the product documentation would be 23 | * appreciated but is not required. 24 | * 25 | * 2. Altered source versions must be plainly marked as such, and must not be 26 | * misrepresented as being the original software. 27 | * 28 | * 3. This notice may not be removed or altered from any source 29 | * distribution. 30 | */ 31 | 32 | #include 33 | #include "PlatformWindows.hpp" 34 | using namespace DartEmbed; 35 | 36 | namespace 37 | { 38 | /// The current state of the controllers 39 | GamePadState __gamePadState[PlayerIndex::Size]; 40 | } // end anonymous namespace 41 | 42 | //---------------------------------------------------------------------- 43 | 44 | GamePadState::GamePadState() 45 | : _connected(false) 46 | , _packetNumber(0) 47 | , _leftThumbstickX(0.0f) 48 | , _leftThumbstickY(0.0f) 49 | , _rightThumbstickX(0.0f) 50 | , _rightThumbstickY(0.0f) 51 | , _leftTrigger(0.0f) 52 | , _rightTrigger(0.0f) 53 | , _buttons(0) 54 | { } 55 | 56 | //---------------------------------------------------------------------- 57 | 58 | GamePadState::GamePadState(const GamePadState& copy) 59 | : _connected(copy._connected) 60 | , _packetNumber(copy._packetNumber) 61 | , _leftThumbstickX(copy._leftThumbstickX) 62 | , _leftThumbstickY(copy._leftThumbstickY) 63 | , _rightThumbstickX(copy._rightThumbstickX) 64 | , _rightThumbstickY(copy._rightThumbstickY) 65 | , _leftTrigger(copy._leftTrigger) 66 | , _rightTrigger(copy._rightTrigger) 67 | , _buttons(copy._buttons) 68 | { } 69 | 70 | //---------------------------------------------------------------------- 71 | 72 | GamePadState& GamePadState::operator= (const GamePadState& copy) 73 | { 74 | _connected = copy._connected; 75 | _packetNumber = copy._packetNumber; 76 | 77 | _leftThumbstickX = copy._leftThumbstickX; 78 | _leftThumbstickY = copy._leftThumbstickY; 79 | 80 | _rightThumbstickX = copy._rightThumbstickX; 81 | _rightThumbstickY = copy._rightThumbstickY; 82 | 83 | _leftTrigger = copy._leftTrigger; 84 | _rightTrigger = copy._rightTrigger; 85 | 86 | _buttons = copy._buttons; 87 | 88 | return *this; 89 | } 90 | 91 | //---------------------------------------------------------------------- 92 | 93 | const GamePadState& GamePad::getState(PlayerIndex::Enum player) 94 | { 95 | return __gamePadState[player]; 96 | } 97 | 98 | //---------------------------------------------------------------------- 99 | 100 | void GamePad::setVibration(PlayerIndex::Enum player, const float leftMotor, const float rightMotor) 101 | { 102 | XINPUT_VIBRATION vibration; 103 | ZeroMemory(&vibration, sizeof(XINPUT_VIBRATION)); 104 | vibration.wLeftMotorSpeed = (std::uint16_t)(leftMotor * 65535.0f); 105 | vibration.wRightMotorSpeed = (std::uint16_t)(rightMotor * 65535.0f); 106 | 107 | XInputSetState(player, &vibration); 108 | } 109 | 110 | //---------------------------------------------------------------------- 111 | 112 | void updateGamePads() 113 | { 114 | DWORD result; 115 | 116 | for (DWORD i = 0; i < PlayerIndex::Size; ++i) 117 | { 118 | XINPUT_STATE state; 119 | ZeroMemory(&state, sizeof(XINPUT_STATE)); 120 | 121 | // Get the state of the controller 122 | result = XInputGetState(i, &state); 123 | 124 | // Get the gamepad 125 | GamePadState& gamePad = __gamePadState[i]; 126 | 127 | if (result == ERROR_SUCCESS) 128 | { 129 | gamePad.setConnected(true); 130 | std::int32_t packetNumber = state.dwPacketNumber; 131 | 132 | // See if the packet number has changed 133 | if (gamePad.getPacketNumber() != packetNumber) 134 | { 135 | gamePad.setPacketNumber(packetNumber); 136 | 137 | // Set the thumbsticks 138 | gamePad.setLeftThumbstickX ((float)state.Gamepad.sThumbLX / 32767.0f); 139 | gamePad.setLeftThumbstickY ((float)state.Gamepad.sThumbLY / 32767.0f); 140 | gamePad.setRightThumbstickX((float)state.Gamepad.sThumbRX / 32767.0f); 141 | gamePad.setRightThumbstickY((float)state.Gamepad.sThumbRY / 32767.0f); 142 | 143 | // Set the trigger 144 | gamePad.setLeftTrigger((float)state.Gamepad.bLeftTrigger / 255.0f); 145 | gamePad.setRightTrigger((float)state.Gamepad.bRightTrigger / 255.0f); 146 | 147 | // Set the buttons 148 | gamePad.setButtons(state.Gamepad.wButtons); 149 | } 150 | } 151 | else 152 | { 153 | // Zero out the values 154 | gamePad.setConnected(false); 155 | gamePad.setPacketNumber(0); 156 | 157 | // Set the thumbsticks 158 | gamePad.setLeftThumbstickX(0.0f); 159 | gamePad.setLeftThumbstickY(0.0f); 160 | gamePad.setRightThumbstickX(0.0f); 161 | gamePad.setRightThumbstickY(0.0f); 162 | 163 | // Set the trigger 164 | gamePad.setLeftTrigger(0.0f); 165 | gamePad.setRightTrigger(0.0f); 166 | 167 | // Set the buttons 168 | gamePad.setButtons(0); 169 | } 170 | } 171 | } 172 | -------------------------------------------------------------------------------- /server/src/IOLibrary.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * \file IOLibrary.cpp 3 | * 4 | * \section COPYRIGHT 5 | * 6 | * Dart Embedding Example 7 | * 8 | * --------------------------------------------------------------------- 9 | * 10 | * Copyright (c) 2012 Don Olmstead 11 | * 12 | * This software is provided 'as-is', without any express or implied 13 | * warranty. In no event will the authors be held liable for any damages 14 | * arising from the use of this software. 15 | * 16 | * Permission is granted to anyone to use this software for any purpose, 17 | * including commercial applications, and to alter it and redistribute it 18 | * freely, subject to the following restrictions: 19 | * 20 | * 1. The origin of this software must not be misrepresented; you must not 21 | * claim that you wrote the original software. If you use this software 22 | * in a product, an acknowledgment in the product documentation would be 23 | * appreciated but is not required. 24 | * 25 | * 2. Altered source versions must be plainly marked as such, and must not be 26 | * misrepresented as being the original software. 27 | * 28 | * 3. This notice may not be removed or altered from any source 29 | * distribution. 30 | */ 31 | 32 | #include "BuiltinLibraries.hpp" 33 | #include "ScriptLibrary.hpp" 34 | #include "NativeResolution.hpp" 35 | using namespace DartEmbed; 36 | 37 | //--------------------------------------------------------------------- 38 | // Directory functions 39 | //--------------------------------------------------------------------- 40 | 41 | DECLARE_FUNCTION(Directory_Exists, 1) 42 | DECLARE_FUNCTION(Directory_Create, 1) 43 | DECLARE_FUNCTION(Directory_Current, 0) 44 | DECLARE_FUNCTION(Directory_CreateTemp, 1) 45 | DECLARE_FUNCTION(Directory_Delete, 2) 46 | DECLARE_FUNCTION(Directory_Rename, 2) 47 | DECLARE_FUNCTION(Directory_NewServicePort, 0) 48 | 49 | //--------------------------------------------------------------------- 50 | // EventHandler functions 51 | //--------------------------------------------------------------------- 52 | 53 | DECLARE_FUNCTION(EventHandler_Start, 1) \ 54 | DECLARE_FUNCTION(EventHandler_SendData, 4) 55 | 56 | //--------------------------------------------------------------------- 57 | // File functions 58 | //--------------------------------------------------------------------- 59 | 60 | DECLARE_FUNCTION(File_Open, 2) 61 | DECLARE_FUNCTION(File_Exists, 1) 62 | DECLARE_FUNCTION(File_Close, 1) 63 | DECLARE_FUNCTION(File_ReadByte, 1) 64 | DECLARE_FUNCTION(File_WriteByte, 2) 65 | DECLARE_FUNCTION(File_WriteString, 2) 66 | DECLARE_FUNCTION(File_ReadList, 4) 67 | DECLARE_FUNCTION(File_WriteList, 4) 68 | DECLARE_FUNCTION(File_Position, 1) 69 | DECLARE_FUNCTION(File_SetPosition, 2) 70 | DECLARE_FUNCTION(File_Truncate, 2) 71 | DECLARE_FUNCTION(File_Length, 1) 72 | DECLARE_FUNCTION(File_LengthFromName, 1) 73 | DECLARE_FUNCTION(File_LastModified, 1) 74 | DECLARE_FUNCTION(File_Flush, 1) 75 | DECLARE_FUNCTION(File_Create, 1) 76 | DECLARE_FUNCTION(File_Delete, 1) 77 | DECLARE_FUNCTION(File_Directory, 1) 78 | DECLARE_FUNCTION(File_FullPath, 1) 79 | DECLARE_FUNCTION(File_OpenStdio, 1) 80 | DECLARE_FUNCTION(File_GetStdioHandleType, 1) 81 | DECLARE_FUNCTION(File_NewServicePort, 0) 82 | 83 | //--------------------------------------------------------------------- 84 | // Platform functions 85 | //--------------------------------------------------------------------- 86 | 87 | DECLARE_FUNCTION(Platform_NumberOfProcessors, 0) 88 | DECLARE_FUNCTION(Platform_OperatingSystem, 0) 89 | DECLARE_FUNCTION(Platform_PathSeparator, 0) 90 | DECLARE_FUNCTION(Platform_LocalHostname, 0) 91 | DECLARE_FUNCTION(Platform_Environment, 0) 92 | 93 | //--------------------------------------------------------------------- 94 | // Process functions 95 | //--------------------------------------------------------------------- 96 | 97 | DECLARE_FUNCTION(Process_Start, 10) 98 | DECLARE_FUNCTION(Process_Kill, 3) 99 | 100 | //--------------------------------------------------------------------- 101 | // ServerSocket functions 102 | //--------------------------------------------------------------------- 103 | 104 | DECLARE_FUNCTION(ServerSocket_CreateBindListen, 4) 105 | DECLARE_FUNCTION(ServerSocket_Accept, 2) 106 | 107 | //--------------------------------------------------------------------- 108 | // Socket functions 109 | //--------------------------------------------------------------------- 110 | 111 | DECLARE_FUNCTION(Socket_CreateConnect, 3) 112 | DECLARE_FUNCTION(Socket_Available, 1) 113 | DECLARE_FUNCTION(Socket_ReadList, 4) 114 | DECLARE_FUNCTION(Socket_WriteList, 4) 115 | DECLARE_FUNCTION(Socket_GetPort, 1) 116 | DECLARE_FUNCTION(Socket_GetRemotePeer, 1) 117 | DECLARE_FUNCTION(Socket_GetError, 1) 118 | DECLARE_FUNCTION(Socket_GetStdioHandle, 2) 119 | DECLARE_FUNCTION(Socket_NewServicePort, 0) 120 | 121 | namespace 122 | { 123 | /// Whether the library has been initialized 124 | bool __libraryInitialized = false; 125 | /// Class entries for the IO library 126 | NativeClassEntry __libraryEntries[8]; 127 | 128 | /// Native entries for the Directory class 129 | NativeEntry __directoryNativeEntries[8]; 130 | /// Native entries for the EventHandlerClass 131 | NativeEntry __eventHandlerNativeEntries[3]; 132 | /// Native entries for the File class 133 | NativeEntry __fileNativeEntries[23]; 134 | /// Native entries for the Platform class 135 | NativeEntry __platformNativeEntries[6]; 136 | /// Native entries for the Process class 137 | NativeEntry __processNativeEntries[3]; 138 | /// Native entries for the ServerSocket class 139 | NativeEntry __serverSocketNativeEntries[3]; 140 | /// Native entries for the Socket class 141 | NativeEntry __socketNativeEntries[10]; 142 | 143 | /** 144 | * Setup hooks to the Directory class entries. 145 | */ 146 | void __setupDirectoryEntries() 147 | { 148 | setNativeEntry(&__directoryNativeEntries[0], "Exists", FUNCTION_NAME(Directory_Exists), 1); 149 | setNativeEntry(&__directoryNativeEntries[1], "Create", FUNCTION_NAME(Directory_Create), 1); 150 | setNativeEntry(&__directoryNativeEntries[2], "Current", FUNCTION_NAME(Directory_Current), 0); 151 | setNativeEntry(&__directoryNativeEntries[3], "CreateTemp", FUNCTION_NAME(Directory_CreateTemp), 1); 152 | setNativeEntry(&__directoryNativeEntries[4], "Delete", FUNCTION_NAME(Directory_Delete), 2); 153 | setNativeEntry(&__directoryNativeEntries[5], "Rename", FUNCTION_NAME(Directory_Rename), 2); 154 | setNativeEntry(&__directoryNativeEntries[6], "NewServicePort", FUNCTION_NAME(Directory_NewServicePort), 0); 155 | // Set the sentinal value 156 | setNativeEntry(&__directoryNativeEntries[7], "", 0, 0); 157 | } 158 | 159 | /** 160 | * Setup hooks to the EventHandler class entries. 161 | */ 162 | void __setupEventHandlerEntries() 163 | { 164 | setNativeEntry(&__eventHandlerNativeEntries[0], "Start", FUNCTION_NAME(EventHandler_Start), 1); 165 | setNativeEntry(&__eventHandlerNativeEntries[1], "SendData", FUNCTION_NAME(EventHandler_SendData), 4); 166 | // Set the sentinal value 167 | setNativeEntry(&__eventHandlerNativeEntries[2], "", 0, 0); 168 | } 169 | 170 | /** 171 | * Setup hooks to the File class entries. 172 | */ 173 | void __setupFileEntries() 174 | { 175 | setNativeEntry(&__fileNativeEntries[ 0], "Open", FUNCTION_NAME(File_Open), 2); 176 | setNativeEntry(&__fileNativeEntries[ 1], "Exists", FUNCTION_NAME(File_Exists), 1); 177 | setNativeEntry(&__fileNativeEntries[ 2], "Close", FUNCTION_NAME(File_Close), 1); 178 | setNativeEntry(&__fileNativeEntries[ 3], "ReadByte", FUNCTION_NAME(File_ReadByte), 1); 179 | setNativeEntry(&__fileNativeEntries[ 4], "WriteByte", FUNCTION_NAME(File_WriteByte), 2); 180 | setNativeEntry(&__fileNativeEntries[ 5], "WriteString", FUNCTION_NAME(File_WriteString), 2); 181 | setNativeEntry(&__fileNativeEntries[ 6], "ReadList", FUNCTION_NAME(File_ReadList), 4); 182 | setNativeEntry(&__fileNativeEntries[ 7], "WriteList", FUNCTION_NAME(File_WriteList), 4); 183 | setNativeEntry(&__fileNativeEntries[ 8], "Position", FUNCTION_NAME(File_Position), 1); 184 | setNativeEntry(&__fileNativeEntries[ 9], "SetPosition", FUNCTION_NAME(File_SetPosition), 2); 185 | setNativeEntry(&__fileNativeEntries[10], "Truncate", FUNCTION_NAME(File_Truncate), 2); 186 | setNativeEntry(&__fileNativeEntries[11], "Length", FUNCTION_NAME(File_Length), 1); 187 | setNativeEntry(&__fileNativeEntries[12], "LengthFromName", FUNCTION_NAME(File_LengthFromName), 1); 188 | setNativeEntry(&__fileNativeEntries[13], "LastModified", FUNCTION_NAME(File_LastModified), 1); 189 | setNativeEntry(&__fileNativeEntries[14], "Flush", FUNCTION_NAME(File_Flush), 1); 190 | setNativeEntry(&__fileNativeEntries[15], "Create", FUNCTION_NAME(File_Create), 1); 191 | setNativeEntry(&__fileNativeEntries[16], "Delete", FUNCTION_NAME(File_Delete), 1); 192 | setNativeEntry(&__fileNativeEntries[17], "Directory", FUNCTION_NAME(File_Directory), 1); 193 | setNativeEntry(&__fileNativeEntries[18], "FullPath", FUNCTION_NAME(File_FullPath), 1); 194 | setNativeEntry(&__fileNativeEntries[19], "OpenStdio", FUNCTION_NAME(File_OpenStdio), 1); 195 | setNativeEntry(&__fileNativeEntries[20], "GetStdioHandleType", FUNCTION_NAME(File_GetStdioHandleType), 1); 196 | setNativeEntry(&__fileNativeEntries[21], "NewServicePort", FUNCTION_NAME(File_NewServicePort), 0); 197 | // Set the sentinal value 198 | setNativeEntry(&__fileNativeEntries[22], "", 0, 0); 199 | } 200 | 201 | /** 202 | * Setup hooks to the Platform class entries. 203 | */ 204 | void __setupPlatformEntries() 205 | { 206 | setNativeEntry(&__platformNativeEntries[0], "NumberOfProcessors", FUNCTION_NAME(Platform_NumberOfProcessors), 0); 207 | setNativeEntry(&__platformNativeEntries[1], "OperatingSystem", FUNCTION_NAME(Platform_OperatingSystem), 0); 208 | setNativeEntry(&__platformNativeEntries[2], "PathSeparator", FUNCTION_NAME(Platform_PathSeparator), 0); 209 | setNativeEntry(&__platformNativeEntries[3], "LocalHostname", FUNCTION_NAME(Platform_LocalHostname), 0); 210 | setNativeEntry(&__platformNativeEntries[4], "Environment", FUNCTION_NAME(Platform_Environment), 0); 211 | // Set the sentinal value 212 | setNativeEntry(&__platformNativeEntries[5], "", 0, 0); 213 | } 214 | 215 | /** 216 | * Setup hooks to the Process class entries. 217 | */ 218 | void __setupProcessEntries() 219 | { 220 | setNativeEntry(&__processNativeEntries[0], "Start", FUNCTION_NAME(Process_Start), 10); 221 | setNativeEntry(&__processNativeEntries[1], "Kill", FUNCTION_NAME(Process_Kill), 3); 222 | // Set the sentinal value 223 | setNativeEntry(&__processNativeEntries[2], "", 0, 0); 224 | } 225 | 226 | /** 227 | * Setup hooks to the ServerSocket class entries. 228 | */ 229 | void __setupServerSocketEntries() 230 | { 231 | setNativeEntry(&__serverSocketNativeEntries[0], "CreateBindListen", FUNCTION_NAME(ServerSocket_CreateBindListen), 4); 232 | setNativeEntry(&__serverSocketNativeEntries[1], "Accept", FUNCTION_NAME(ServerSocket_Accept), 2); 233 | // Set the sentinal value 234 | setNativeEntry(&__serverSocketNativeEntries[2], "", 0, 0); 235 | } 236 | 237 | /** 238 | * Setup hooks to the Socket class entries. 239 | */ 240 | void __setupSocketEntries() 241 | { 242 | setNativeEntry(&__socketNativeEntries[0], "CreateConnect", FUNCTION_NAME(Socket_CreateConnect), 3); 243 | setNativeEntry(&__socketNativeEntries[1], "Available", FUNCTION_NAME(Socket_Available), 1); 244 | setNativeEntry(&__socketNativeEntries[2], "ReadList", FUNCTION_NAME(Socket_ReadList), 4); 245 | setNativeEntry(&__socketNativeEntries[3], "WriteList", FUNCTION_NAME(Socket_WriteList), 4); 246 | setNativeEntry(&__socketNativeEntries[4], "GetPort", FUNCTION_NAME(Socket_GetPort), 1); 247 | setNativeEntry(&__socketNativeEntries[5], "GetRemotePeer", FUNCTION_NAME(Socket_GetRemotePeer), 1); 248 | setNativeEntry(&__socketNativeEntries[6], "GetError", FUNCTION_NAME(Socket_GetError), 1); 249 | setNativeEntry(&__socketNativeEntries[7], "GetStdioHandle", FUNCTION_NAME(Socket_GetStdioHandle), 2); 250 | setNativeEntry(&__socketNativeEntries[8], "NewServicePort", FUNCTION_NAME(Socket_NewServicePort), 0); 251 | // Set the sentinal value 252 | setNativeEntry(&__socketNativeEntries[9], "", 0, 0); 253 | } 254 | 255 | /** 256 | * Setup the class entries. 257 | */ 258 | void __setupClassEntries() 259 | { 260 | setNativeClassEntry(&__libraryEntries[0], "Directory", __directoryNativeEntries); 261 | setNativeClassEntry(&__libraryEntries[1], "EventHandler", __eventHandlerNativeEntries); 262 | setNativeClassEntry(&__libraryEntries[2], "File", __fileNativeEntries); 263 | setNativeClassEntry(&__libraryEntries[3], "Platform", __platformNativeEntries); 264 | setNativeClassEntry(&__libraryEntries[4], "Process", __processNativeEntries); 265 | setNativeClassEntry(&__libraryEntries[5], "ServerSocket", __serverSocketNativeEntries); 266 | setNativeClassEntry(&__libraryEntries[6], "Socket", __socketNativeEntries); 267 | // Set the sentinal value 268 | setNativeClassEntry(&__libraryEntries[7], "", 0); 269 | } 270 | 271 | /** 272 | * Sets up the native entries for the IO library. 273 | */ 274 | void __setupIOLibrary() 275 | { 276 | if (!__libraryInitialized) 277 | { 278 | __setupClassEntries(); 279 | 280 | __setupDirectoryEntries(); 281 | __setupEventHandlerEntries(); 282 | __setupFileEntries(); 283 | __setupPlatformEntries(); 284 | __setupProcessEntries(); 285 | __setupServerSocketEntries(); 286 | __setupSocketEntries(); 287 | } 288 | 289 | __libraryInitialized = true; 290 | } 291 | 292 | /** 293 | * Native resolver for the dart:io library. 294 | */ 295 | //CREATE_NATIVE_RESOLVER(__ioLibraryResolver, __libraryEntries) 296 | Dart_NativeFunction __ioLibraryResolver(Dart_Handle name, int argumentCount) 297 | { 298 | const char* nativeFunctionName = 0; 299 | Dart_Handle result = Dart_StringToCString(name, &nativeFunctionName); 300 | 301 | assert(nativeFunctionName); 302 | 303 | NativeCallHash hash; 304 | fnv1aHashFunctionCall(nativeFunctionName, &hash); 305 | 306 | NativeClassEntry* classEntry = __libraryEntries; 307 | 308 | while (classEntry->entries != 0) 309 | { 310 | NativeEntry* functionEntry = classEntry->entries; 311 | 312 | if (classEntry->hash == hash.classHash) 313 | { 314 | while (functionEntry->function != 0) 315 | { 316 | if (functionEntry->hash == hash.functionHash) 317 | { 318 | assert(functionEntry->argumentCount == argumentCount); 319 | return functionEntry->function; 320 | } 321 | 322 | functionEntry++; 323 | } 324 | 325 | return 0; 326 | } 327 | 328 | classEntry++; 329 | } 330 | 331 | return 0; 332 | } 333 | 334 | /** 335 | * Initialize the dart:io library. 336 | * 337 | * \param library The IO library to initialize. 338 | */ 339 | void __ioLibraryInitializer(Dart_Handle library) 340 | { 341 | Dart_Handle timerClosure = Dart_Invoke(library, Dart_NewString("_getTimerFactoryClosure"), 0, 0); 342 | Dart_Handle isolateLibrary = Dart_LookupLibrary(Dart_NewString("dart:isolate")); 343 | 344 | Dart_Handle args[1]; 345 | args[0] = timerClosure; 346 | Dart_Handle result = Dart_Invoke(isolateLibrary, Dart_NewString("_setTimerFactoryClosure"), 1, args); 347 | } 348 | } // end anonymous namespace 349 | 350 | //--------------------------------------------------------------------- 351 | 352 | ScriptLibrary* BuiltinLibraries::createIOLibrary() 353 | { 354 | // Setup the native entries 355 | __setupIOLibrary(); 356 | 357 | // The library source is compiled in along with the snapshot. 358 | // Native entries are present within the library so a resolver needs to be set. 359 | // IO initializer allows some functions to be called before the library is used. 360 | return new ScriptLibrary("dart:io", 0, __ioLibraryResolver, __ioLibraryInitializer); 361 | } 362 | -------------------------------------------------------------------------------- /server/src/InputLibrary.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * \file InputLibrary.cpp 3 | * 4 | * \section COPYRIGHT 5 | * 6 | * Dart Embedding Example 7 | * 8 | * --------------------------------------------------------------------- 9 | * 10 | * Copyright (c) 2012 Don Olmstead 11 | * 12 | * This software is provided 'as-is', without any express or implied 13 | * warranty. In no event will the authors be held liable for any damages 14 | * arising from the use of this software. 15 | * 16 | * Permission is granted to anyone to use this software for any purpose, 17 | * including commercial applications, and to alter it and redistribute it 18 | * freely, subject to the following restrictions: 19 | * 20 | * 1. The origin of this software must not be misrepresented; you must not 21 | * claim that you wrote the original software. If you use this software 22 | * in a product, an acknowledgment in the product documentation would be 23 | * appreciated but is not required. 24 | * 25 | * 2. Altered source versions must be plainly marked as such, and must not be 26 | * misrepresented as being the original software. 27 | * 28 | * 3. This notice may not be removed or altered from any source 29 | * distribution. 30 | */ 31 | 32 | #include "EmbedLibraries.hpp" 33 | #include 34 | #include 35 | #include "Arguments.hpp" 36 | #include "ScriptLibrary.hpp" 37 | #include "NativeResolution.hpp" 38 | using namespace DartEmbed; 39 | 40 | namespace 41 | { 42 | //--------------------------------------------------------------------- 43 | // Source code 44 | //--------------------------------------------------------------------- 45 | 46 | const char* __sourceCode = 47 | "#library('embed:input');\n" 48 | "#import('dart:nativewrappers');\n" 49 | "\n" 50 | "class GamePadState extends NativeFieldWrapperClass1\n" 51 | "{\n" 52 | " GamePadState() { _initialize(); }\n" 53 | " void _initialize() native 'GamePadState_New';\n" 54 | " bool get isConnected() native 'GamePadState_IsConnected';\n" 55 | " double get leftThumbstickX() native 'GamePadState_GetLeftThumbstickX';\n" 56 | " double get leftThumbstickY() native 'GamePadState_GetLeftThumbstickY';\n" 57 | " double get rightThumbstickX() native 'GamePadState_GetRightThumbstickX';\n" 58 | " double get rightThumbstickY() native 'GamePadState_GetRightThumbstickY';\n" 59 | " double get leftTrigger() native 'GamePadState_GetLeftTrigger';\n" 60 | " double get rightTrigger() native 'GamePadState_GetRightTrigger';\n" 61 | " int get buttons() native 'GamePadState_GetButtons';\n" 62 | "}\n" 63 | "\n" 64 | "class GamePad\n" 65 | "{\n" 66 | " static void getState(int index, GamePadState state) native 'GamePad_GetState';\n" 67 | " static void setVibration(int index, double leftMotor, double rightMotor) native 'GamePad_SetVibration';\n" 68 | "}\n"; 69 | 70 | //--------------------------------------------------------------------- 71 | // Native functions 72 | //--------------------------------------------------------------------- 73 | 74 | inline PlayerIndex::Enum __getPlayerIndex(Dart_NativeArguments args, int index) 75 | { 76 | std::int32_t player; 77 | getValue(args, 0, &player); 78 | 79 | if ((player < 0) || (player >= PlayerIndex::Size)) 80 | return PlayerIndex::One; 81 | else 82 | return static_cast(player); 83 | } 84 | 85 | void GamePad_GetState(Dart_NativeArguments args) 86 | { 87 | PlayerIndex::Enum index = __getPlayerIndex(args, 0); 88 | 89 | GamePadState* state; 90 | getNativeField(args, 1, &state); 91 | 92 | *state = GamePad::getState(index); 93 | } 94 | 95 | void GamePad_SetVibration(Dart_NativeArguments args) 96 | { 97 | PlayerIndex::Enum index = __getPlayerIndex(args, 0); 98 | 99 | float leftMotor; 100 | getValue(args, 1, &leftMotor); 101 | 102 | float rightMotor; 103 | getValue(args, 2, &rightMotor); 104 | 105 | GamePad::setVibration(index, leftMotor, rightMotor); 106 | } 107 | 108 | void GamePadState_Delete(Dart_Handle handle, void* data) 109 | { 110 | GamePadState* state = static_cast(data); 111 | delete state; 112 | } 113 | 114 | void GamePadState_New(Dart_NativeArguments args) 115 | { 116 | Dart_Handle instance = Dart_GetNativeArgument(args, 0); 117 | 118 | GamePadState* state = new GamePadState(); 119 | Dart_SetNativeInstanceField(instance, 0, reinterpret_cast(state)); 120 | 121 | Dart_NewWeakPersistentHandle(instance, state, GamePadState_Delete); 122 | } 123 | 124 | void GamePadState_IsConnected(Dart_NativeArguments args) 125 | { 126 | GamePadState* state = 0; 127 | getNativeField(args, 0, &state); 128 | 129 | Dart_SetReturnValue(args, Dart_NewBoolean(state->isConnected())); 130 | } 131 | 132 | void GamePadState_GetLeftThumbstickX(Dart_NativeArguments args) 133 | { 134 | GamePadState* state = 0; 135 | getNativeField(args, 0, &state); 136 | 137 | Dart_SetReturnValue(args, Dart_NewDouble(state->getLeftThumbstickX())); 138 | } 139 | 140 | void GamePadState_GetLeftThumbstickY(Dart_NativeArguments args) 141 | { 142 | GamePadState* state = 0; 143 | getNativeField(args, 0, &state); 144 | 145 | Dart_SetReturnValue(args, Dart_NewDouble(state->getLeftThumbstickY())); 146 | } 147 | 148 | void GamePadState_GetRightThumbstickX(Dart_NativeArguments args) 149 | { 150 | GamePadState* state = 0; 151 | getNativeField(args, 0, &state); 152 | 153 | Dart_SetReturnValue(args, Dart_NewDouble(state->getRightThumbstickX())); 154 | } 155 | 156 | void GamePadState_GetRightThumbstickY(Dart_NativeArguments args) 157 | { 158 | GamePadState* state = 0; 159 | getNativeField(args, 0, &state); 160 | 161 | Dart_SetReturnValue(args, Dart_NewDouble(state->getRightThumbstickY())); 162 | } 163 | 164 | void GamePadState_GetLeftTrigger(Dart_NativeArguments args) 165 | { 166 | GamePadState* state = 0; 167 | getNativeField(args, 0, &state); 168 | 169 | Dart_SetReturnValue(args, Dart_NewDouble(state->getLeftTrigger())); 170 | } 171 | 172 | void GamePadState_GetRightTrigger(Dart_NativeArguments args) 173 | { 174 | GamePadState* state = 0; 175 | getNativeField(args, 0, &state); 176 | 177 | Dart_SetReturnValue(args, Dart_NewDouble(state->getRightTrigger())); 178 | } 179 | 180 | void GamePadState_GetButtons(Dart_NativeArguments args) 181 | { 182 | GamePadState* state = 0; 183 | getNativeField(args, 0, &state); 184 | 185 | Dart_SetReturnValue(args, Dart_NewInteger(state->getButtons())); 186 | } 187 | 188 | //--------------------------------------------------------------------- 189 | // Virtual machine entries 190 | //--------------------------------------------------------------------- 191 | 192 | /// Whether the library has been initialized 193 | bool __libraryInitialized = false; 194 | /// Class entries for the input library 195 | NativeClassEntry __libraryEntries[2]; 196 | 197 | /// Native entries for the GamePad class 198 | NativeEntry __gamePadNativeEntries[3]; 199 | /// Native entries for the GamePadState class 200 | NativeEntry __gamePadStateNativeEntries[10]; 201 | 202 | /** 203 | * Setup hooks to the GamePad class entries. 204 | */ 205 | void __setupGamePadEntries() 206 | { 207 | setNativeEntry(&__gamePadNativeEntries[0], "GetState", GamePad_GetState, 2); 208 | setNativeEntry(&__gamePadNativeEntries[1], "SetVibration", GamePad_SetVibration, 3); 209 | // Set the sentinal value 210 | setNativeEntry(&__gamePadNativeEntries[2], "", 0, 0); 211 | } 212 | 213 | /** 214 | * Setup hooks to the GamePadState class entries. 215 | */ 216 | void __setupGamePadStateEntries() 217 | { 218 | setNativeEntry(&__gamePadStateNativeEntries[0], "New", GamePadState_New, 1); 219 | setNativeEntry(&__gamePadStateNativeEntries[1], "IsConnected", GamePadState_IsConnected, 1); 220 | setNativeEntry(&__gamePadStateNativeEntries[2], "GetLeftThumbstickX", GamePadState_GetLeftThumbstickX, 1); 221 | setNativeEntry(&__gamePadStateNativeEntries[3], "GetLeftThumbstickY", GamePadState_GetLeftThumbstickY, 1); 222 | setNativeEntry(&__gamePadStateNativeEntries[4], "GetRightThumbstickX", GamePadState_GetRightThumbstickX, 1); 223 | setNativeEntry(&__gamePadStateNativeEntries[5], "GetRightThumbstickY", GamePadState_GetRightThumbstickY, 1); 224 | setNativeEntry(&__gamePadStateNativeEntries[6], "GetLeftTrigger", GamePadState_GetLeftTrigger, 1); 225 | setNativeEntry(&__gamePadStateNativeEntries[7], "GetRightTrigger", GamePadState_GetRightTrigger, 1); 226 | setNativeEntry(&__gamePadStateNativeEntries[8], "GetButtons", GamePadState_GetButtons, 1); 227 | // Set the sentinal value 228 | setNativeEntry(&__gamePadStateNativeEntries[9], "", 0, 0); 229 | } 230 | 231 | /** 232 | * Setup the class entries. 233 | */ 234 | void __setupClassEntries() 235 | { 236 | setNativeClassEntry(&__libraryEntries[0], "GamePad", __gamePadNativeEntries); 237 | setNativeClassEntry(&__libraryEntries[1], "GamePadState", __gamePadStateNativeEntries); 238 | // Set the sentinal value 239 | setNativeClassEntry(&__libraryEntries[2], "", 0); 240 | } 241 | 242 | /** 243 | * Sets up the native entries for the input library. 244 | */ 245 | void __setupInputLibrary() 246 | { 247 | if (!__libraryInitialized) 248 | { 249 | __setupClassEntries(); 250 | 251 | __setupGamePadEntries(); 252 | __setupGamePadStateEntries(); 253 | } 254 | 255 | __libraryInitialized = true; 256 | } 257 | 258 | /** 259 | * Native resolver for the dart:io library. 260 | */ 261 | //CREATE_NATIVE_RESOLVER(__inputLibraryResolver, __libraryEntries) 262 | Dart_NativeFunction __inputLibraryResolver(Dart_Handle name, int argumentCount) 263 | { 264 | const char* nativeFunctionName = 0; 265 | Dart_Handle result = Dart_StringToCString(name, &nativeFunctionName); 266 | 267 | assert(nativeFunctionName); 268 | 269 | printf("Resolving: %s\n", nativeFunctionName); 270 | 271 | NativeCallHash hash; 272 | fnv1aHashFunctionCall(nativeFunctionName, &hash); 273 | 274 | NativeClassEntry* classEntry = __libraryEntries; 275 | 276 | while (classEntry->entries != 0) 277 | { 278 | NativeEntry* functionEntry = classEntry->entries; 279 | 280 | if (classEntry->hash == hash.classHash) 281 | { 282 | while (functionEntry->function != 0) 283 | { 284 | if (functionEntry->hash == hash.functionHash) 285 | { 286 | assert(functionEntry->argumentCount == argumentCount); 287 | return functionEntry->function; 288 | } 289 | 290 | functionEntry++; 291 | } 292 | 293 | return 0; 294 | } 295 | 296 | classEntry++; 297 | } 298 | 299 | return 0; 300 | } 301 | } // end anonymous namespace 302 | 303 | //--------------------------------------------------------------------- 304 | 305 | void EmbedLibraries::createInputLibrary() 306 | { 307 | // Setup the native entries 308 | __setupInputLibrary(); 309 | 310 | VirtualMachine::loadScriptLibrary("embed:input", __sourceCode, __inputLibraryResolver); 311 | } 312 | -------------------------------------------------------------------------------- /server/src/Isolate.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * \file Isolate.cpp 3 | * 4 | * \section COPYRIGHT 5 | * 6 | * Dart Embedding Example 7 | * 8 | * --------------------------------------------------------------------- 9 | * 10 | * Copyright (c) 2012 Don Olmstead 11 | * 12 | * This software is provided 'as-is', without any express or implied 13 | * warranty. In no event will the authors be held liable for any damages 14 | * arising from the use of this software. 15 | * 16 | * Permission is granted to anyone to use this software for any purpose, 17 | * including commercial applications, and to alter it and redistribute it 18 | * freely, subject to the following restrictions: 19 | * 20 | * 1. The origin of this software must not be misrepresented; you must not 21 | * claim that you wrote the original software. If you use this software 22 | * in a product, an acknowledgment in the product documentation would be 23 | * appreciated but is not required. 24 | * 25 | * 2. Altered source versions must be plainly marked as such, and must not be 26 | * misrepresented as being the original software. 27 | * 28 | * 3. This notice may not be removed or altered from any source 29 | * distribution. 30 | */ 31 | 32 | #include 33 | #include 34 | #include 35 | 36 | #define WIN32_LEAN_AND_MEAN 37 | #define NOMINMAX 38 | #define NOKERNEL 39 | #define NOUSER 40 | #define NOSERVICE 41 | #define NOSOUND 42 | #define NOMCX 43 | 44 | #include 45 | 46 | #include "dart_api.h" 47 | #include "isolate_data.h" 48 | #include "NativeResolution.hpp" 49 | #include "ScriptLibrary.hpp" 50 | #include "BuiltinLibraries.hpp" 51 | using namespace DartEmbed; 52 | 53 | /// The snapshot data 54 | extern const uint8_t* snapshot_buffer; 55 | 56 | namespace 57 | { 58 | //---------------------------------------------------------------------- 59 | // Virtual machine instances 60 | //---------------------------------------------------------------------- 61 | 62 | /// The current directory 63 | char* __currentDirectory; 64 | /// Whether the virtual machine has been initialized 65 | bool __initialized = false; 66 | /// The isolates currently running in the virtual machine 67 | std::vector __runningIsolates; 68 | 69 | //---------------------------------------------------------------------- 70 | // ScriptLibrary instances 71 | //---------------------------------------------------------------------- 72 | 73 | /// The dart:core library 74 | ScriptLibrary* __coreLibrary; 75 | /// The dart:io library 76 | ScriptLibrary* __ioLibrary; 77 | /// The dart:json library 78 | ScriptLibrary* __jsonLibrary; 79 | /// The dart:uri library 80 | ScriptLibrary* __uriLibrary; 81 | /// The dart:crypto library 82 | ScriptLibrary* __cryptoLibrary; 83 | /// The dart:utf library 84 | ScriptLibrary* __utfLibrary; 85 | 86 | /// Any additional libraries specified 87 | std::vector __libraries; 88 | 89 | //---------------------------------------------------------------------- 90 | // URI/URL functions 91 | //---------------------------------------------------------------------- 92 | 93 | /** 94 | * Resolves the script's URI. 95 | * 96 | * Invokes _resolveScriptUri from within the core library to determine the 97 | * full URI to the file. 98 | * 99 | * \note Could be moved to aux lib. Should be overloadable assuming that 100 | * _resolveScriptUri doesn't have to be invoked. This would allow 101 | * for embedders who already have their own URI implementation and 102 | * file system accessor to be used. 103 | * 104 | * \param scriptUri The path to the script. 105 | * \param coreLibrary Handle to the core library. 106 | * \returns The full URI to the script. 107 | */ 108 | Dart_Handle __resolveScriptUri(const char* scriptUri, Dart_Handle coreLibrary) 109 | { 110 | const std::int32_t numberOfArgs = 3; 111 | 112 | Dart_Handle args[numberOfArgs]; 113 | args[0] = Dart_NewString(__currentDirectory); 114 | args[1] = Dart_NewString(scriptUri); 115 | args[2] = Dart_True(); // Windows host is always true 116 | 117 | return Dart_Invoke(coreLibrary, Dart_NewString("_resolveScriptUri"), numberOfArgs, args); 118 | } 119 | 120 | /** 121 | * Determines the file path from the given URI. 122 | * 123 | * Invokes _filePathFromUri from within the core library to determine the 124 | * path to the file. 125 | * 126 | * \note Could be moved to aux lib. Should be overloadable assuming that 127 | * _filePathFromUri doesn't have to be invoked. This would allow 128 | * for embedders who already have their own URI implementation and 129 | * file system accessor to be used. 130 | * 131 | * \param scriptUri URI to the script. 132 | * \param coreLibrary Handle to the core library. 133 | * \returns The file path to the script. 134 | */ 135 | Dart_Handle __filePathFromUri(Dart_Handle scriptUri, Dart_Handle coreLibrary) 136 | { 137 | const std::int32_t numberOfArgs = 2; 138 | Dart_Handle args[numberOfArgs]; 139 | args[0] = scriptUri; 140 | args[1] = Dart_True(); // Windows host is always true 141 | 142 | return Dart_Invoke(coreLibrary, Dart_NewString("_filePathFromUri"), numberOfArgs, args); 143 | } 144 | 145 | /** 146 | * Detemines if the URL signifies a Dart library. 147 | * 148 | * \param url The url to query. 149 | * \returns true if the URL is a Dart libray; false otherwise. 150 | */ 151 | bool __isDartSchemeUrl(const char* url) 152 | { 153 | return strncmp(url, "dart:", 5) == 0; 154 | } 155 | 156 | //---------------------------------------------------------------------- 157 | // File loading 158 | //---------------------------------------------------------------------- 159 | 160 | /** 161 | * Reads the source from the given URI. 162 | * 163 | * \note Could be moved to the aux lib. Should be overloadable so file handling 164 | * can be handled by the embedder. 165 | * 166 | * \param scriptUri URI for the script. 167 | * \param coreLibrary Handle to the core library. 168 | */ 169 | Dart_Handle __readSource(Dart_Handle scriptUri, Dart_Handle coreLibrary) 170 | { 171 | Dart_Handle scriptPath = __filePathFromUri(scriptUri, coreLibrary); 172 | 173 | const char* scriptPathString; 174 | Dart_StringToCString(scriptPath, &scriptPathString); 175 | 176 | FILE* file = fopen(scriptPathString, "r"); 177 | 178 | if (file) 179 | { 180 | fseek(file, 0, SEEK_END); 181 | long length = ftell(file); 182 | fseek(file, 0, SEEK_SET); 183 | 184 | char* buffer = new char[length + 1]; 185 | size_t read = fread(buffer, 1, length, file); 186 | fclose(file); 187 | buffer[read] = '\0'; 188 | 189 | Dart_Handle source = Dart_NewString(buffer); 190 | 191 | delete[] buffer; 192 | 193 | return source; 194 | } 195 | 196 | return Dart_Error("Unable to read file"); 197 | } 198 | 199 | /** 200 | * Loads a script from the given URI. 201 | * 202 | * \param scriptUri URI pointing to the script's location. 203 | * \param resolve Whether the script's location needs to be resolved. 204 | * \param coreLibrary The dart:core library. 205 | */ 206 | Dart_Handle __loadScript(const char* scriptUri, bool resolve, Dart_Handle coreLibrary) 207 | { 208 | Dart_Handle resolvedScriptUri; 209 | 210 | if (resolve) 211 | { 212 | resolvedScriptUri = __resolveScriptUri(scriptUri, coreLibrary); 213 | 214 | if (Dart_IsError(resolvedScriptUri)) 215 | { 216 | return resolvedScriptUri; 217 | } 218 | } 219 | else 220 | { 221 | resolvedScriptUri = Dart_NewString(scriptUri); 222 | } 223 | 224 | Dart_Handle source = __readSource(resolvedScriptUri, coreLibrary); 225 | 226 | if (Dart_IsError(source)) 227 | { 228 | return source; 229 | } 230 | 231 | return Dart_LoadScript(resolvedScriptUri, source); 232 | } 233 | 234 | //---------------------------------------------------------------------- 235 | // Library tag handler 236 | //---------------------------------------------------------------------- 237 | 238 | /** 239 | * Handles loading libraries and scripts into the isolate. 240 | * 241 | * \param tag The type of tag received. 242 | * \param library The library to load into. 243 | * \param url The URL for the library. 244 | */ 245 | Dart_Handle __libraryTagHandler(Dart_LibraryTag tag, Dart_Handle library, Dart_Handle url) 246 | { 247 | const char* urlString = 0; 248 | Dart_Handle result = Dart_StringToCString(url, &urlString); 249 | 250 | if (Dart_IsError(result)) 251 | return result; 252 | bool isDartScheme = __isDartSchemeUrl(urlString); 253 | 254 | if (tag == kCanonicalizeUrl) 255 | { 256 | if (isDartScheme) 257 | return url; 258 | 259 | // Check other libraries that were added 260 | std::int32_t hash = fnv1aHash(urlString); 261 | std::size_t count = __libraries.size(); 262 | 263 | for (std::size_t i = 0; i < count; ++i) 264 | { 265 | ScriptLibrary* library = __libraries[i]; 266 | 267 | if (hash == library->getHashedName()) 268 | return url; 269 | } 270 | } 271 | else 272 | { 273 | // Check other libraries that were added 274 | std::int32_t hash = fnv1aHash(urlString); 275 | std::size_t count = __libraries.size(); 276 | 277 | for (std::size_t i = 0; i < count; ++i) 278 | { 279 | ScriptLibrary* library = __libraries[i]; 280 | 281 | if (hash == library->getHashedName()) 282 | return library->load(); 283 | } 284 | } 285 | 286 | return Dart_Error("Do not know how to load '%s'", urlString); 287 | } 288 | 289 | } // end anonymous namespace 290 | 291 | //---------------------------------------------------------------------- 292 | // Isolate methods 293 | //---------------------------------------------------------------------- 294 | 295 | Isolate::Isolate(Dart_Isolate isolate, Dart_Handle library, Isolate* parent) 296 | : _isolate(isolate) 297 | , _library(library) 298 | , _parent(parent) 299 | { 300 | __runningIsolates.push_back(this); 301 | } 302 | 303 | //---------------------------------------------------------------------- 304 | 305 | Isolate::~Isolate() 306 | { 307 | //Dart_ExitScope(); 308 | 309 | //Dart_EnterIsolate(_isolate); 310 | //Dart_ShutdownIsolate(); 311 | } 312 | 313 | //---------------------------------------------------------------------- 314 | 315 | void Isolate::invokeFunction(const char* name) 316 | { 317 | Dart_EnterScope(); 318 | Dart_Handle result = Dart_Invoke(_library, Dart_NewString(name), 0, NULL); 319 | 320 | // Run the main loop 321 | // This should probably be somewhere else. 322 | // Wondering how requestAnimationFrame handles this situation. 323 | Dart_RunLoop(); 324 | 325 | Dart_ExitScope(); 326 | } 327 | 328 | //---------------------------------------------------------------------- 329 | 330 | Isolate* Isolate::loadScript(const char* path) 331 | { 332 | char* error = 0; 333 | return createIsolate(path, "main", true, new IsolateData(), &error); 334 | } 335 | 336 | //---------------------------------------------------------------------- 337 | 338 | Isolate* Isolate::createIsolate(const char* scriptUri, const char* main, bool resolveScript, void* data, char** error) 339 | { 340 | Dart_Isolate isolate = Dart_CreateIsolate(scriptUri, main, snapshot_buffer, data, error); 341 | 342 | if (isolate) 343 | { 344 | Dart_EnterScope(); 345 | 346 | Dart_Handle result; 347 | result = Dart_SetLibraryTagHandler(__libraryTagHandler); 348 | 349 | if (Dart_IsError(result)) 350 | { 351 | *error = strdup(Dart_GetError(result)); 352 | Dart_ExitScope(); 353 | Dart_ShutdownIsolate(); 354 | return 0; 355 | } 356 | 357 | // Should an import map be created? 358 | 359 | // Setup URI library 360 | Dart_Handle uriLibrary = __uriLibrary->load(); 361 | 362 | if (Dart_IsError(uriLibrary)) 363 | { 364 | *error = strdup(Dart_GetError(result)); 365 | Dart_ExitScope(); 366 | Dart_ShutdownIsolate(); 367 | return 0; 368 | } 369 | 370 | // Setup core builtin library 371 | Dart_Handle coreLibrary = __coreLibrary->load(); 372 | 373 | if (Dart_IsError(coreLibrary)) 374 | { 375 | *error = strdup(Dart_GetError(result)); 376 | Dart_ExitScope(); 377 | Dart_ShutdownIsolate(); 378 | return 0; 379 | } 380 | 381 | // Setup IO library 382 | Dart_Handle ioLibrary = __ioLibrary->load(); 383 | 384 | if (Dart_IsError(ioLibrary)) 385 | { 386 | *error = strdup(Dart_GetError(result)); 387 | Dart_ExitScope(); 388 | Dart_ShutdownIsolate(); 389 | return 0; 390 | } 391 | 392 | // Load the script into the isolate 393 | Dart_Handle library = __loadScript(scriptUri, resolveScript, coreLibrary); 394 | 395 | if (Dart_IsError(library)) 396 | { 397 | *error = strdup(Dart_GetError(library)); 398 | Dart_ExitScope(); 399 | Dart_ShutdownIsolate(); 400 | return 0; 401 | } 402 | 403 | // Implicitly import the core library 404 | // It isn't clear why this seems to be the only library 405 | // that requires this import call 406 | result = Dart_LibraryImportLibrary(library, coreLibrary); 407 | 408 | if (Dart_IsError(result)) 409 | { 410 | *error = strdup(Dart_GetError(library)); 411 | Dart_ExitScope(); 412 | Dart_ShutdownIsolate(); 413 | return 0; 414 | } 415 | 416 | //Dart_ExitScope(); 417 | 418 | return new Isolate(isolate, library, static_cast(data)); 419 | } 420 | 421 | return 0; 422 | } 423 | 424 | //---------------------------------------------------------------------- 425 | 426 | bool Isolate::isolateCreateCallback(const char* scriptUri, const char* main, void* callbackData, char** error) 427 | { 428 | Isolate* isolate = createIsolate(scriptUri, main, true, new IsolateData(), error); 429 | 430 | // See if the isolate was created successfully 431 | return isolate != 0; 432 | } 433 | 434 | //---------------------------------------------------------------------- 435 | 436 | void Isolate::isolateShutdownCallback(void* callbackData) 437 | { 438 | 439 | } 440 | 441 | //---------------------------------------------------------------------- 442 | // Virtual machine methods 443 | //---------------------------------------------------------------------- 444 | 445 | bool VirtualMachine::initialize() 446 | { 447 | if (!__initialized) 448 | { 449 | if (Dart_SetVMFlags(0, 0)) 450 | { 451 | if (Dart_Initialize(Isolate::isolateCreateCallback, 0, Isolate::isolateShutdownCallback)) 452 | { 453 | // Setup the core libraries 454 | __coreLibrary = BuiltinLibraries::createCoreLibrary(); 455 | __ioLibrary = BuiltinLibraries::createIOLibrary(); 456 | __jsonLibrary = BuiltinLibraries::createJsonLibrary(); 457 | __uriLibrary = BuiltinLibraries::createUriLibrary(); 458 | __cryptoLibrary = BuiltinLibraries::createCryptoLibrary(); 459 | __utfLibrary = BuiltinLibraries::createUtfLibrary(); 460 | 461 | // Get the current directory 462 | std::int32_t length = GetCurrentDirectory(0, 0); 463 | __currentDirectory = new char[length]; 464 | GetCurrentDirectory(length + 1, __currentDirectory); 465 | 466 | __initialized = true; 467 | } 468 | } 469 | } 470 | 471 | return __initialized; 472 | } 473 | 474 | //---------------------------------------------------------------------- 475 | 476 | void VirtualMachine::terminate() 477 | { 478 | if (__initialized) 479 | { 480 | // Shutdown the libraries 481 | delete __coreLibrary; 482 | delete __ioLibrary; 483 | delete __jsonLibrary; 484 | delete __uriLibrary; 485 | delete __cryptoLibrary; 486 | delete __utfLibrary; 487 | 488 | std::size_t count = __libraries.size(); 489 | 490 | for (std::size_t i = 0; i < count; ++i) 491 | delete __libraries[i]; 492 | 493 | __libraries.clear(); 494 | } 495 | 496 | __initialized = false; 497 | } 498 | 499 | //---------------------------------------------------------------------- 500 | 501 | void VirtualMachine::loadScriptLibrary( 502 | const char* name, 503 | const char* source, 504 | Dart_NativeEntryResolver nativeResolver, 505 | Dart_LibraryInitializer initializer) 506 | { 507 | ScriptLibrary* library = new ScriptLibrary(name, source, nativeResolver, initializer); 508 | 509 | __libraries.push_back(library); 510 | } 511 | 512 | //---------------------------------------------------------------------- 513 | 514 | std::size_t VirtualMachine::getNumberOfIsolates() 515 | { 516 | return __runningIsolates.size(); 517 | } 518 | -------------------------------------------------------------------------------- /server/src/NativeResolution.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * \file NativeResolution.hpp 3 | * 4 | * \section COPYRIGHT 5 | * 6 | * Dart Embedding Example 7 | * 8 | * --------------------------------------------------------------------- 9 | * 10 | * Copyright (c) 2012 Don Olmstead 11 | * 12 | * This software is provided 'as-is', without any express or implied 13 | * warranty. In no event will the authors be held liable for any damages 14 | * arising from the use of this software. 15 | * 16 | * Permission is granted to anyone to use this software for any purpose, 17 | * including commercial applications, and to alter it and redistribute it 18 | * freely, subject to the following restrictions: 19 | * 20 | * 1. The origin of this software must not be misrepresented; you must not 21 | * claim that you wrote the original software. If you use this software 22 | * in a product, an acknowledgment in the product documentation would be 23 | * appreciated but is not required. 24 | * 25 | * 2. Altered source versions must be plainly marked as such, and must not be 26 | * misrepresented as being the original software. 27 | * 28 | * 3. This notice may not be removed or altered from any source 29 | * distribution. 30 | */ 31 | 32 | #ifndef DART_EMBED_NATIVE_RESOLUTION_HPP_INCLUDED 33 | #define DART_EMBED_NATIVE_RESOLUTION_HPP_INCLUDED 34 | 35 | #include 36 | #include "dart_api.h" 37 | 38 | namespace DartEmbed 39 | { 40 | /** 41 | * Maps the name of a function to the function pointer. 42 | */ 43 | struct NativeEntry 44 | { 45 | /// Hash containing the native entry name 46 | std::int32_t hash; 47 | /// Function pointer 48 | Dart_NativeFunction function; 49 | #ifdef _DEBUG 50 | /// Name of the native entry 51 | const char* name; 52 | /// Number of arguments 53 | std::int32_t argumentCount; 54 | #endif 55 | } ; // end struct NativeEntry 56 | 57 | /** 58 | * Maps the name of a class to an array of associated functions. 59 | */ 60 | struct NativeClassEntry 61 | { 62 | /// Hash containing the native entry name 63 | std::int32_t hash; 64 | /// Pointer to an array of NativeEntries 65 | NativeEntry* entries; 66 | #ifdef _DEBUG 67 | /// Name of the class 68 | const char* name; 69 | #endif 70 | } ; // end struct NativeClassEntry 71 | 72 | /** 73 | * Hash structure for a native call. 74 | */ 75 | struct NativeCallHash 76 | { 77 | /// Hash for the class name 78 | std::int32_t classHash; 79 | /// Hash for the function name 80 | std::int32_t functionHash; 81 | } ; // end struct NativeCallHash 82 | 83 | 84 | /** 85 | * Implementation of the FNV1A hashing algorithm. 86 | * 87 | * \param str The string to hash. 88 | * \returns The computed hash. 89 | */ 90 | inline std::int32_t fnv1aHash(const char* str) 91 | { 92 | std::int32_t hash = 2166136261u; 93 | 94 | while (*str != '\0') 95 | { 96 | hash ^= *str++; 97 | hash *= 16777619u; 98 | } 99 | 100 | return hash; 101 | } 102 | 103 | /** 104 | * Hashes the function call. 105 | * 106 | * Assumes that the string is of the format className_functionName. 107 | * 108 | * \param str The string to hash. 109 | * \param hash Structure containing the hash. 110 | */ 111 | inline void fnv1aHashFunctionCall(const char* str, NativeCallHash* hash) 112 | { 113 | std::int32_t classHash = 2166136261u; 114 | 115 | while (*str != '_') 116 | { 117 | classHash ^= *str++; 118 | classHash *= 16777619u; 119 | } 120 | 121 | // Advance past '_' 122 | str++; 123 | 124 | hash->classHash = classHash; 125 | hash->functionHash = fnv1aHash(str); 126 | } 127 | 128 | /** 129 | * Sets the fields of a NativeClassEntry. 130 | * 131 | * \param entry The NativeClassEntry to populate. 132 | * \param name The name of the class. 133 | * \param entries An array holding the class' native functions. 134 | */ 135 | inline void setNativeClassEntry(NativeClassEntry* entry, const char* name, NativeEntry* entries) 136 | { 137 | entry->hash = fnv1aHash(name); 138 | entry->entries = entries; 139 | 140 | #ifdef _DEBUG 141 | entry->name = name; 142 | #endif 143 | } 144 | 145 | /** 146 | * Sets the fields of a NativeEntry. 147 | * 148 | * \param entry The NativeEntry to populate. 149 | * \param name The name of the function. 150 | * \param function The function pointer to associate to the name. 151 | * \param argumentCount The number of arguments the function takes. 152 | */ 153 | inline void setNativeEntry(NativeEntry* entry, const char* name, Dart_NativeFunction function, std::int32_t argumentCount) 154 | { 155 | entry->hash = fnv1aHash(name); 156 | entry->function = function; 157 | 158 | #ifdef _DEBUG 159 | entry->name = name; 160 | entry->argumentCount = argumentCount; 161 | #endif 162 | } 163 | 164 | /** 165 | * Macro to create a native resolver. 166 | * 167 | * Once constexpr is available this should change to a template. It 168 | * could also be used as a default if a native resolver is passed a void* 169 | * which would contain the NativeClassEntry array. 170 | * 171 | * \param functionName Function name to use for the resolver. 172 | * \param nativeEntries Pointer to a NativeClassEntries array. 173 | */ 174 | #define CREATE_NATIVE_RESOLVER(functionName, libraryEntries) \ 175 | Dart_NativeFunction functionName(Dart_Handle name, int argumentCount) \ 176 | { \ 177 | const char* nativeFunctionName = 0; \ 178 | Dart_Handle result = Dart_StringToCString(name, &nativeFunctionName); \ 179 | \ 180 | assert(nativeFunctionName); \ 181 | \ 182 | NativeCallHash hash; \ 183 | fnv1aHashFunctionCall(nativeFunctionName, &hash); \ 184 | \ 185 | NativeClassEntry* classEntry = libraryEntries; \ 186 | \ 187 | while (classEntry->entries != 0) \ 188 | { \ 189 | NativeEntry* functionEntry = classEntry->entries; \ 190 | \ 191 | if (classEntry->hash == hash.classHash) \ 192 | { \ 193 | while (functionEntry->function != 0) \ 194 | { \ 195 | if (functionEntry->hash == hash.functionHash) \ 196 | { \ 197 | assert(functionEntry->argumentCount == argumentCount); \ 198 | return functionEntry->function; \ 199 | } \ 200 | \ 201 | functionEntry++; \ 202 | } \ 203 | \ 204 | return 0; \ 205 | } \ 206 | \ 207 | classEntry++; \ 208 | } \ 209 | \ 210 | return 0; \ 211 | } 212 | } // end namespace DartEmbed 213 | 214 | #endif // end DART_EMBED_NATIVE_RESOLUTION_HPP_INCLUDED 215 | -------------------------------------------------------------------------------- /server/src/PlatformWindows.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * \file PlatformWindows.hpp 3 | * 4 | * \section COPYRIGHT 5 | * 6 | * Dart Embedding Example 7 | * 8 | * --------------------------------------------------------------------- 9 | * 10 | * Copyright (c) 2012 Don Olmstead 11 | * 12 | * This software is provided 'as-is', without any express or implied 13 | * warranty. In no event will the authors be held liable for any damages 14 | * arising from the use of this software. 15 | * 16 | * Permission is granted to anyone to use this software for any purpose, 17 | * including commercial applications, and to alter it and redistribute it 18 | * freely, subject to the following restrictions: 19 | * 20 | * 1. The origin of this software must not be misrepresented; you must not 21 | * claim that you wrote the original software. If you use this software 22 | * in a product, an acknowledgment in the product documentation would be 23 | * appreciated but is not required. 24 | * 25 | * 2. Altered source versions must be plainly marked as such, and must not be 26 | * misrepresented as being the original software. 27 | * 28 | * 3. This notice may not be removed or altered from any source 29 | * distribution. 30 | */ 31 | 32 | #ifndef DART_EMBED_PLATFORM_WINDOWS_HPP_INCLUDED 33 | #define DART_EMBED_PLATFORM_WINDOWS_HPP_INCLUDED 34 | 35 | #define WIN32_LEAN_AND_MEAN 36 | 37 | #include 38 | #include 39 | 40 | #include 41 | 42 | /// Classname for the application 43 | #define WINDOW_CLASS_NAME "Dart Embed Application" 44 | 45 | /** 46 | * Update game pads. 47 | */ 48 | void updateGamePads(); 49 | 50 | #endif // end DART_EMBED_PLATFORM_WINDOWS_HPP_INCLUDED 51 | -------------------------------------------------------------------------------- /server/src/ScriptLibrary.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * \file ScriptLibrary.cpp 3 | * 4 | * \section COPYRIGHT 5 | * 6 | * Dart Embedding Example 7 | * 8 | * --------------------------------------------------------------------- 9 | * 10 | * Copyright (c) 2012 Don Olmstead 11 | * 12 | * This software is provided 'as-is', without any express or implied 13 | * warranty. In no event will the authors be held liable for any damages 14 | * arising from the use of this software. 15 | * 16 | * Permission is granted to anyone to use this software for any purpose, 17 | * including commercial applications, and to alter it and redistribute it 18 | * freely, subject to the following restrictions: 19 | * 20 | * 1. The origin of this software must not be misrepresented; you must not 21 | * claim that you wrote the original software. If you use this software 22 | * in a product, an acknowledgment in the product documentation would be 23 | * appreciated but is not required. 24 | * 25 | * 2. Altered source versions must be plainly marked as such, and must not be 26 | * misrepresented as being the original software. 27 | * 28 | * 3. This notice may not be removed or altered from any source 29 | * distribution. 30 | */ 31 | 32 | #include "ScriptLibrary.hpp" 33 | #include "dart_api.h" 34 | #include "NativeResolution.hpp" 35 | using namespace DartEmbed; 36 | 37 | //---------------------------------------------------------------------- 38 | 39 | ScriptLibrary::ScriptLibrary( 40 | const char* name, 41 | const char* source, 42 | Dart_NativeEntryResolver nativeResolver, 43 | Dart_LibraryInitializer initializer) 44 | : _name(name) 45 | , _hashedName(fnv1aHash(name)) 46 | , _source(source) 47 | , _nativeResolver(nativeResolver) 48 | , _initializer(initializer) 49 | { } 50 | 51 | //---------------------------------------------------------------------- 52 | 53 | Dart_Handle ScriptLibrary::load() 54 | { 55 | // Lookup the library 56 | Dart_Handle url = Dart_NewString(_name); 57 | Dart_Handle library = Dart_LookupLibrary(url); 58 | 59 | // See if the library needs to be loaded 60 | // If its contained in the snapshot it's already present 61 | if (Dart_IsError(library)) 62 | { 63 | library = Dart_LoadLibrary(url, Dart_NewString(_source)); 64 | } 65 | 66 | // See if the library requires setup 67 | if (!Dart_IsError(library)) 68 | { 69 | // Setup a native resolver 70 | if (_nativeResolver != 0) 71 | Dart_SetNativeResolver(library, _nativeResolver); 72 | 73 | // Call the initialization routine 74 | if (_initializer != 0) 75 | _initializer(library); 76 | } 77 | else 78 | { 79 | const char* error = Dart_GetError(library); 80 | printf(error); 81 | } 82 | 83 | return library; 84 | } 85 | -------------------------------------------------------------------------------- /server/src/ScriptLibrary.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * \file ScriptLibrary.hpp 3 | * 4 | * \section COPYRIGHT 5 | * 6 | * Dart Embedding Example 7 | * 8 | * --------------------------------------------------------------------- 9 | * 10 | * Copyright (c) 2012 Don Olmstead 11 | * 12 | * This software is provided 'as-is', without any express or implied 13 | * warranty. In no event will the authors be held liable for any damages 14 | * arising from the use of this software. 15 | * 16 | * Permission is granted to anyone to use this software for any purpose, 17 | * including commercial applications, and to alter it and redistribute it 18 | * freely, subject to the following restrictions: 19 | * 20 | * 1. The origin of this software must not be misrepresented; you must not 21 | * claim that you wrote the original software. If you use this software 22 | * in a product, an acknowledgment in the product documentation would be 23 | * appreciated but is not required. 24 | * 25 | * 2. Altered source versions must be plainly marked as such, and must not be 26 | * misrepresented as being the original software. 27 | * 28 | * 3. This notice may not be removed or altered from any source 29 | * distribution. 30 | */ 31 | 32 | #ifndef DART_EMBED_SCRIPT_LIBRARY_HPP_INCLUDED 33 | #define DART_EMBED_SCRIPT_LIBRARY_HPP_INCLUDED 34 | 35 | #include 36 | 37 | namespace DartEmbed 38 | { 39 | //--------------------------------------------------------------------- 40 | // Forward declarations for Dart types 41 | //--------------------------------------------------------------------- 42 | 43 | class Isolate; 44 | 45 | /** 46 | * 47 | */ 48 | class ScriptLibrary 49 | { 50 | public: 51 | 52 | /** 53 | * Creates an instance of the ScriptLibrary class. 54 | * 55 | * \param name The name of the library. 56 | * \param source The source code for the library. 57 | * \param nativeResolver The native resolver for the library. 58 | * \param initializer Function to call that will provide any initialization for the library. 59 | */ 60 | ScriptLibrary( 61 | const char* name, 62 | const char* source, 63 | Dart_NativeEntryResolver nativeResolver = 0, 64 | Dart_LibraryInitializer initializer = 0 65 | ); 66 | 67 | //--------------------------------------------------------------------- 68 | // Properties 69 | //--------------------------------------------------------------------- 70 | 71 | public: 72 | 73 | /** 74 | * Gets the hashed name of the library. 75 | * 76 | * \returns The hashed name of the library. 77 | */ 78 | std::int32_t getHashedName() const 79 | { 80 | return _hashedName; 81 | } 82 | 83 | /** 84 | * Gets the name of the library. 85 | * 86 | * \returns The name of the library. 87 | */ 88 | inline const char* getName() const 89 | { 90 | return _name; 91 | } 92 | 93 | /** 94 | * Whether the library has native functions. 95 | * 96 | * \returns true if the library has native functions; false otherwise. 97 | */ 98 | inline bool hasNatives() const 99 | { 100 | return _nativeResolver != 0; 101 | } 102 | 103 | //--------------------------------------------------------------------- 104 | // Class methods 105 | //--------------------------------------------------------------------- 106 | 107 | public: 108 | 109 | /** 110 | * Loads the library into the current isolate. 111 | */ 112 | Dart_Handle load(); 113 | 114 | //--------------------------------------------------------------------- 115 | // Member variables 116 | //--------------------------------------------------------------------- 117 | 118 | private: 119 | 120 | friend class Isolate; 121 | 122 | /// Hashed name of the library 123 | std::int32_t _hashedName; 124 | /// The name of the library 125 | const char* _name; 126 | /// The source code for the library 127 | const char* _source; 128 | /// Native resolver for the library 129 | Dart_NativeEntryResolver _nativeResolver; 130 | /// Function call that provides any initialization for the library 131 | Dart_LibraryInitializer _initializer; 132 | } ; // end class ScriptLibrary 133 | } // end namespace DartEmbed 134 | 135 | #endif // end DART_EMBED_SCRIPT_LIBRARY_HPP_INCLUDED 136 | -------------------------------------------------------------------------------- /server/src/isolate_data.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 2 | // for details. All rights reserved. Use of this source code is governed by a 3 | // BSD-style license that can be found in the LICENSE file. 4 | 5 | #ifndef BIN_ISOLATE_DATA_H_ 6 | #define BIN_ISOLATE_DATA_H_ 7 | 8 | // Forward declaration. 9 | class EventHandler; 10 | 11 | // Data associated with every isolate in the standalone VM 12 | // embedding. This is used to free external resources for each isolate 13 | // when the isolate shuts down. 14 | class IsolateData { 15 | public: 16 | IsolateData() : event_handler(NULL) {} 17 | 18 | EventHandler* event_handler; 19 | 20 | private: 21 | IsolateData(const IsolateData&); 22 | void operator=(const IsolateData&); 23 | }; 24 | 25 | #endif // BIN_ISOLATE_DATA_H_ 26 | -------------------------------------------------------------------------------- /server/src/main.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * \file main.cpp 3 | * 4 | * \section COPYRIGHT 5 | * 6 | * Dart Embedding Example 7 | * 8 | * --------------------------------------------------------------------- 9 | * 10 | * Copyright (c) 2012 Don Olmstead 11 | * 12 | * This software is provided 'as-is', without any express or implied 13 | * warranty. In no event will the authors be held liable for any damages 14 | * arising from the use of this software. 15 | * 16 | * Permission is granted to anyone to use this software for any purpose, 17 | * including commercial applications, and to alter it and redistribute it 18 | * freely, subject to the following restrictions: 19 | * 20 | * 1. The origin of this software must not be misrepresented; you must not 21 | * claim that you wrote the original software. If you use this software 22 | * in a product, an acknowledgment in the product documentation would be 23 | * appreciated but is not required. 24 | * 25 | * 2. Altered source versions must be plainly marked as such, and must not be 26 | * misrepresented as being the original software. 27 | * 28 | * 3. This notice may not be removed or altered from any source 29 | * distribution. 30 | */ 31 | 32 | #include 33 | #include 34 | #include "PlatformWindows.hpp" 35 | #include "BuiltinLibraries.hpp" 36 | #include "EmbedLibraries.hpp" 37 | using namespace DartEmbed; 38 | 39 | namespace 40 | { 41 | /// Handle to the window 42 | HWND handle; 43 | 44 | //--------------------------------------------------------------------- 45 | 46 | void InitWindow(std::int32_t width, std::int32_t height) 47 | { 48 | // Set the window styles 49 | DWORD dwStyle = WS_VISIBLE | WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX; 50 | DWORD dwExStyle = WS_EX_APPWINDOW; 51 | 52 | // Get the window size 53 | RECT rect; 54 | rect.left = 0; 55 | rect.right = width - 1; 56 | rect.top = 0; 57 | rect.bottom = height - 1; 58 | 59 | AdjustWindowRectEx(&rect, dwStyle, FALSE, dwExStyle); 60 | 61 | std::int32_t fullWidth = rect.right - rect.left + 1; 62 | std::int32_t fullHeight = rect.bottom + rect.top + 1; 63 | 64 | // Get the working area 65 | RECT wa; 66 | 67 | SystemParametersInfo(SPI_GETWORKAREA, 0, &wa, 0); 68 | 69 | // Create the window 70 | handle = CreateWindowExA 71 | ( 72 | dwExStyle, 73 | WINDOW_CLASS_NAME, 74 | WINDOW_CLASS_NAME, 75 | dwStyle, 76 | wa.left, wa.top, 77 | fullWidth, 78 | fullHeight, 79 | 0, 80 | 0, 81 | 0, 82 | 0 83 | ); 84 | } 85 | 86 | //--------------------------------------------------------------------- 87 | 88 | LRESULT WINAPI MsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) 89 | { 90 | switch (msg) 91 | { 92 | case WM_DESTROY: 93 | { 94 | PostQuitMessage(0); 95 | return 0; 96 | } 97 | } 98 | 99 | return DefWindowProc(hWnd, msg, wParam, lParam); 100 | } 101 | 102 | //--------------------------------------------------------------------- 103 | 104 | DWORD WINAPI __scriptThread(LPVOID param) 105 | { 106 | // Load the script and invoke 107 | Isolate* isolate = Isolate::loadScript("server.dart"); 108 | isolate->invokeFunction("main"); 109 | 110 | return 0; 111 | } 112 | } // end anonymous namespace 113 | 114 | //--------------------------------------------------------------------- 115 | 116 | int main() 117 | { 118 | // Register window class 119 | WNDCLASSEXA wc; 120 | wc.cbSize = sizeof(WNDCLASSEX); 121 | wc.style = CS_CLASSDC; 122 | wc.lpfnWndProc = MsgProc; 123 | wc.cbClsExtra = 0; 124 | wc.cbWndExtra = 0; 125 | wc.hInstance = GetModuleHandle(0); 126 | wc.hIcon = LoadIcon(0, IDI_APPLICATION); 127 | wc.hCursor = LoadCursor(0, IDC_ARROW); 128 | wc.hbrBackground = 0; 129 | wc.lpszMenuName = 0; 130 | wc.lpszClassName = WINDOW_CLASS_NAME; 131 | wc.hIconSm = 0; 132 | 133 | RegisterClassExA(&wc); 134 | 135 | // Open the window 136 | InitWindow(640, 480); 137 | 138 | // Initialize the virtual machine 139 | VirtualMachine::initialize(); 140 | 141 | // Setup the embed libraries 142 | EmbedLibraries::createInputLibrary(); 143 | 144 | // Start the thread 145 | DWORD scriptThreadId; 146 | HANDLE scriptThread = CreateThread( 147 | 0, 148 | 0, 149 | __scriptThread, 150 | 0, 151 | 0, 152 | &scriptThreadId 153 | ); 154 | 155 | // Start the message pump 156 | MSG msg = {0}; 157 | 158 | while (msg.message != WM_QUIT) 159 | { 160 | if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) 161 | { 162 | TranslateMessage(&msg); 163 | DispatchMessage(&msg); 164 | } 165 | else 166 | { 167 | updateGamePads(); 168 | } 169 | } 170 | 171 | // Destroy the virtual machine 172 | VirtualMachine::terminate(); 173 | 174 | // Wait for the thread to exit 175 | WaitForSingleObject(scriptThread, INFINITE); 176 | 177 | return 0; 178 | } 179 | -------------------------------------------------------------------------------- /test/game_pad.dart: -------------------------------------------------------------------------------- 1 | /** 2 | * Dart Embedding Example 3 | * 4 | * --------------------------------------------------------------------- 5 | * 6 | * Copyright (c) 2012 Don Olmstead 7 | * 8 | * This software is provided 'as-is', without any express or implied 9 | * warranty. In no event will the authors be held liable for any damages 10 | * arising from the use of this software. 11 | * 12 | * Permission is granted to anyone to use this software for any purpose, 13 | * including commercial applications, and to alter it and redistribute it 14 | * freely, subject to the following restrictions: 15 | * 16 | * 1. The origin of this software must not be misrepresented; you must not 17 | * claim that you wrote the original software. If you use this software 18 | * in a product, an acknowledgment in the product documentation would be 19 | * appreciated but is not required. 20 | * 21 | * 2. Altered source versions must be plainly marked as such, and must not be 22 | * misrepresented as being the original software. 23 | * 24 | * 3. This notice may not be removed or altered from any source 25 | * distribution. 26 | */ 27 | 28 | class GamePadState 29 | { 30 | bool isConnected; 31 | double leftThumbstickX; 32 | double leftThumbstickY; 33 | double rightThumbstickX; 34 | double rightThumbstickY; 35 | double leftTrigger; 36 | double rightTrigger; 37 | int buttons; 38 | 39 | GamePadState() 40 | : isConnected = false 41 | , leftThumbstickX = 0.0 42 | , leftThumbstickY = 0.0 43 | , rightThumbstickX = 0.0 44 | , rightThumbstickY = 0.0 45 | , leftTrigger = 0.0 46 | , rightTrigger = 0.0 47 | , buttons = 0; 48 | 49 | void cloneTo(GamePadState copy) 50 | { 51 | copy.isConnected = isConnected; 52 | copy.leftThumbstickX = leftThumbstickX; 53 | copy.leftThumbstickY = leftThumbstickY; 54 | copy.rightThumbstickX = rightThumbstickX; 55 | copy.rightThumbstickY = rightThumbstickY; 56 | copy.leftTrigger = leftTrigger; 57 | copy.rightTrigger = rightTrigger; 58 | copy.buttons = buttons; 59 | } 60 | } 61 | 62 | class GamePad 63 | { 64 | /// List of game pads 65 | static List _gamePads; 66 | 67 | static void onInitialize() 68 | { 69 | _gamePads = new List(); 70 | 71 | GamePadState gamePad; 72 | 73 | // Create player 1 74 | gamePad = new GamePadState(); 75 | gamePad.isConnected = true; 76 | gamePad.leftThumbstickX = 0.5; 77 | gamePad.leftThumbstickY = 0.1; 78 | gamePad.rightThumbstickX = -0.2; 79 | gamePad.rightThumbstickY = -0.6; 80 | gamePad.leftTrigger = 0.33; 81 | gamePad.rightTrigger = 0.25; 82 | gamePad.buttons = 12288; 83 | 84 | _gamePads.add(gamePad); 85 | 86 | // Create player 2 87 | gamePad = new GamePadState(); 88 | gamePad.isConnected = true; 89 | gamePad.leftThumbstickX = 0.5; 90 | gamePad.leftThumbstickY = -0.3; 91 | gamePad.rightThumbstickX = -0.8; 92 | gamePad.rightThumbstickY = -0.6; 93 | gamePad.leftTrigger = 0.5; 94 | gamePad.rightTrigger = 0.75; 95 | gamePad.buttons = 13; 96 | 97 | _gamePads.add(gamePad); 98 | 99 | // Create player 3 100 | gamePad = new GamePadState(); 101 | gamePad.isConnected = true; 102 | gamePad.leftThumbstickX = -0.5; 103 | gamePad.leftThumbstickY = -0.3; 104 | gamePad.rightThumbstickX = 0.8; 105 | gamePad.rightThumbstickY = -0.2; 106 | gamePad.leftTrigger = 0.2; 107 | gamePad.rightTrigger = 0.95; 108 | gamePad.buttons = 63; 109 | 110 | _gamePads.add(gamePad); 111 | 112 | // Create player 4 113 | gamePad = new GamePadState(); 114 | gamePad.isConnected = true; 115 | gamePad.leftThumbstickX = 0.33; 116 | gamePad.leftThumbstickY = -0.40; 117 | gamePad.rightThumbstickX = -0.1; 118 | gamePad.rightThumbstickY = -0.25; 119 | gamePad.leftTrigger = 0.8; 120 | gamePad.rightTrigger = 0.4; 121 | gamePad.buttons = 15; 122 | 123 | _gamePads.add(gamePad); 124 | } 125 | 126 | static void getState(int index, GamePadState state) 127 | { 128 | _gamePads[index].cloneTo(state); 129 | } 130 | 131 | static void setVibration(int index, double leftMotor, double rightMotor) 132 | { 133 | 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /test/test_server.dart: -------------------------------------------------------------------------------- 1 | /** 2 | * Dart Embedding Example 3 | * 4 | * --------------------------------------------------------------------- 5 | * 6 | * Copyright (c) 2012 Don Olmstead 7 | * 8 | * This software is provided 'as-is', without any express or implied 9 | * warranty. In no event will the authors be held liable for any damages 10 | * arising from the use of this software. 11 | * 12 | * Permission is granted to anyone to use this software for any purpose, 13 | * including commercial applications, and to alter it and redistribute it 14 | * freely, subject to the following restrictions: 15 | * 16 | * 1. The origin of this software must not be misrepresented; you must not 17 | * claim that you wrote the original software. If you use this software 18 | * in a product, an acknowledgment in the product documentation would be 19 | * appreciated but is not required. 20 | * 21 | * 2. Altered source versions must be plainly marked as such, and must not be 22 | * misrepresented as being the original software. 23 | * 24 | * 3. This notice may not be removed or altered from any source 25 | * distribution. 26 | */ 27 | 28 | #import('dart:io'); 29 | #import('dart:json'); 30 | #import('dart:isolate'); 31 | #source('game_pad.dart'); 32 | 33 | String gamePadStateMessage(int index, GamePadState gamePad) 34 | { 35 | return 36 | """ 37 | { 38 | "index": ${index}, 39 | "connected": ${gamePad.isConnected}, 40 | "leftThumbstick": { 41 | "x": ${gamePad.leftThumbstickX}, 42 | "y": ${gamePad.leftThumbstickY} 43 | }, 44 | "rightThumbstick": { 45 | "x": ${gamePad.rightThumbstickX}, 46 | "y": ${gamePad.rightThumbstickY} 47 | }, 48 | "leftTrigger": ${gamePad.leftTrigger}, 49 | "rightTrigger": ${gamePad.rightTrigger}, 50 | "buttons": ${gamePad.buttons} 51 | } 52 | """; 53 | } 54 | 55 | void _handleConnection(WebSocketConnection connection) 56 | { 57 | print('New connection'); 58 | bool connected = true; 59 | GamePadState gamePad = new GamePadState(); 60 | int playerIndex = 0; 61 | 62 | connection.onMessage = (message) { 63 | // Parse the message 64 | Map parsed = JSON.parse(message); 65 | 66 | // Get the standard values 67 | String type = parsed['type']; 68 | int index = parsed['index']; 69 | 70 | if (type == 'index') 71 | { 72 | // Start sending this game pad data 73 | playerIndex = index; 74 | 75 | print('Request $index'); 76 | } 77 | else if (type == 'vibration') 78 | { 79 | double leftMotor = parsed['leftMotor']; 80 | double rightMotor = parsed['rightMotor']; 81 | 82 | print('Vibration $index: left $leftMotor right $rightMotor'); 83 | GamePad.setVibration(index, leftMotor, rightMotor); 84 | } 85 | }; 86 | 87 | connection.onClosed = (int status, String reason) { 88 | print('Closed with $status for $reason'); 89 | connected = false; 90 | }; 91 | 92 | connection.onError = (e) { 93 | print('Error was $e'); 94 | connected = false; 95 | }; 96 | 97 | // Emulate a 60fps application 98 | Timer timer = new Timer.repeating(16, (e) { 99 | if (connected) 100 | { 101 | GamePad.getState(playerIndex, gamePad); 102 | connection.send(gamePadStateMessage(playerIndex, gamePad)); 103 | } 104 | else 105 | { 106 | e.cancel(); 107 | } 108 | }); 109 | } 110 | 111 | void _startServer(String host, int port) 112 | { 113 | // Create the websockets server 114 | HttpServer server = new HttpServer(); 115 | WebSocketHandler wsHandler = new WebSocketHandler(); 116 | server.addRequestHandler((req) => req.path == '/ws', wsHandler.onRequest); 117 | 118 | wsHandler.onOpen = _handleConnection; 119 | 120 | print('Starting server ${host}:${port}'); 121 | server.listen(host, port); 122 | } 123 | 124 | void main() 125 | { 126 | // Create the gamepads 127 | GamePad.onInitialize(); 128 | 129 | // Load configuration 130 | Path path = new Path('config.json'); 131 | File file = new File.fromPath(path); 132 | Future configuration = file.readAsText(Encoding.ASCII); 133 | 134 | configuration.onComplete((result) { 135 | // Set defaults 136 | String host = '127.0.0.1'; 137 | int port = 8000; 138 | 139 | if (result.hasValue) 140 | { 141 | Map config = JSON.parse(result.value); 142 | host = config['host']; 143 | port = config['port']; 144 | } 145 | else 146 | { 147 | print('config.json not found using defaults'); 148 | } 149 | 150 | _startServer(host, port); 151 | }); 152 | } 153 | --------------------------------------------------------------------------------