PDA

View Full Version : Windows, sharing, and runtime controls



joshuha
June 15th, 2007, 04:05
I brought this up during beta and while I figured out a hacky way around it want to revisit the topic.

Say we have the below XML:


<windowclass name="test">
<sharable />
<frame>modifier</frame>
<placement>
<size>
<width>100</width>
<height>150</height>
</size>
</placement>
<sheetdata>
</sheetdata>
</windowclass>

<template name="gen_icon">
<genericcontrol>
<bounds>0,0,1,1</bounds>
</genericcontrol>
</template>


And the following function:


function test()
local testwin = Interface.openWindow("test","");
testwin.createControl("gen_icon","c1");
testwin.c1.setIcon("d20icon");
testwin.c1.setStaticBounds(0,0,25,25);
end


Now the purpose of the above is pretty simple. I define my own windowclass. Then when I call test at runtime via a slashhandler command it creates an instance of that windowclass and adds the genericcontrol at runtime. It works as I expect it to.

If the client calls the same command he also gets the same windows to spawn as I expect since I did not restrict who can iniatiate the command.

Now for the tricky part. Say I wanted to restrict this to the host and share the window with the client. This works but only shares the base windowclass without the control on it. The reason for this is it was added at runtime but you would think a share would share the current context of the window but it does not. I am guessing here but I suspect the client calls the window and uses its local copy of the windowclass to build the window.

So I was thinking of a way around this that would work for me. I have a function that both the host and client can run and it works for both of them seperately. How can I make this run on the client machine? What I would need is some type of way to have the client call the test function.

This would be easy if there were some sort of event or handler that I know would be guranteed to fire constantly I could use that to read a value from the DB that it had been called on the GM side and then fire a similar function locally (that would read some values from another DB node to rebuild the same window).

Anyone have any ideas?

Dachannien
June 15th, 2007, 11:25
Maybe I'm not understanding correctly how FG works when I say this, but I'll throw it out there anyway:

onUpdate always fires when a database node gets updated. If there's an object open in the local context that has a handler registered to a particular node, the function should get called in the local context when the node's onUpdate event fires. You could use the database as a sort of message passing interface.

joshuha
June 15th, 2007, 16:46
Thats not a bad idea, the only issue I worry about is speed. Earlier when testing things where I read/update the db.xml I would get severe synching issues unless I manually did a /save from the command line or the db.xml did its own save.

I'll have to play around with it to see how long it takes before the client picks up on it. In beta, I would say write a value to a DBnode and then 2 seconds later attempt to read it from the same node and get the old value (unless I manually did a /save).

I requested a saveDB function that would do the same thing as /save but not sure if thats on the todo list. Of course, the original thing back then was solved once we got to start using the Registries as that is realtime (but wouldn't work here since Registries are local to a machine).

TarynWinterblade
June 16th, 2007, 06:55
I'm very tired right now, so I might be fairly off...

Move the code to create the icon in the window into the window's onInit... that should get called each time the window is instanciated...

Hopefully that helps...

joshuha
June 16th, 2007, 07:01
That would still be static though and I might have as well declared the control in the XML no?

But the problem that I am ultimately getting at is I want it programattic so I have control at runtime or via some other automation. Can't give away what I am talking about yet though. The onUpdate handler looks like my best bet and I briefly tested this with some print functions instead of creating controls but it did fire off on the client side so I think it will work for me.

TarynWinterblade
June 16th, 2007, 07:21
That would still be static though and I might have as well declared the control in the XML no?

This is why talking to friends and trying to read posts at the same time after 15 hours of work.. is a Very Bad Idea (TM)


But the problem that I am ultimately getting at is I want it programattic so I have control at runtime or via some other automation. Can't give away what I am talking about yet though. The onUpdate handler looks like my best bet and I briefly tested this with some print functions instead of creating controls but it did fire off on the client side so I think it will work for me.

Hmm... I'm imagining some form of generic class code that I'll want to write up later (damn that Java training that makes me want to turn everything into its simplest form, then create a class that expands on that, and so on and so forth...)

Just a thought back to my old WoW UI days, though... since we have very few ways of triggering an event on the client side from the host side, you could always write some form of "whisper" command processor.

Essentially, you would send a message to the client that looks like:
"<c%>:somecommand"

And on the client side, writing code that says onMessageReceive, search for any message that starts with "<c%>" and then process whatever comes after that.

In this case, you could do something like:

<c%>:createControl:test:gen_icon:c1:d20icon:0:0:25:25

Which of course passes all the required commands (simplification can be done if the variable aspects aren't as numerous...)

Hope that helps. I thought maybe a different perspective on event triggering might be of use (this was... pretty much the only way to do things up until a very recent-ish patch... before I left it was recent anyway...)

joshuha
June 16th, 2007, 16:23
That works as well and I was using this actually for some other things. You can call a sub function to split things back into a table easily too. I did this with space seperate values and a keyword on the beginning.

string.gsub(stTrigger, "(%w+)", function(w) table.insert(trigger, w) end);

Basically it breaks thing apart by words into a table. You could change it to from words into : easy enough or whatever you wanted to use as your seperator.

The DB.xml nodeUpdate method has its advantages though because it can store the state of the "master" window as far as how many custom controls and what the state of them are. Of course, you could still do that with the message trigger method and use the local registry files to store what you get in the trigger.

Another useful thing I found for the onReceiveMessage event is for dice processing. Trying to process and say send a message to the chatwindow on the onDiceLanded event will result in your message going before the dice are spit on to the screen (as the dice message is posted AFTER that trigger is dealt with). I create a flag called afterDiceLanded at the end of the onDiceLanded in the registry. Then on the onRecieveMessage I check if that flag exists (it will only do so if a dicelanded triggered it) and then do whatever processing you need (of course storing any other information in the registry you need from the dice roll) and then remove the flag from the registry. This makes what you want to do process after the dice results hit the screen.

The only issue there is when a DM rolls his dice in secret mode, since it doesn't send the message over the network it doesn't trigger onRecieveMessage.

What we need, devs, is an onAddMessage trigger too!

TarynWinterblade
June 16th, 2007, 20:27
That works as well and I was using this actually for some other things. You can call a sub function to split things back into a table easily too. I did this with space seperate values and a keyword on the beginning.

string.gsub(stTrigger, "(%w+)", function(w) table.insert(trigger, w) end);

Basically it breaks thing apart by words into a table. You could change it to from words into : easy enough or whatever you wanted to use as your seperator.


Regex is always so useful and yet, I normally hate trying to remember how to form one for the issue at hand. >.<




The DB.xml nodeUpdate method has its advantages though because it can store the state of the "master" window as far as how many custom controls and what the state of them are. Of course, you could still do that with the message trigger method and use the local registry files to store what you get in the trigger.


That's a very good point. I never thought about that aspect of things.



Another useful thing I found for the onReceiveMessage event is for dice processing. Trying to process and say send a message to the chatwindow on the onDiceLanded event will result in your message going before the dice are spit on to the screen (as the dice message is posted AFTER that trigger is dealt with). I create a flag called afterDiceLanded at the end of the onDiceLanded in the registry. Then on the onRecieveMessage I check if that flag exists (it will only do so if a dicelanded triggered it) and then do whatever processing you need (of course storing any other information in the registry you need from the dice roll) and then remove the flag from the registry. This makes what you want to do process after the dice results hit the screen.


*checks his code*

Are you sure about onDiceLanded causing messages to fire before the dice message does? I was testing out an automatic fumble rolling method for attack rolls, it sends two messages - one being the actual roll (using a random number and faking the actual die roll), and the other being the result (ie: "So-and-so falls down from fumbling the attack badly."). This all fires in onDiceLanded, and appears in the correct order (original roll, fumble roll, description text).

The key, I think, is to make sure you call deliverMessage on the original message first, before you start calling other functions.

(as for the automatic fumble rolling... I have no idea if it's actually going to make it into the final code. It seems kinda tacky in retrospect)



The only issue there is when a DM rolls his dice in secret mode, since it doesn't send the message over the network it doesn't trigger onRecieveMessage.

What we need, devs, is an onAddMessage trigger too!


Hear hear! And while we're at it... I'd like a way to change the message data in onMessageReceieved.

joshuha
June 16th, 2007, 21:30
Are you sure about onDiceLanded causing messages to fire before the dice message does? I was testing out an automatic fumble rolling method for attack rolls, it sends two messages - one being the actual roll (using a random number and faking the actual die roll), and the other being the result (ie: "So-and-so falls down from fumbling the attack badly."). This all fires in onDiceLanded, and appears in the correct order (original roll, fumble roll, description text).

The key, I think, is to make sure you call deliverMessage on the original message first, before you start calling other functions.


Well I suppose if you call your own deliver message for the original data and then return a true that would allow you to control the order a bit. I was still letting it exit and process normally.

I would have stilll ended up using the registry though to maintain a running count of multiple rolls and spit out a total once a condition is met but will keep that in mind for other applications.

TarynWinterblade
June 16th, 2007, 21:56
Well I suppose if you call your own deliver message for the original data and then return a true that would allow you to control the order a bit. I was still letting it exit and process normally.

I would have stilll ended up using the registry though to maintain a running count of multiple rolls and spit out a total once a condition is met but will keep that in mind for other applications.

Right. Sorry. My code was just expanding on the fullattack die type in the normal d20 code. Didn't bother thinking that things could just get processed normally. >.<

Griogre
June 18th, 2007, 01:42
Regex is always so useful and yet, I normally hate trying to remember how to form one for the issue at hand. >.<
LOL, so very, very true. :p

joshuha
June 18th, 2007, 04:59
Right. Sorry. My code was just expanding on the fullattack die type in the normal d20 code. Didn't bother thinking that things could just get processed normally. >.<

I actually ended using this with a combination of the registry to keep rolling totals for exploded dice and do some other neat tricks that I can't give away yet.