r3-legacy/src/game-lib-system-gui.js

464 lines
12 KiB
JavaScript
Raw Normal View History

2017-06-19 15:54:02 +02:00
/**
* System takes care of updating all the entities (based on their component data)
* @param apiSystem GameLib.API.System
* @constructor
*/
GameLib.System.GUI = function(
apiSystem
) {
GameLib.System.call(
this,
apiSystem
);
2017-06-29 15:23:50 +02:00
this.guis = [];
this.selected = [];
2017-06-29 15:23:50 +02:00
this.buildGUISubscription = null;
this.meshDeletedSubscription = null;
this.meshSelectedSubscription = null;
this.meshDeselectedSubscription = null;
this.newEntitySubscription = null;
this.meshSelectionObjects = {};
2017-06-19 15:54:02 +02:00
};
GameLib.System.GUI.prototype = Object.create(GameLib.System.prototype);
GameLib.System.GUI.prototype.constructor = GameLib.System.GUI;
GameLib.System.GUI.prototype.start = function() {
2017-06-29 15:23:50 +02:00
this.guis = GameLib.EntityManager.Instance.queryComponents(GameLib.GUI);
2017-06-19 15:54:02 +02:00
/**
* Add some GUI behaviour
*/
dat.GUI.prototype.removeEmtpyFolders = function() {
for (var property in this.__folders) {
if (this.__folders.hasOwnProperty(property)){
var folder = this.__folders[property];
if (folder.__listening.length === 0) {
folder.close();
this.__ul.removeChild(folder.domElement.parentNode);
delete this.__folders[property];
this.onResize();
}
}
}
};
dat.GUI.prototype.removeAllFolders = function() {
for (var property in this.__folders) {
if (this.__folders.hasOwnProperty(property)){
var folder = this.__folders[property];
folder.close();
this.__ul.removeChild(folder.domElement.parentNode);
delete this.__folders[property];
this.onResize();
}
}
};
2017-06-29 15:23:50 +02:00
this.guis.map(function(gui){
2017-06-19 15:54:02 +02:00
gui.domElement.instance.parentElement.appendChild(gui.instance.domElement);
2017-06-29 15:23:50 +02:00
});
this.buildGUISubscription = this.subscribe(
GameLib.Event.BUILD_GUI,
this.buildGUI
);
this.meshDeletedSubscription = this.subscribe(
GameLib.Event.MESH_DELETED,
this.meshDeleted
);
this.meshSelectedSubscription = this.subscribe(
GameLib.Event.MESH_SELECTED,
this.meshSelectionChange
2017-06-29 15:23:50 +02:00
);
this.meshDeselectedSubscription = this.subscribe(
GameLib.Event.MESH_DESELECTED,
this.meshSelectionChange
2017-06-29 15:23:50 +02:00
);
this.newEntitySubscription = this.subscribe(
GameLib.Event.NEW_ENTITY,
this.newEntity
)
2017-06-19 15:54:02 +02:00
};
2017-06-29 15:23:50 +02:00
GameLib.System.GUI.prototype.buildGUI = function(data) {
2017-06-19 15:54:02 +02:00
2017-06-29 15:23:50 +02:00
this.guis.map(function(gui){
/**
* Check if we have data
*/
if (GameLib.Utils.UndefinedOrNull(data.components)) {
console.log('no data components');
return;
2017-06-29 15:23:50 +02:00
}
if (GameLib.Utils.UndefinedOrNull(data.components.length) || data.components.length === 0) {
console.log('no components selected');
return;
}
2017-06-29 15:23:50 +02:00
/**
* First, start fresh - remove all folders
*/
gui.removeAllFolders();
/**
* Sort the components by component type
*/
data.components.sort(
function(a, b) {
if (a.componentType > b.componentType) {
return 1;
}
if (a.componentType < b.componentType) {
return -1;
}
return 0;
}
);
/**
* Split the components into groups of componentType
*/
var componentGroups = data.components.reduce(
function(result, component) {
var componentData = result.pop();
if (component.componentType === componentData.componentType) {
/**
* This is the first component
*/
componentData.components.push(component);
result.push(componentData);
return result;
}
2017-06-29 15:23:50 +02:00
if (component.componentType !== componentData.componentType) {
result.push(componentData);
result.push({
componentType : component.componentType,
components:[component]
});
return result;
}
2017-06-29 15:23:50 +02:00
},
[
{
componentType : data.components[0].componentType,
components : []
}
]
);
2017-06-29 15:23:50 +02:00
componentGroups.map(
2017-06-29 15:23:50 +02:00
function(componentGroup){
if (componentGroup.components.length < 1) {
console.warn('invalid number of components');
}
var templateObject = {
template : {
/**
* Doing this here is just to put parentEntity at the top of the gui
*/
'parentEntity' : componentGroup.components[0].parentEntity
},
affected : [componentGroup.components[0]],
componentType : componentGroup.componentType
};
for (var property in componentGroup.components[0]) {
if (
componentGroup.components[0].hasOwnProperty(property) ||
typeof componentGroup.components[0][property] === 'function'
) {
if (typeof componentGroup.components[0][property] === 'function') {
templateObject.template[property] = function(__property) {
return function() {
this.affected.map(
function(component) {
component[__property].bind(component)();
}
)
}.bind(templateObject);
}(property);
} else {
templateObject.template[property] = componentGroup.components[0][property];
}
}
}
var componentTemplate = componentGroup.components.reduce(
function(result, component) {
if (component === componentGroup.components[0]) {
/**
* This is the first component, just return
*/
return result;
}
/**
* Now start to filter out the properties
*/
for (var property in component) {
if (
component.hasOwnProperty(property)
) {
if (!result.template.hasOwnProperty(property)) {
continue;
}
if (
result.template[property] instanceof GameLib.Vector2 ||
result.template[property] instanceof GameLib.Vector3 ||
result.template[property] instanceof GameLib.Vector4
) {
if (!result.template[property].equals(component[property])) {
delete result.template[property];
}
continue;
}
if (result.template[property] !== component[property]) {
delete result.template[property];
}
}
}
/**
* Store the affected component
*/
result.affected.push(component);
return result;
},
templateObject
);
/**
* componentTemplate now contains for this particular component type group - all
* the properties which are modifiable, and also the objects affected by this property changes
*/
var name;
if (GameLib.Utils.UndefinedOrNull(componentTemplate.template.name)) {
name = GameLib.Component.GetComponentName(componentTemplate.componentType);
} else {
name = componentTemplate.template.name;
}
var folder = gui.addFolder(name);
if (!folder) {
throw new Error('Could not create folder');
}
for (var templateProperty in componentTemplate.template) {
if (
componentTemplate.template.hasOwnProperty(templateProperty) ||
typeof (componentTemplate.template[templateProperty]) === 'function'
) {
if (typeof (componentTemplate.template[templateProperty]) === 'function') {
folder.add(componentTemplate.template, templateProperty);
continue;
}
if (componentTemplate.template[templateProperty] instanceof GameLib.Vector2) {
gui.buildVectorControl(folder, componentTemplate, templateProperty, 2);
continue;
}
if (componentTemplate.template[templateProperty] instanceof GameLib.Vector3) {
gui.buildVectorControl(folder, componentTemplate, templateProperty, 3);
continue;
}
if (componentTemplate.template[templateProperty] instanceof GameLib.Vector4) {
gui.buildVectorControl(folder, componentTemplate, templateProperty, 4);
continue;
}
// if (
// component.linkedObjects &&
// component.linkedObjects[property]
// ) {
// if (property === 'parentEntity') {
// this.buildEntitySelectionControlFromArray(
// folder,
// component,
// property,
// entityManager
// )
// } else if (component.linkedObjects[property] instanceof Array) {
// this.buildArrayManager(
// folder,
// component,
// property,
// component.linkedObjects[property],
// entityManager
// )
// } else {
// this.buildSelectControl(folder, component, property, entityManager, component.linkedObjects[property]);
// }
//
// } else if (typeof (component[property]) === 'object') {
//
// if (this.isColor(component[property])) {
// this.buildControl(folder, component, property);
// } else {
// //console.log('ignored: ' + property);
// }
// } else {
// this.buildControl(folder, component, property, entityManager);
// }
}
}
}
);
});
2017-06-29 15:23:50 +02:00
};
GameLib.System.GUI.prototype.meshDeleted = function(data) {
2017-06-29 15:23:50 +02:00
};
GameLib.System.GUI.prototype.meshSelectionChange = function(data) {
var meshes = GameLib.EntityManager.Instance.queryComponents(GameLib.D3.Mesh);
var components = [];
meshes.map(function(mesh){
if (!mesh.selected) {
return;
}
if (mesh.parentEntity) {
GameLib.Utils.PushUnique(components, mesh.parentEntity);
}
components.push(mesh);
mesh.materials.map(
function(material){
GameLib.Utils.PushUnique(components, material);
}
);
mesh.materials.map(
function(material){
for (var property in material.linkedObjects) {
if (
material.linkedObjects.hasOwnProperty(property) &&
material.hasOwnProperty(property) &&
material[property] &&
property !== 'parentEntity'
)
{
GameLib.Utils.PushUnique(components, material[property]);
for (var tProperty in material[property].linkedObjects) {
if (
material[property].linkedObjects.hasOwnProperty(tProperty) &&
material[property].hasOwnProperty(tProperty) &&
material[property][tProperty] &&
tProperty !== 'parentEntity'
) {
GameLib.Utils.PushUnique(components, material[property][tProperty]);
}
}
}
}
}
);
});
GameLib.Event.Emit(
GameLib.Event.BUILD_GUI,
{
components : components
}
);
};
GameLib.System.GUI.prototype.meshSelected = function(data) {
};
GameLib.System.GUI.prototype.meshDeslected = function(data) {
2017-06-29 15:23:50 +02:00
};
GameLib.System.GUI.prototype.newEntity = function(data) {
};
GameLib.System.GUI.prototype.stop = function() {
this.guis.map(function(gui){
2017-06-19 15:54:02 +02:00
gui.domElement.instance.parentElement.removeChild(gui.instance.domElement);
2017-06-29 15:23:50 +02:00
});
delete dat.GUI.removeEmtpyFolders;
delete dat.GUI.removeAllFolders;
2017-06-29 15:23:50 +02:00
this.buildGUISubscription.remove();
this.meshDeletedSubscription.remove();
this.meshSelectedSubscription.remove();
this.meshDeselectedSubscription.remove();
this.newEntitySubscription.remove();
this.guis = [];
2017-06-19 15:54:02 +02:00
};