Page 1 of 1
More fun with inventory events
Posted: Tue Feb 11, 2014 5:07 pm
by kaypy
Suppose you have the following code
Code: Select all
function dlog(text)
__log(text)
dsb_write(debug_color, text )
end
function log_on_remove(self,id,who)
dlog("MOVED : " .. id)
end
obj.silk_shirt.after_from_torso=log_on_remove
obj.tabard.after_from_legs=log_on_remove
-- callback for M_NEXTTICK
function test_on_tick(id, data)
dlog("CALL0")
dsb_move(2,0,3,4,3) -- refers to a worn shirt
dlog("CALL1")
dsb_move(3,0,3,4,3) -- refers to a worn tabard
dlog("CALL2")
end
What do you suppose happens when the M_NEXTTICK event occurs?
Answer: It depends on when it is called...
Code: Select all
function test_after_remove(self,id,who)
dsb_msg(0,id,M_NEXTTICK,0)
end
function method_trigger(name, ppos, who, what)
dsb_msg(0,what,M_NEXTTICK,0)
end
obj.testcase=clone_arch(obj.dagger, {
after_from_r_hand=test_after_remove,
msg_handler={[M_NEXTTICK]=test_on_tick},
methods = {
{ "THROW", 0, CLASS_NINJA, method_throw_obj },
{ "TRIGGER", 0, CLASS_NINJA, method_trigger }
}
})
From running the trigger:
Lua: CALL0
Lua: MOVED : 2
Lua: CALL1
Lua: MOVED : 3
Lua: CALL2
From the remove callback:
Lua: CALL0
Lua: CALL1
Lua: CALL2
Lua: MOVED : 2
Lua: MOVED : 3
OK I can see why it could wind up working that way, but it sure makes understanding the system challenging...
Re: More fun with inventory events
Posted: Tue Feb 11, 2014 9:45 pm
by Sophia
It's a bit tricky! I think you're the first (well, second if you count me, I guess) person to analyze DSB's timing of events in this much detail.
The reason for this is because DSB has a queuing system to prevent all kinds of terrible crashes, like moving something out of an inventory slot in a function that iterates over all the inventory slots, or something. So, as a result, the processing of the
dsb_move and its subsequent events is delayed. If it would help you, I could put in a flag that would disable the queue, but I would name it something like DISABLING_THE_QUEUE_MIGHT_CRASH_DSB ...
Re: More fun with inventory events
Posted: Wed Feb 12, 2014 1:36 am
by kaypy
What I think might be useful would be almost the opposite-
How hard would it be to add something like
dsb_msg(END_OF_QUEUE,id,messagetype,data)?
What I am working towards is equipment that occupies multiple slots by putting itself in the primary slot and having virtual items it places in the other slots.
So when it detects being put in its slot it needs to first move the current occupant of the secondary slot out, then move the virtual item in. Since I have to wait for the current occupant to be removed before I can add the new one, the timing gets a bit tricky. And stepping back to a simpler test case kept giving me misleading results 8-)
So for example I think I can put items in place by something like:
1) detect base-item to-inventory
1.1) move current items away
1.2) change base-item type to something with appropriate from-inventory method
1.3) move former-base-item away
2) detect former-base-item from-inventory
2.1) current items are away, so move virtual items in
2.2) move former-base-item back in
The really messy part comes from merging all the virtual items back in to the base item when it gets removed. Or for real mess, dealing with replacing one multipart item with another.
Some sort of wait-till-the-end-of-the-queue function would allow for much less item-type shuffling
Re: More fun with inventory events
Posted: Wed Feb 12, 2014 4:59 am
by Sophia
kaypy wrote:How hard would it be to add something like dsb_msg(END_OF_QUEUE,id,messagetype,data)?
Flushing the queue before DSB is expecting it would have all sorts of weird problems. I'd really rather not do that if we can help it.
kaypy wrote:What I am working towards is equipment that occupies multiple slots by putting itself in the primary slot and having virtual items it places in the other slots.
Clever!
One option, of course, is that large items don't actually clear space for themselves at all. If they're put in a place where they "fit," then they go in, and if they don't, then they'll simply refuse to be dropped in the backpack. It's one of the easier ways to handle it, and would completely circumvent the problem-- although it's perhaps not the most user-friendly.
Otherwise, it seems like what would help you the most would be some way of handling the object clearing space for itself and then being able to move objects in without creating problems, without having to use messages delayed by a tick or something else that might be awkward like that. Ultimately, what might be the best approach would be to maintain some state information in the queue and then let calls to
dsb_move use that, so that it won't fail if you try to move something into a slot that is queued up to be emptied. That will allow everything to "just work." I'll try to update DSB to work that way.
Re: More fun with inventory events
Posted: Wed Feb 12, 2014 11:10 am
by kaypy
I wasn't thinking of flushing the queue, just appending a "send this message now" event to the end of it.
So I can do
"move this item"
"at the end of the queue (ie once the item is moved) do the next step"
Here's a version that works except there are visible delays at each step. If I could fire off the next event at the end of the queue instead of a tick later than the end of the queue it would probably all be fine
http://en.file-upload.net/download-8612 ... s.lua.html
Re: More fun with inventory events
Posted: Wed Feb 12, 2014 9:39 pm
by Sophia
Oh, I see.
I'll add a special END_OF_FRAME delay that defers the processing of the message to the end of the current frame. It isn't quite 1, but it's more than 0. That should have the same effect for you, but without the mess of connecting any message processing to the inventory queue.