Skip to content

Commit 68a1f46

Browse files
committed
Merge branch 'master' of https://github.com/playcanvas/engine into standard-node-material
# Conflicts: # rollup.config.js # src/graphics/program-lib/programs/standard.js
2 parents 69ecac7 + 63e235c commit 68a1f46

File tree

145 files changed

+9213
-5974
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

145 files changed

+9213
-5974
lines changed

.github/CONTRIBUTING.md

Lines changed: 106 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# CONTRIBUTING
1+
# CONTRIBUTING
22

33
# HOW TO CONTRIBUTE
44

@@ -8,7 +8,7 @@
88
4. Keep PR simple and focused - one PR per feature.
99
5. Make a Pull Request.
1010
6. Complete the [Contributor License Agreement](https://docs.google.com/a/playcanvas.com/forms/d/1Ih69zQfJG-QDLIEpHr6CsaAs6fPORNOVnMv5nuo0cjk/viewform).
11-
7. Happy Days! :)
11+
7. Happy Days! 🎉
1212

1313
#### Tips
1414

@@ -22,7 +22,7 @@ Try to keep PR focused on a single feature, small PR's are easier to review and
2222

2323
## General
2424

25-
These coding standards are based on the [Google JavaScript Coding Standards](https://google.github.io/styleguide/javascriptguide.xml). If something is not defined here, use this guide as a backup.
25+
Our coding standards are derived from the [Google JavaScript Coding Standards](https://google.github.io/styleguide/javascriptguide.xml) which are based on ES5 (ECMA2009). Also we have a whitelist of modern JavaScript features (ES6+), explicitly listed below.
2626

2727
### Keep it simple
2828

@@ -32,6 +32,14 @@ Simple code is always better. Modular (horizontal dependencies) code is easier t
3232

3333
For example, use "Initialize" instead of "Initialise", and "color" instead of "colour".
3434

35+
### Whitelisted ES6+ features:
36+
37+
* `let`, `const` instead of `var`
38+
* `for of` loop
39+
* `class` instead of `prototype`
40+
* `import`/`export` handled by build scripts for bundling
41+
* function default parameters
42+
3543
### Opening braces should be on the same line as the statement
3644

3745
For example:
@@ -68,16 +76,16 @@ On save, set your text editor to remove trailing spaces and ensure there is an e
6876
### Use spaces between operators
6977

7078
```javascript
71-
var foo = 16 + 32 / 4;
79+
let foo = 16 + 32 / 4;
7280

73-
for (var i = 0, len = list.length; i < len; i++) {
81+
for (let i = 0; i < list.length; i++) {
7482
// ...
7583
}
7684
```
7785

7886
### Leave a space after the function keyword for anonymous functions
7987
```javascript
80-
var fn = function () {
88+
let fn = function () {
8189

8290
};
8391
```
@@ -88,59 +96,42 @@ foo();
8896
bar(1, 2);
8997
```
9098

91-
### Use spaces between [ ] and { } brackets
99+
### Use spaces between [ ] and { } brackets, unless they are empty
92100
```javascript
93-
var a = { };
94-
var b = { key: 'value' };
95-
var c = [ ];
96-
var d = [ 32, 64 ];
101+
let a = {};
102+
let b = { key: 'value' };
103+
let c = [];
104+
let d = [ 32, 64 ];
97105
```
98106

99-
### No semicolon on closing function brace
107+
### `let` and `const` instead of `var` (ES6)
100108

101-
Semicolons are not needed to delimit the ends of functions. Follow the convention below:
102109
```javascript
103-
function class() {
104-
} // Note the lack of semicolon here
105-
```
110+
for (let i = 0; i < items.length; i++) {
111+
const item = items[i];
112+
}
106113

107-
Semicolons **are** needed if you're function is declared as a variable
108-
```javascript
109-
var fn = function () {
110-
}; // Note the semicolon here
114+
var a = 10; // not good
111115
```
112116

113-
### Put all variable declarations at the top of functions
114-
115-
Variable declarations should all be placed first or close to the top of functions. This is because variables have a function-level scope.
116-
117-
Variables should be declared one per line.
118-
117+
### For of loop (ES6)
119118
```javascript
120-
function fn() {
121-
var a = 0;
122-
var b = 1;
123-
var c = 2;
119+
// ok
120+
for (let i = 0; i < items.length; i++) {
121+
const item = items[i];
124122
}
125-
```
126-
```javascript
127-
function fn() {
128-
var i;
129-
var bar = 0;
130123

131-
for(i = 0; i < 32; ++i) {
132-
bar += i;
133-
}
124+
// more readable but generally slower
125+
for (const item of items) {
134126

135-
for(var i = 0; i < 32; i++) { } // don't do this, as i is already defined
136127
}
137128
```
138129

139130
### Exit logic early
140131

141132
In functions exit early to simplify logic flow and avoid building indention-hell:
142133
```javascript
143-
var foo = function (bar) {
134+
let foo = function (bar) {
144135
if (! bar)
145136
return;
146137

@@ -150,7 +141,7 @@ var foo = function (bar) {
150141

151142
Same for iterators:
152143
```javascript
153-
for(var i = 0; i < items.length; i++) {
144+
for (let i = 0; i < items.length; i++) {
154145
if (! items[i].test)
155146
continue;
156147

@@ -164,36 +155,36 @@ for(var i = 0; i < items.length; i++) {
164155

165156
```javascript
166157
// Namespace should have short lowercase names
167-
var namespace = { };
158+
let namespace = { };
168159

169-
// Classes (or rather Constructors) should be CamelCase
170-
var MyClass = function () { };
160+
// Classes should be CamelCase
161+
class MyClass { }
171162

172163
// Variables should be mixedCase
173-
var mixedCase = 1;
164+
let mixedCase = 1;
174165

175166
// Function are usually variables so should be mixedCase
176167
// (unless they are class constructors)
177-
var myFunction = function () { };
168+
let myFunction = function () { };
178169

179170
// Constants should be ALL_CAPITALS separated by underscores.
180171
// Note, ES5 doesn't support constants,
181172
// so this is just convention.
182-
var THIS_IS_CONSTANT = "well, kind of";
173+
const THIS_IS_CONSTANT = "well, kind of";
183174

184175
// Private variables should start with a leading underscore.
185176
// Note, you should attempt to make private variables actually private using
186177
// a closure.
187-
var _private = "private";
188-
var _privateFn = function () { };
178+
let _private = "private";
179+
let _privateFn = function () { };
189180
```
190181

191182
### Acronyms should not be upper-case, they should follow coding standards
192183

193184
Treat acronyms like a normal word. e.g.
194185
```javascript
195-
var json = ""; // not "JSON";
196-
var id = 1; // not "ID";
186+
let json = ""; // not "JSON";
187+
let id = 1; // not "ID";
197188

198189
function getId() { }; // not "getID"
199190
function loadJson() { }; // not "loadJSON"
@@ -223,7 +214,7 @@ function asyncFunction(callback) {
223214
It is often useful to be able to cache the 'this' object to get around the scoping behavior of JavaScript. If you need to do this, cache it in a variable called 'self'.
224215

225216
```javascript
226-
var self = this;
217+
let self = this;
227218
```
228219

229220
### Avoid using function.bind(scope)
@@ -236,26 +227,47 @@ setTimeout(function() {
236227

237228
Instead use `self` reference in upper scope:
238229
```javascript
239-
var self = this;
230+
let self = this;
240231
setTimeout(function() {
241232
self.foo();
242233
});
243234
```
244235

236+
### Default function parameters (ES6)
237+
238+
Use this notation for function default parameters:
239+
```javascript
240+
// good
241+
function foo(a, b = 10) {
242+
return a + b;
243+
}
244+
245+
// not good
246+
function foo(a, b) {
247+
if (b === undefined)
248+
b = 10;
249+
return a + b;
250+
}
251+
```
252+
253+
245254
## Privacy
246255

247256
### Make variables private if used only internally
248257

249258
Variables that should be accessible only within class should start with `_`:
250259
```javascript
251-
var Item = function () {
252-
this._a = "private";
253-
};
254-
Item.prototype.bar = function() {
255-
this._a += "!";
256-
};
260+
class Item {
261+
constructor() {
262+
this._a = "private";
263+
}
257264

258-
var foo = new Item();
265+
bar() {
266+
this._a += "!";
267+
}
268+
}
269+
270+
let foo = new Item();
259271
foo._a += "?"; // not good
260272
```
261273

@@ -264,7 +276,7 @@ foo._a += "?"; // not good
264276
The hasOwnProperty() function should be used when iterating over an object's members. This is to avoid accidentally picking up unintended members that may have been added to the object's prototype. For example:
265277

266278
```javascript
267-
for (var key in values) {
279+
for (let key in values) {
268280
if (! values.hasOwnProperty(key))
269281
continue;
270282

@@ -285,51 +297,48 @@ asset-registry.js
285297
graph-node.js
286298
```
287299

288-
## Namespaces and Classes
300+
## Namespaces and Classes (ES6)
289301

290-
The entire PlayCanvas API must be declared under the ```pc``` namespace. The vast majority of the PlayCanvas codebase is made up of 'class' definitions. These have the following structure (which should be adhered to):
302+
The entire PlayCanvas API must be declared under the ```pc``` namespace. This is handled by build script, so ES6 notation of `import`/`export` should be used. The vast majority of the PlayCanvas codebase is made up of `class` definitions. These have the following structure (which should be adhered to):
291303

292304
```javascript
293-
Object.assign(pc, function() {
294-
// Closure to define new class
305+
class Class {
306+
someFunc(x) { }
307+
}
295308

296-
var Class = function () {
297-
};
309+
export { Class };
310+
```
298311

299-
Object.assign(Class.prototype, {
300-
someFunc: function () {
312+
You can also extend existing classes:
301313

302-
}
303-
});
314+
```javascript
315+
import { Class } from './class.js';
316+
317+
class SubClass extends Class {
318+
constructor() {
319+
// call parent class constructor
320+
super();
321+
}
322+
323+
someFunc(x) {
324+
// if method is overriden
325+
// this is the way to call parent class method
326+
super.someFunc(x);
327+
}
328+
}
304329

305-
return {
306-
Class: Class
307-
};
308-
}());
330+
export { SubClass };
309331
```
310332

311-
You can also subclass existing classes:
333+
Use `class` instead of `prototype` for defining Classes:
312334

313335
```javascript
314-
Object.assign(pc, function() {
315-
// Closure to define new class
316-
317-
var SubClass = function () {
318-
pc.SuperClass.call(this);
319-
};
320-
321-
// optionally can inherit
322-
SubClass.prototype = Object.create(pc.SuperClass.prototype);
323-
SubClass.prototype.constructor = SubClass;
324-
325-
Object.assign(SubClass.prototype, {
326-
someFunc: function () {
327-
SuperClass.prototype.someFunc.call(this);
328-
}
329-
});
330-
331-
return {
332-
SubClass: SubClass
333-
};
334-
}());
336+
// good
337+
class Class {
338+
someFunc() { }
339+
}
340+
341+
// not good
342+
function Class() { }
343+
Class.prototype.someFunc = function() { };
335344
```

examples/assets/scripts/lights/area-light-lut.js

Lines changed: 13 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Loading
Loading
Loading

examples/examples.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ var categories = [
1616
}, {
1717
name: "graphics",
1818
examples: [
19+
"area-lights",
1920
"area-picker",
2021
"batching-dynamic",
2122
"grab-pass",

0 commit comments

Comments
 (0)