I have a class Events in one file along with some objects of that class, and another file which triggers the events which have been imported. My problem is that when the trigger method is called on any of these objects, the subscribers and message fields are undefined, meaning they were deleted. How do I stop the attributes from being deleted?
#object attributes prematurely destroyed
1 messages · Page 1 of 1 (latest)
Events.js
import { world } from "@minecraft/server";
/**
* An event
*/
class GaiaEvent {
/**
* The list of subscribers for this event
*/
subscribers = []; // # means private field
/**
* The message to send when the event fires
*/
message = "";
/**
* Creates a new event
* @param {string} message the message to send on fire
*/
constructor(message){
this.message = message;
}
/**
* Subscribes a function to this event
* @param {function} fn The function to subscribe
*/
subscribe(fn){
this.subscribers.push(fn);
}
/**
* Triggers this event
* @param {object} eventData
*/
trigger(eventData = {}){
world.sendMessage(this.message);
for (const fn of this.subscribers){
fn(eventData);
}
}
}
//#region event definitions
/**
* An event that fires once a tick
*/
export const tick1 = new GaiaEvent("tick1");
/**
* An event that fires every other tick
*/
export const tick2 = new GaiaEvent("tick2");
/**
* An event that fires every 8 ticks
*/
export const tick8 = new GaiaEvent("tick8");
/**
* An event that fires when the block the player is standing on changes (only evaluates for x and z axis)
*/
export const playerChangeBlock = new GaiaEvent("player block changed");
/**
* An event that fires when the biome the player is in changes (in Gaia)
*/
export const playerChangeBiome = new GaiaEvent("player biome changed");
/**
* An event that fires when an InventoryBlock is placed
*/
export const inventoryBlockPlaced = new GaiaEvent("inventory block placed");
/**
* An event that fires when an InventoryBlock is broken
*/
export const inventoryBlockBroken = new GaiaEvent("inventory block destoyed");
//#endregion
tickEvents.js
import { system, world } from "@minecraft/server"
import { Gaia } from './api/Gaia.js'
import {vec3, Vec3} from './Vector'
import * as Events from "./api/Events"
//event triggers
//system.runInterval(Events.tick1.trigger,1);
//system.runInterval(Events.tick2.trigger,2);
system.runInterval(Events.tick8.trigger,8);
//clear entities
Events.tick8.subscribe(() => {
const players = Gaia.getPlayers();
for (const player of players){
Gaia.getEntities({location: player.location, maxDistance: 500, type: "minecraft:shulker"}).forEach((entity) => entity.remove());
}
})
//update biomes/fog
let playerLocations = []
Events.tick2.subscribe(() => {
const players = Gaia.getPlayers();
for (const player of players){
const floorpos = Vec3.floor(vec3(player.location));
if (floorpos == playerLocations[player.id]){
Events.playerChangeBlockEvent.trigger({player:player});
}
}
})
I don't see any error, try removing = "" and = []
And set the subscribers value inside the constructor
while this does change the output, it just switches what's undefined
now this is undefined
*null
and you dont have another function nested in one of the class methods?
kinda, it calls all the subscribers
should be fine then
can you just log out a constructed event?
like
Object.getOwnPropertyNames(theInstance)
are you just asking to list the properties in the object?
hmm... I put it outside the class in tickEvents.js and got this
so it definitely has the properties, but it still doesn't work
putting it in the constructor also prints the same thing
That is odd. Maybe it doesnt like how you export it. Try constructing one in the file you need it just to see if its that
it might be, but I'm not doing that in the final version
just to test
same error
the only time i had this kind of copius error was because of my import order
figured it out:
you want the runInterval to be like system.runInterval(() => Events.tick8.trigger(), 8);
this is because just passing a function to the runInterval will do Events.tick8.trigger.call(), which changes where the function is bound to (this is not the Events.tick8 anymore, it is global scope)
here is the mdn reference link for more info:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call#thisarg
https://developer.mozilla.org/en-US/docs/Web/API/setInterval#the_this_problem
^ this particularly pertains to setInterval
so system.runInterval(() => { Events.tick8.trigger({}) },8); should work?
yes
turns out I also have to do this in trigger
theres probably a better way to write that, but whatever
Use trigger inside of mc events/runInterval
nah i dont think thats true that thing happrn only when u pass the func directly here the func is being called
yeah it's not that runInterval specifically does fn.call(), but it is the same in concept bc the context of this is changed to global scope
i just used .call() cuz that was the first way i was able to repro the issue
^ mdn explained it properly in this one
umm i missing soemthin or what ? cuz what i am saying is that we are calling the func, engine calls the func only when we pass on to the func
class Foo {
constructor (value) {
this.value = value
}
say (i = 0) {
console.warn([this.value,i].join())
}
}
let a = new Foo("hello")
setTimeout(() => a.say(1), 10)
setTimeout(a.say, 20)
hello,1
,0
or its quick js working diff?
i think we agree, just misundestand each other...
putting it in a lambda was my proposed fix
qjs does it like that too
ahh so author was passing func