Skip to content

Commit

Permalink
Merge pull request #277 from pzuraq/update-to-decorator
Browse files Browse the repository at this point in the history
[BUGFIX] Updates internals for Ember Canary
  • Loading branch information
machty authored Mar 7, 2019
2 parents ce38e83 + 8c22398 commit f164914
Show file tree
Hide file tree
Showing 5 changed files with 191 additions and 90 deletions.
30 changes: 9 additions & 21 deletions addon/-task-group.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,8 @@ import { or, bool } from '@ember/object/computed';
import EmberObject from '@ember/object';
import { objectAssign, _ComputedProperty } from './utils';
import TaskStateMixin from './-task-state-mixin';
import {
propertyModifiers,
resolveScheduler
} from './-property-modifiers-mixin';

import { propertyModifiers } from './-property-modifiers-mixin';
import { gte } from 'ember-compatibility-helpers';

export const TaskGroup = EmberObject.extend(TaskStateMixin, {
isTaskGroup: true,
Expand All @@ -17,24 +14,15 @@ export const TaskGroup = EmberObject.extend(TaskStateMixin, {

_numRunningOrNumQueued: or('numRunning', 'numQueued'),
isRunning: bool('_numRunningOrNumQueued'),
isQueued: false
isQueued: false,
});

export class TaskGroupProperty extends _ComputedProperty {
constructor(taskFn) {
let tp;
super(function(_propertyName) {
return TaskGroup.create({
fn: taskFn,
context: this,
_origin: this,
_taskGroupPath: tp._taskGroupPath,
_scheduler: resolveScheduler(tp, this, TaskGroup),
_propertyName,
});
});
tp = this;
}
export let TaskGroupProperty;

if (gte('3.10.0-alpha.1')) {
TaskGroupProperty = class {};
} else {
TaskGroupProperty = class extends _ComputedProperty {};
}

objectAssign(TaskGroupProperty.prototype, propertyModifiers);
145 changes: 89 additions & 56 deletions addon/-task-property.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,37 +3,35 @@ import { addObserver } from '@ember/object/observers';
import { addListener } from '@ember/object/events';
import EmberObject from '@ember/object';
import { getOwner } from '@ember/application';
import {
default as TaskInstance,
getRunningInstance
} from './-task-instance';
import { default as TaskInstance, getRunningInstance } from './-task-instance';
import {
PERFORM_TYPE_DEFAULT,
PERFORM_TYPE_UNLINKED,
PERFORM_TYPE_LINKED
PERFORM_TYPE_LINKED,
} from './-task-instance';
import TaskStateMixin from './-task-state-mixin';
import { TaskGroup } from './-task-group';
import {
propertyModifiers,
resolveScheduler
} from './-property-modifiers-mixin';
import { propertyModifiers } from './-property-modifiers-mixin';
import {
objectAssign,
INVOKE,
_cleanupOnDestroy,
_ComputedProperty
_ComputedProperty,
} from './utils';
import EncapsulatedTask from './-encapsulated-task';
import { deprecate } from '@ember/debug';
import { gte } from 'ember-compatibility-helpers';

const PerformProxy = EmberObject.extend({
_task: null,
_performType: null,
_linkedObject: null,

perform(...args) {
return this._task._performShared(args, this._performType, this._linkedObject);
return this._task._performShared(
args,
this._performType,
this._linkedObject
);
},
});

Expand Down Expand Up @@ -184,10 +182,15 @@ export const Task = EmberObject.extend(TaskStateMixin, {
if (typeof this.fn === 'object') {
let owner = getOwner(this.context);
let ownerInjection = owner ? owner.ownerInjection() : {};
this._taskInstanceFactory = EncapsulatedTask.extend(ownerInjection, this.fn);
this._taskInstanceFactory = EncapsulatedTask.extend(
ownerInjection,
this.fn
);
}

_cleanupOnDestroy(this.context, this, 'cancelAll', { reason: 'the object it lives on was destroyed or unrendered' });
_cleanupOnDestroy(this.context, this, 'cancelAll', {
reason: 'the object it lives on was destroyed or unrendered',
});
},

_curry(...args) {
Expand Down Expand Up @@ -315,7 +318,6 @@ export const Task = EmberObject.extend(TaskStateMixin, {
* @readOnly
*/


/**
* The current number of active running task instances. This
* number will never exceed maxConcurrency.
Expand Down Expand Up @@ -413,42 +415,62 @@ export const Task = EmberObject.extend(TaskStateMixin, {
@class TaskProperty
*/
export class TaskProperty extends _ComputedProperty {
constructor(taskFn) {
let tp;
super(function(_propertyName) {
taskFn.displayName = `${_propertyName} (task)`;
return Task.create({
fn: tp.taskFn,
context: this,
_origin: this,
_taskGroupPath: tp._taskGroupPath,
_scheduler: resolveScheduler(tp, this, TaskGroup),
_propertyName,
_debug: tp._debug,
_hasEnabledEvents: tp._hasEnabledEvents
});
});
tp = this;
this.taskFn = taskFn;
this.eventNames = null;
this.cancelEventNames = null;
this._observes = null;
}
export let TaskProperty;

if (gte('3.10.0')) {
TaskProperty = class {};
} else {
// Prior to the 3.10.0 refactors, we had to extend the _ComputedProprety class
// for a classic decorator/descriptor to run correctly.
TaskProperty = class extends _ComputedProperty {
callSuperSetup() {
if (super.setup) {
super.setup(...arguments);
}
}
};
}

objectAssign(TaskProperty.prototype, {
setup(proto, taskName) {
if (super.setup) {
super.setup(...arguments);
if (this.callSuperSetup) {
this.callSuperSetup(...arguments);
}

if (this._maxConcurrency !== Infinity && !this._hasSetBufferPolicy) {
// eslint-disable-next-line no-console
console.warn(`The use of maxConcurrency() without a specified task modifier is deprecated and won't be supported in future versions of ember-concurrency. Please specify a task modifier instead, e.g. \`${taskName}: task(...).enqueue().maxConcurrency(${this._maxConcurrency})\``);
console.warn(
`The use of maxConcurrency() without a specified task modifier is deprecated and won't be supported in future versions of ember-concurrency. Please specify a task modifier instead, e.g. \`${taskName}: task(...).enqueue().maxConcurrency(${
this._maxConcurrency
})\``
);
}

registerOnPrototype(addListener, proto, this.eventNames, taskName, 'perform', false);
registerOnPrototype(addListener, proto, this.cancelEventNames, taskName, 'cancelAll', false);
registerOnPrototype(addObserver, proto, this._observes, taskName, 'perform', true);
}
registerOnPrototype(
addListener,
proto,
this.eventNames,
taskName,
'perform',
false
);
registerOnPrototype(
addListener,
proto,
this.cancelEventNames,
taskName,
'cancelAll',
false
);
registerOnPrototype(
addObserver,
proto,
this._observes,
taskName,
'perform',
true
);
},

/**
* Calling `task(...).on(eventName)` configures the task to be
Expand Down Expand Up @@ -485,7 +507,7 @@ export class TaskProperty extends _ComputedProperty {
this.eventNames = this.eventNames || [];
this.eventNames.push.apply(this.eventNames, arguments);
return this;
}
},

/**
* This behaves like the {@linkcode TaskProperty#on task(...).on() modifier},
Expand All @@ -503,12 +525,12 @@ export class TaskProperty extends _ComputedProperty {
this.cancelEventNames = this.cancelEventNames || [];
this.cancelEventNames.push.apply(this.cancelEventNames, arguments);
return this;
}
},

observes(...properties) {
this._observes = properties;
return this;
}
},

/**
* Configures the task to cancel old currently task instances
Expand Down Expand Up @@ -630,25 +652,34 @@ export class TaskProperty extends _ComputedProperty {
*/

perform() {
deprecate(`[DEPRECATED] An ember-concurrency task property was not set on its object via 'defineProperty'.
You probably used 'set(obj, "myTask", task(function* () { ... }) )'.
deprecate(
`[DEPRECATED] An ember-concurrency task property was not set on its object via 'defineProperty'.
You probably used 'set(obj, "myTask", task(function* () { ... }) )'.
Unfortunately due to this we can't tell you the name of the task.`,
false,
{
id: 'ember-meta.descriptor-on-object',
until: '3.5.0',
url: 'https://emberjs.com/deprecations/v3.x#toc_use-defineProperty-to-define-computed-properties',
url:
'https://emberjs.com/deprecations/v3.x#toc_use-defineProperty-to-define-computed-properties',
}
);
throw new Error("An ember-concurrency task property was not set on its object via 'defineProperty'. See deprecation warning for details.");
}
}
throw new Error(
"An ember-concurrency task property was not set on its object via 'defineProperty'. See deprecation warning for details."
);
},
});

objectAssign(TaskProperty.prototype, propertyModifiers);

let handlerCounter = 0;

function registerOnPrototype(addListenerOrObserver, proto, names, taskName, taskMethod, once) {
function registerOnPrototype(
addListenerOrObserver,
proto,
names,
taskName,
taskMethod,
once
) {
if (names) {
for (let i = 0; i < names.length; ++i) {
let name = names[i];
Expand All @@ -671,3 +702,5 @@ function makeTaskCallback(taskName, method, once) {
}
};
}

let handlerCounter = 0;
71 changes: 63 additions & 8 deletions addon/index.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,31 @@
import Ember from 'ember';
import { computed } from '@ember/object';
import { timeout, forever } from './utils';
import { TaskProperty } from './-task-property';
import { Task, TaskProperty } from './-task-property';
import { didCancel } from './-task-instance';
import { TaskGroupProperty } from './-task-group';
import { TaskGroup, TaskGroupProperty } from './-task-group';
import { all, allSettled, hash, race } from './-cancelable-promise-helpers';
import { waitForQueue, waitForEvent, waitForProperty } from './-wait-for';
import { resolveScheduler } from './-property-modifiers-mixin';
import { gte } from 'ember-compatibility-helpers';

function _computed(fn) {
if (gte('3.10.0')) {
let cp = function(proto, key) {
if (cp.setup !== undefined) {
cp.setup(proto, key);
}

return computed(fn)(...arguments);
};

Ember._setComputedDecorator(cp);

return cp;
} else {
return computed(fn);
}
}

/**
* A Task is a cancelable, restartable, asynchronous operation that
Expand Down Expand Up @@ -50,8 +72,26 @@ import { waitForQueue, waitForEvent, waitForProperty } from './-wait-for';
* @param {function} generatorFunction the generator function backing the task.
* @returns {TaskProperty}
*/
export function task(...args) {
return new TaskProperty(...args);
export function task(taskFn) {
let tp = _computed(function(_propertyName) {
tp.taskFn.displayName = `${_propertyName} (task)`;
return Task.create({
fn: tp.taskFn,
context: this,
_origin: this,
_taskGroupPath: tp._taskGroupPath,
_scheduler: resolveScheduler(tp, this, TaskGroup),
_propertyName,
_debug: tp._debug,
_hasEnabledEvents: tp._hasEnabledEvents,
});
});

tp.taskFn = taskFn;

Object.setPrototypeOf(tp, TaskProperty.prototype);

return tp;
}

/**
Expand All @@ -74,9 +114,24 @@ export function task(...args) {
* ```
*
* @returns {TaskGroup}
*/
export function taskGroup(...args) {
return new TaskGroupProperty(...args);
*/
export function taskGroup(taskFn) {
let tp = _computed(function(_propertyName) {
return TaskGroup.create({
fn: tp.taskFn,
context: this,
_origin: this,
_taskGroupPath: tp._taskGroupPath,
_scheduler: resolveScheduler(tp, this, TaskGroup),
_propertyName,
});
});

tp.taskFn = taskFn;

Object.setPrototypeOf(tp, TaskGroupProperty.prototype);

return tp;
}

export {
Expand All @@ -89,5 +144,5 @@ export {
waitForQueue,
waitForEvent,
waitForProperty,
forever
forever,
};
Loading

0 comments on commit f164914

Please sign in to comment.