linking system fixed

beta.r3js.org
-=yb4f310 2017-10-27 12:35:46 +02:00
parent c366810951
commit 3ada730069
3 changed files with 149 additions and 202 deletions

View File

@ -50,37 +50,7 @@ GameLib.Component = function(
if (this.dependencies.length === 0) {
delete this.dependencies;
/**
* Build ID to object should run through all sub components -
* if one is found which is not linked, this component is not linked fully
*/
this.buildIdToObject();
/**
* Don't try to create an instance of this object until it is fully linked
*/
if (this.linked) {
try {
if (!this.delayed) {
this.createInstance();
}
// else {
// GameLib.Event.Subscribe(
// GameLib.Event.DELAYED_INSTANCE,
// function(data) {
//
// }
// )
// }
//
} catch (error) {
console.error(error);
}
}
this.performInstanceCreation();
} else {
GameLib.Event.Emit(
@ -97,6 +67,54 @@ GameLib.Component = function(
GameLib.Component.prototype = Object.create(GameLib.API.Component.prototype);
GameLib.Component.prototype.constructor = GameLib.Component;
/**
* This function, performs standard instance creation steps for all our components, which means
* Ensure we have no dependencies
* Build a list of all child components - if they are all linked, we are ready to create an instance
* Ensure we are linked
* Ensure we are not delayed
* Try to create the instance
* Error Log if failed
* Don't do anything if we are not fully linked
*/
GameLib.Component.prototype.performInstanceCreation = function() {
var dependencies = true;
if (GameLib.Utils.UndefinedOrNull(this.dependencies)) {
dependencies = false;
}
if (this.dependencies && this.dependencies instanceof Array && this.dependencies.length === 0) {
dependencies = false;
}
if (dependencies) {
throw new Error('performInstanceCreation called while this object still has dependencies');
}
delete this.dependencies;
/**
* Build ID to object should run through all sub components -
* if one is found which is not linked, this component is not linked fully
*/
this.buildIdToObject();
/**
* Don't try to create an instance of this object until it is fully linked
*/
if (this.linked) {
if (!this.delayed) {
try {
this.createInstance();
} catch (error) {
console.error(error);
}
}
}
};
GameLib.Component.prototype.createInstance = function() {
console.log('create instance : '+ this.name);

View File

@ -59,51 +59,52 @@ GameLib.D3.Animation.ANIMATION_FUNCTION_TYPE_SCALE = 3;
GameLib.D3.Animation.prototype.createInstance = function() {
this.instance = {
rotation : null,
translation : null,
scale : null
};
try {
var instance = {
rotation : null,
translation : null,
scale : null
};
if (this.rotationFn) {
instance.rotation = new Function(
this.instance.rotation = new Function(
'data',
this.rotationFn
).bind(this);
}
if (this.translationFn) {
instance.translation = new Function(
this.instance.translation = new Function(
'data',
this.translationFn
).bind(this);
}
if (this.scaleFn) {
instance.scale = new Function(
this.instance.scale = new Function(
'data',
this.scaleFn
).bind(this);
}
} catch (error) {
console.error(error);
this.publish(
GameLib.Event.ANIMATION_COMPILE_FAILED,
{
component : this
}
)
}
return instance;
} catch (error) {
/**
* Return true here to indicate that even though the compilation failed, the instance will be fine and
* this component loaded fine.
*/
return true;
}
GameLib.Component.prototype.createInstance.call(this);
};
/**
* Updates the instance with the current state
*/
GameLib.D3.Animation.prototype.updateInstance = function() {
try {
try {
if (this.rotationFn) {
this.instance.rotation = new Function('data', this.rotationFn).bind(this);
@ -139,6 +140,7 @@ GameLib.D3.Animation.prototype.updateInstance = function() {
}
} catch (error) {
console.error(error);
this.publish(
GameLib.Event.ANIMATION_COMPILE_FAILED,
{

View File

@ -203,10 +203,6 @@ GameLib.System.Linking.prototype.start = function() {
};
GameLib.System.Linking.prototype.registerDependenciesDirect = function(data) {
this.registerDependencies(data.component);
};
GameLib.System.Linking.prototype.link = function(component, data) {
for (var property in component.linkedObjects) {
if (component.linkedObjects.hasOwnProperty(property)) {
@ -259,15 +255,18 @@ GameLib.System.Linking.prototype.resolveDependencies = function(component) {
if (!component.loaded) {
/**
* This component has not fully loaded - we should resolve its dependencies later
* This component has not fully loaded - we should resolve dependencies to it later
*/
return false;
}
/**
* Now find all the components which depend on this component
*/
var parentComponents = this.dependencies[component.id];
/**
* Now find all the components which depend on this component
* If we don't have any components which depend on this component, simply return
*/
if (GameLib.Utils.UndefinedOrNull(parentComponents)) {
@ -278,6 +277,9 @@ GameLib.System.Linking.prototype.resolveDependencies = function(component) {
return false;
}
/**
* Otherwise, process them all
*/
parentComponents.map(
function (parentComponent) {
@ -290,31 +292,32 @@ GameLib.System.Linking.prototype.resolveDependencies = function(component) {
/**
* We record that we linked a child component to a parent component
*/
if (this.resolved.indexOf(component) === -1) {
this.resolved.push(component);
}
GameLib.Utils.PushUnique(this.resolved, component);
/**
* First check if the dependencies have already been met
*/
if (GameLib.Utils.UndefinedOrNull(parentComponent.dependencies)) {
if (
GameLib.Utils.UndefinedOrNull(parentComponent.dependencies) ||
(
parentComponent.dependencies instanceof Array &&
parentComponent.dependencies.length === 0
)
) {
/**
* This means - a parent component instance could maybe have been delayed to be created
* because the component constructor or linking system did not know at time of 'createInstance'
* that it required another object to fully become active
*/
if (GameLib.Utils.UndefinedOrNull(parentComponent.instance)) {
if (
!parentComponent.loaded ||
GameLib.Utils.UndefinedOrNull(parentComponent.instance)
) {
try {
parentComponent.buildIdToObject();
if (parentComponent.loaded) {
parentComponent.createInstance();
}
GameLib.Utils.PushUnique(this.resolved, parentComponent);
parentComponent.performInstanceCreation();
} catch (error) {
console.error(error);
@ -326,47 +329,34 @@ GameLib.System.Linking.prototype.resolveDependencies = function(component) {
* It is time to 'update' this instance with this information (if any of it is relevant - depends
* on the component)
*/
parentComponent.updateInstance();
// parentComponent.updateInstance();
}
return;
}
/**
* Remove the actual dependency
*/
var index = parentComponent.dependencies.indexOf(component.id);
if (index === -1) {
// console.warn('dependency mismatch');
} else {
parentComponent.dependencies.splice(index, 1);
}
/**
* If we now managed to link the objects, and this object has no more dependencies
*/
if (parentComponent.dependencies.length === 0) {
/**
* Remove the actual dependency
*/
var index = parentComponent.dependencies.indexOf(component.id);
if (index !== -1) {
parentComponent.dependencies.splice(index, 1);
}
delete parentComponent.dependencies;
try {
parentComponent.buildIdToObject();
if (parentComponent.loaded) {
parentComponent.createInstance();
}
GameLib.Utils.PushUnique(this.resolved, parentComponent);
} catch (error) {
console.error(error);
/**
* If we now managed to link the objects, and this object has no more dependencies
*/
if (parentComponent.dependencies.length === 0) {
parentComponent.performInstanceCreation();
}
}
}.bind(this)
);
/**
* We now linked all the components which depends on this component, to this component. Time to cleanup our
* dependencies
*/
delete this.dependencies[component.id];
/**
@ -379,6 +369,9 @@ GameLib.System.Linking.prototype.resolveDependencies = function(component) {
}
);
/**
* If we happen to have no more dependencies - we linked a bunch of components which are ready to use
*/
if (GameLib.Utils.IsEmpty(this.dependencies)) {
/**
@ -396,30 +389,30 @@ GameLib.System.Linking.prototype.resolveDependencies = function(component) {
);
this.resolved = [];
}
/**
* And this is it - we need to check if the dependencies array contains any 'resolved' components -
* If it is - resolve the dependencies of this newly 'resolved' component
*/
this.resolved.map(
function(component) {
for (var key in this.dependencies) {
if (this.dependencies.hasOwnProperty(key)) {
if (key === component.id) {
/**
* We found a resolved component - which is a dependency for another component.
* Resolve the dependencies of this component - this is recursive and should be done carefully
*/
this.resolveDependencies(component);
}
} else {
var keys = Object.keys(this.dependencies);
/**
* And this is it - we need to check if the dependencies array contains any 'resolved' components -
* If it does - resolve the dependencies of this newly 'resolved' component
*/
this.resolved.map(
function(component) {
if (keys.indexOf(component.id) !== -1) {
/**
* We found a resolved component - which is a dependency for another component.
* Resolve the dependencies of this component - this is recursive and should be done carefully
*/
this.resolveDependencies(component);
}
}
}.bind(this)
);
return true;
}.bind(this)
);
}
};
@ -485,22 +478,15 @@ GameLib.System.Linking.prototype.registerDependencies = function(component) {
);
if (component.dependencies.length === 0) {
delete component.dependencies;
component.buildIdToObject();
if (component.loaded) {
try {
component.createInstance();
} catch (error) {
console.log(error);
}
}
component.performInstanceCreation();
}
}
};
/**
* When a component is created, register its dependencies, and try to resolve them
* @param data
*/
GameLib.System.Linking.prototype.componentCreated = function(data) {
/**
@ -520,69 +506,17 @@ GameLib.System.Linking.prototype.componentCreated = function(data) {
};
GameLib.System.Linking.prototype.imageNotFound = function(data) {
/**
* OK - here we do not have an image.
* The right thing to do - is to simply create a MeshBasicMaterial - we completely
* ignore the dependencies - because we want to resolve them still later.
*/
/**
* For blender files (and others) - we create Basic Material Instances
*/
var textures = GameLib.EntityManager.Instance.queryComponents(GameLib.D3.Texture);
textures.map(function(texture){
/**
* data.image is a runtime image
*/
if (texture.image === data.image.id) {
if (GameLib.Utils.UndefinedOrNull(texture.dependencies)) {
/**
* The texture instance has already been created, we need to update the instance
*/
if (texture && texture.instance) {
texture.updateInstance();
}
return;
}
/**
* Remove this image as a dependency
*/
var index = texture.dependencies.indexOf(data.image.id);
if (index !== -1) {
texture.dependencies.splice(index, 1);
}
/**
* If all dependencies have been met - create the instance and notify other listeners.
*/
if (texture.dependencies.length === 0) {
delete texture.dependencies;
texture.buildIdToObject();
if (texture.loaded) {
try {
texture.createInstance();
this.resolveDependencies(texture);
} catch (error) {
console.error(error);
}
}
}
}
}.bind(this));
/**
* When you want to register dependencies directly - Component constructor does this when it knows the
* component instance cannot be created because it has a bunch of dependencies. So it tells the linking
* system about it, so the linking system can create the instance when the dependency loads or already exists
* @param data
*/
GameLib.System.Linking.prototype.registerDependenciesDirect = function(data) {
this.registerDependencies(data.component);
};
GameLib.System.Linking.prototype.imageChanged = function(data) {
var materials = GameLib.EntityManager.Instance.queryComponents(GameLib.D3.Material);
@ -599,15 +533,6 @@ GameLib.System.Linking.prototype.imageChanged = function(data) {
};
GameLib.System.Linking.prototype.arrayItemAdded = function(data) {
};
GameLib.System.Linking.prototype.arrayItemRemoved = function(data) {
};
GameLib.System.Linking.prototype.instanceCreated = function(data) {
};
GameLib.System.Linking.prototype.meshInstanceCreated = function(data) {
this.resolveDependencies(data.mesh);
@ -791,6 +716,8 @@ GameLib.System.Linking.prototype.arrayItemAdded = function(data) {
GameLib.System.Linking.prototype.instanceCreated = function(data) {
this.resolveDependencies(data.component);
if (data.component instanceof GameLib.D3.RaycastVehicle) {
var worlds = GameLib.EntityManager.Instance.queryComponents(GameLib.D3.PhysicsWorld);