Skip to content

Instantly share code, notes, and snippets.

@SeijiEmery
Last active January 30, 2017 23:24
Show Gist options
  • Save SeijiEmery/0f322dd3843f2805ca70 to your computer and use it in GitHub Desktop.
Save SeijiEmery/0f322dd3843f2805ca70 to your computer and use it in GitHub Desktop.
Hifi entity scripting example
//
// This is for a client / server side entity controller / simulator script (one script that handles
// simulations for N entities, instead of N scripts that each do simulations), though something like
// this could probably with entity scripts with some tweaking.
//
var ENTITY_TIMEOUT = 30; // 30 secs
var TIMEOUT_REFRESH_INTERVAL = 20; // 20 secs
// Entity abstraction class (there will be a JS library that does this for you soon-ish)
(function () {
var managedEntities = [];
// Simple Entity class; basically just an abstraction over the Entities calls. Add more methods here as needed.
function Entity (properties) {
// enforce cleanup of non-persistent entities
if (!properties.persistent && !properites.shared) {
managedEntities.push(this);
properties.lifetime = ENTITY_TIMEOUT;
this.timeout = TIMEOUT_REFRESH_INTERVAL;
}
var entityId = Entities.addEntity(properties);
Object.defineProperty(this, 'id', {
writable: false, value: entityId
});
Object.defineProperty(this, 'type', {
writable: false, value: properties.type
});
Object.defineProperty(this, 'isManaged', {
writable: false, value: !(this.properties.persistent || thsi.properties.shared);
})
if (!properties.persistent) {
this.timeout = ENTITY_TIMEOUT;
}
}
this.Entity = Entity;
// Update select properties on the entity.
Entity.prototype.update = function (properties) {
Entities.editEntity(this.id, properties);
}
// Get all properties on the entity. Try to keep calls to a minimum by caching
// values (position, color, etc) where it makes sense, as this is actually a fairly
// expensive call.
Entity.prototype.getProperties = function () {
return Entities.getEntityProperties(this.id);
}
// Kill this entity
Entity.prototype.destroy = function () {
Entities.deleteEntity(this.id);
if (this.isManaged) {
// If entity is managed we must remove it from the managed list
for (var i = managedEntities.length - 1; i >= 0; --i) {
if (managedEntities[i] === this) {
// swap to end + delete
var l = managedEntities.length - 1;
if (l > 0 && i != l) {
managedEntities[i] = managedEntities[l];
}
managedEntities.pop();
break;
}
}
}
}
// Global 'object' used to manage + cleanup all entities
this.EntityManager = {
update: function (dt) {
managedEntities.forEach(function(entity) {
if ((entity.timeout -= dt) < 0.0) {
entity.update({ lifetime: entity.getProperties().age + TIMEOUT_REFRESH_INTERVAL });
}
});
},
teardown: function () {
while (managedEntities.length > 0) {
managedEntities.pop().destroy();
}
}
}
});
// Other subsystems... (whatever objects you're simulating, etc)
(function () {
// ...
})();
// Setup
(function () {
// Put global state here (and init to null)
var fooObject = null;
var listOfOtherObjects = [];
// Use delayed initialization so we can wait for Entities.canRez() && Entities.canAdjustLocks()
function initEntities () {
// Create stuff...
Script.update.connect(EntityManager.update);
Script.scriptEnding.connect(EntityManager.teardown);
}
function update (dt) {
// Do updates...
}
// Teardown
function teardown () {
// De-init stuff; entities will be automatically cleaned up provided that EntityManager.teardown is called
}
function setup () {
if (Entities.canRez() && Entities.canAdjustLocks()) {
Script.update.disconnect(setup);
initEntities();
Script.update.connect(update);
Script.scriptEnding.connect(teardown);
}
}
Script.update.connect(setup);
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment