I've been working on a way to sort of duplicate a composer for the standard client, of the MUD I play.
What this would do, in python, is allow easier editing of files, then send the resulting text to the main MUSH window, or discard and exit.
What I have so far is below, and well.... its not working.
When I call the 'edit' function via an alias, it opens up the TK window and all, but then it goes straight to the 'save' function. When you exit that (because It won't save no matter what, and I can't figure out why I can't even get THAT working), it'll freeze or crash Mush.
Any ideas at ALL on how to rectify one or all of these issues. Thanks
def edit(*args):
textedit()
class textedit(Frame):
global Root
Root = Tk()
global Sb
Sb = Scrollbar(Root)
global Tx
Tx = Text(Root)
def __init__(self, parent=None):
try:
Tx.config(font=('Bitstream Vera Sans Mono', 9, 'normal'))
except:
Tx.config(font=('courier', 9, 'normal'))
Tx.focus_set()
Sb.pack(side=RIGHT, fill=Y)
Tx.pack(side=LEFT, fill=Y)
Sb.config(command=Tx.yview)
Tx.config(yscrollcommand=Sb.set)
menubar = Menu(Root)
File = Menu(menubar, tearoff=0)
menubar.add_cascade(label="File", menu=File)
File.add_command(label="Save", command=textedit.save(self))
File.add_command(label="Quit", command=Root.destroy)
Root.config(menu=menubar)
Root.title("MUSHComposer -- " + str(world.WorldName))
def save(self):
filename = asksaveasfilename()
if filename:
text = Tx.gettext()
open(filename, 'w').write(text)
al_norm(text)
I assume you are creating a window here. One of the rules in Windows is that you can only have **one** primary window for each execution thread. When you use "None", or NULL is some others, you are basically telling it to create a new primary window. The OS will attempt to do so, may even display the window (maybe), but the moment you attempt to close it the system won't have a clue which primary window you are talking about. That assumes you even get far enough to close it though, sometimes it just hangs or crashes immediately as the system can no longer tell "which" window system events for the application should go to. I am not real clear on what does go wrong, just that its not good.
You can try using the "GetFrame" function to return Mushclient's own window, then use that as the "parent". However, no one has attempted this since the "GetFrame" function became available, so no one really knows how things like button clicks, etc. will work, or even if they will work at all, in this situation. I admit, I have had other things I have been doing that have distracted me from even trying, but it all hedges on "if" events are handled right.
In other words, if its possible depends entirely on if clicking on a button on the window you create "will" actually send the event to the script, or if it vanishes into limbo because of some unknown issue. No one here knows. No one here has, sadly, really tried since it became theoretically possible, and I have found a complete lack of compassion for the ignorance we share, never mind pre-existing examples, on forums about the subject that might answer the question. I posted a request for something on it a week ago and still haven't got a response where I did. The previous one I posted they told me to talk to the people on the current forum I just posted at last week. I am getting the run around, either because the answer is so damn obvious they don't want to bother, or because they don't have a clue either.
By all means try. If it works, then at least we know "one" of them does. And that may be enough to suggest that wxLua will work to, if Nick switches to that instead of plain Lua.
What this would do ... is allow easier editing of files, then send the resulting text to the main MUSH window, or discard and exit.
Why not just "send to notepad" (the existing editor built into the client), and then do something with that once you have edited it? For instance, GetNotepadText gets the contents of a notepad window.
Or, the notepad window has a "send to MUD" option (Edit menu) for sending the text back to the MUD.
Sigh. Nick. Don't torpedo this before it gets off the ground. If he can get it to work, it will answer a number of questions we need answered... The problem he is trying to solve actually goes way beyond anything you can solve with, "Why not just use the notepad and some script?" And.. One good reason imho, you can't place the notepad anyplace but in the MDI frame, which severely limits your ability to use it, unless you have lots of desktop space or multiple monitors, which is currently buggy, **and** you leave the main window stretched to the entire available desktop space. Seperate windows are *far* more versitile and can be used for more than pure black and white text, if anyone can manage to make them work.
Mind you, if he doesn't want to go through the hassle to figure it out, that's another thing. But its not like making the notepad work as he wants is any less trivial, since it doesn't exactly come with buttons "specific" to the tasks he wants to perform.
I wasn't torpedoing it. If the intention is to develop a generic way of doing GUI interfaces, well fine.
However sometimes what is really required is a simple solution to the problem. The requirement in the original post seemed to be a way to "edit files" and "send the resulting text to the main MUSH window". The notepad does that.
Hey, Nick:
I HAVE tried it your way. The issues I find with this is to save/quit/send the text you still have it within the MUSH main window, thus covering up anything else you have, AND would still have to use aliases and the like to try to save/quit/send the text.
Quote:
you can't place the notepad anyplace but in the MDI frame, which severely limits your ability to use it
That really is my biggest factor in trying to create a seperate window for the editor
I really AM trying to make it its own GUI window, only using TK, so that anyone with Python can use it. I mean its not going to be any super 'OMG AWESOME', Syntax highlighting, spell-checker of an editor. Just a basic one.
My goal with this project is, to learn more of TK (proper usage), make a useful GUI approach to edit simple text files, and allow the window to be a seperate entiety of MUSH.
Glade someone else is as bugged by the limitations as I am. lol
Now comes the hard/easy part. In principle, it should be as easy as doing:
def __init__(self, parent=world.GetFrame)
instead of "None". The problem is, its not clear how events are handled. Basically, we are not sure if Python, TK, or something like wxLua (which I would love to see replace Lua because of its GUI systems) have there own event handler, and more to the point, if events are correctly sent to them, instead of to Mushclient. If they have to pass through Mushclient, then its not clear how/if MFC will pass them back to the script, or if something in Mushclient itself must be changed to make this happen. I have had a question posted on a wxwidgets forum for a week, which no one has answered, about just what happens in this case. Maybe someone asking on a Python forum can get a better response... Basic problem is, most implimentations either have Python, etc. creating **all** GUI elements, not just taking them onto an existing client in which the script runs, or they are imbedded in something like Internet Explorer, which has its *own* event handlers and connection systems to create and link the objects to the scripting.
Worst case, we need to have Nick make a few changes to Mushclient to make it work, but no one here has a clue what, or even if, this is needed. Best case, it works without changes. We just don't know at the moment. *However*, I suspect that the answer is, "It will work anyway", since I am reasonably sure I read something some place about people using Events to *hook* into what someone else's application was doing and keep an eye on what was going on in it. I am less certain if that "hook" involved telling the existing object to add the application as an event sink, or if instead they used some crazy system call to latch into the main event stream. The later is damned dangerous and if things are not released back the way they where before, it *will* crash the entire OS, since the next link in the chain of application that "should" be called becomes a "Null" pointer, instead of a correct location (oops!).
Anyway, making the window *should* be as easy as replacing that one line. The real question is, "Will clicking the "save" button/menu item then correctly call 'save(self)'?" At the moment, we simply don't know, or how to fix it if it doesn't.
If they have to pass through Mushclient, then its not clear how/if MFC will pass them back to the script, or if something in Mushclient itself must be changed to make this happen.
As I think I may have mentioned before, as MUSHclient is written using MFC, the internals of MFC do the initial handling of events, and if MFC doesn't think an event is for the application, then it won't be given it.
The other problem here is the notion of "pass them back to the script". The script is not something that is "always alive" - it is activated at certain times, eg. when a trigger calls a script. Then MUSHclient does a "script engine call", and while that is active, then MUSHclient is dormant.
I see from the wxwidgets mailing list that you (Shadowfyr) have been pursuing this discussion there in the hope of getting some resolution to the problems we are aware of. As far as I can see, there are still unanswered questions.
Looking at the description for wxLua on the SourceForge site, we see this: "It consists of an executable for running standalone wxLua scripts and a library for extending C++ programs with a fast, small, fully embeddable scripting language.".
Notice the main aim is to run "an executable for running standalone wxLua scripts". That is, and the demos seem to support this, that you can make a GUI executable with Lua as the script language. This is fine, because the executable has its own event loop.
It still isn't clear to me how a program, like MUSHclient, that already has its own event loop, will marry with wxLua, which wants one too. The references on the mailing list to other applications (eg. Photoshop plugins) sound a little doubtful, with the poster saying "I believe there is code about how to do this".
Yes. The thing with stuff like Photoshop is that their own code contains an interface which "includes" functions to tie stuff like new windows, etc. into the application. I really wish I understood event sinks better. :(
I mean, presumably all that a "connect" function does is tell the object, "Every time *you* have this event, you need to call a function at *this* address." Its all the stuff in between that is bloody unclear, including if those entry points might "wake up" the script engine without Mushclient itself having to do so. Its bloody frustrating to not be able to get the information from wxLua forums, so having to nose around wxwidgets, which **isn't** the same thing at all. Wxwidgets isn't a scriptable implimentation, its actually a complete replacement for the normal APIs you might use to build an application, or rather a *translation* layer, which lets you port those API calls between different platforms. So, its not a surprise that they can't come up with an answer about it. But its damn frustrating that no one else can either. Even a simple, "No, that won't work without modification.", would be nice.
In any case, one can simply try and see by making the one change I suggested to the Python script. The crashing is caused by trying to create two primaries in the same application, you can crash yours just as easilly if written in plain C++ without Python doing that. And Python uses similar "connect" functions to link events to event sinks to those that wxLua would be using. Its not entirely clear if its the "base" application handling the events or the script engine.
Mind you, I have seen cases of people talking about integrating Lua, wxLua, etc. into "text based console applications", and those ***don't*** generally have event systems at all. Its quite possible that the engines supply their own event handlers and that Windows is smart enough to know that objects the engine own go there. That is why I suggest just trying it with Python to see what happens. If not, we at least know that something more needs to be done to make it happen.
The reason you can attatch Lua into pretty much anything is because it has a nice handy C interface. You can run bits of compiled C code as Lua functions, and you can have C functions call easily into Lua's interface. Lua has it's own event handling, and doesn't rely on a specific program's.
I'm not too terribly clear on this, but a friend of mine has been explaining it to me here and there while he's been teaching me Lua. It actually does have a different interface with the C libraries than most other scripting languages, which is why it is so easy to incorporate into programs.
Plugging Lua into an application is an entirely different beast from setting up any kind of Windows event handling.
Lua per se doesn't really have "event handling" when you embed it into an application. When you embed Lua it simply gives your application the ability to make calls into Lua. (And let Lua make calls into your C program, but those always start by calling Lua which then calls back to C.) Lua itself doesn't open up handlers to intercept anything.
It's really not comparable to talk about adding Lua into an application, and letting Lua manage windows and so forth.
And in particular, Lua certainly does not supply its own event handler. I'm not sure if wxLua does; it probably does, one way or another. Of course, that makes it hard to mix wxLua with another piece of code that is expecting to have its own full control over the event loop.
It's undoubtedly possible; the real question is how much work Nick would have to do to make it happen. My impression is that it would require an awful lot of work, most probably far too much to justify the gain.
Really? Too much to justify the gain? See, I don't entirely agree with that. Sure, you can use Mushclient now with WINE, but there are some minor limitations. If you also want to use a custom GUI element, like a mapper, you may run into **major** limits that make it effectively impossible. The WX libraries are cross platform, so its not impossible to a) have way more portability to start with and b) even possibly at some point replace the MFC with wx, thus making the application itself completely portable. (Mind you, I am not sure how the license for wx works or if its "practical" to do that. If its some version of GPL that doesn't allow the main application to be closed source...)
And frankly, how the heck else do you manage it? Supply every person that downloads Mushclient with a copy of GCC or WMing and a book on C++ programming? Right now its simply not practical for a casual coder to design ***anything*** to work with Mushclient. I can tell you right now, there are a half dozen ideas I would implement tomorrow *if* some way to do this existed that didn't rely on writing something in a completely different language and compiling it, or creating some lame wrapper for a program or dll I want to use, just because I can't use event sinks at all right now. The problem effects nearly everything we do with this client. You can't even open a web page without wasting script time constantly looking to *see* if the page finished loading in IE, because you can't simply have it "tell you" its done directly. Music players are crippled by the need to constantly ask what song it playing, instead of being told it changed to something new, then looking "once" to find out. Office applications, graphics application, etc. Anything the *pre-exists* and supplies a means to talk to it is crippled because of this when used from inside scripts. Stuff you code yourself.. Less so, but its still absurd that you have to call callplugin or some similar Mushclient function, passing it data on what happened, because you can't simply have the "what happened" call the script needed directly.
Anything you want to do right now requires far more than the basic knowledge of scripting and some simple examples the average user has access to. By comparison, wxLua, or even Python, you could teach someone the basics of creating a window with a button on it in five minutes. I would call that a HUGE advantage. And frankly, I suspect its ignorance that is making the actual problem seem insurmountable or so complicated that its not practical to try.
I don't know near enough about it, but I have read bits and pieces on event sinks, handlers, etc. And by my estimation, which I admit could be wrong, the changes needed are probably little more than overriding a single function in the MFC interface with a new function, which itself would simply do little more than:
function blah (){
if event.name contains "Lua"
call wxLua.eventhandler(event)
else
call me::original_function;
}
In other words, you redirect the events "temporarilly" to something that can figure out that they belong to the script system, pass those that do to it, and any that don't you simply pass "back" to the original MFC event handling function. This of course assumes that such a system exists. If not, then the event source *knows* where the script function is "supposed" to be, so I would assume that part of the event fired would "include" the location of the sink its "supposed" to go to. All that would need to happen is waking the script engine up, calling the address (possibly after verifying it still existed), then continuing on from there.
Now, its been like 4-5 years since I saw an example of anyone doing this, so it could be more complex than I think, but not by the huge chasm of difficulty everyone seems to think it would be. All you are doing is creating an event intercept, without disrupting the existing event sinks. Doing so, from what I remember, is quite trivial. The only question is, "Do we need such a thing in the first place?", and if that intercept needs to handle the function call or just pass things along to the right event handler. By comparison Nick has done stuff just in the last 3-4 updates that make such a change look as simple to manage as successfully filling a glass with water.
I suspect the answer lies in asking the question the right way, in the right place. Problem is, I am notoriously bad at asking the right question the first time, let alone figuring out where the right place really is to ask it. Worse, most places that deal with these things have a notoriously bad habit of linear thinking when it comes to how they code "everything" with it. It literally wouldn't occur to 99.9% of them that one might even *try* to code part of a program in something "other" than wxLua itself. The other 0.1%... problem never imagined trying to intergrate it into and existing GUI. I have chased my tail before over some things like this, only to have the "actual" problem explained in a three page article, with example code. It can drive you slightly nuts looking for anything that isn't "standard" implimentation.
I think you missed the point. Obviously, it would make your day, week, month and year, and be the best thing since sliced bread. But it's very unclear to me that for Nick the work is worth the gain it will bring him. There are relatively few people with this demand as specifically, urgently and vocally as you, and even fewer who would put their wallet where their mouth is. So, from what I can see of the picture, in terms of the cost Nick would incur versus the gain he would obtain, if I were in his shoes, doing something like this would make rather little sense.
Shadowfyr, you have previously suggested that I change MUSHclient to use wxLua rather than Lua. But how practical is this? According to the wxLua web site the size of the installer is 5.3 Mb.
Compare this to the current size of the MUSHclient installer, which is 1.82 Mb.
It seems to me that to support wxLua, even if it were practical from a technical viewpoint, which I am not sure about, would amount to a huge "bloat" of the installation size for MUSHclient (an extra 5.3 Mb) for something that virtually no users, apart from you, have requested.
It isn't totally clear from their page whether you also need wxWidgets as an extra download.
Frankly, it all seems too much. I don't like the idea of the "core" of MUSHclient representing maybe 10% of the total download, and the other 90% being wxLua, wxWidgets, etc.
Compare the size of wxLua (5.3 Mb) to the lua DLL (available here) which is 129 Kb. It is just a huge amount larger.
Quote:
You can't even open a web page without wasting script time constantly looking to *see* if the page finished loading in IE, because you can't simply have it "tell you" its done directly.
Well, loading web pages is asynchronous, that is, it takes time to do. I don't offhand see how you could get that to work, although the luasql package might allow that to a certain extent.
Quote:
Music players are crippled by the need to constantly ask what song it playing ...
MUSHclient wasn't designed to be a music player. I am concerned that if changes were made to implement this, perhaps at considerable effort, then the client would become more unreliable (or even, just larger) for the 99% of users who are not worried about trying to do such things.
As of MFC 4.0 there was implemented a system called "message reflection". This is a MFC specific set of functions that allow you to redirect any event messages recieved by the main window to an event handler in its children. This means you could create a class whose "sole" job was to strip out events specific to script and handle them, using nothing more than fairly standard code and existing MFC features. Now, mind you, this may still mean that Mushclient would need to keep track of which events to watch for and which sinks are to be called when doing so, but that's just a lookup table, and *maybe* some script function to call object.invoke to have Mushclient create the connection itself. If however, wxLua has its own event handling system, then in, if it follows the specification for reflection, which I admit is a big if, then it will already be recieving those. If it doesn't, but again, does have a handler, all Nick needs is a class that impliments reflection for events in general, then code in there that passes the reflected events to the script engines event handler.
The first possibility requires two functions and maybe 100 lines of code (at a guess), the second case, if event handlers exist in wxLua, would require *no* code at all, the last case... Probably about 5 lines of code. Worst case, may require something to keep track of a table that is basically identical to the tables he already implimented to support *existing" function calls for things like OnPluginSend, etc. I.e., the code already exists to handle the function calls, its just sorting out the events that is the issue. And that is imho, not that big of a deal, since all it involves it calling "Invoke" on the object a few times to get the event name, and inform it to start generating events. Everything else is simply and extension of what the client is already doing. And that is the *worst case* situation.
I'll keep looking though, to see what else might effect how it works. Heck, assuming that the version of C++ I have can create at least MFC4.0 application (its very old), I might even try to see if I can get an example working. Maybe. Its not like I am that good at C++. lol
wxLuaState(wxEvtHandler *handler, wxWindowID id = wxID_ANY)
Creates a complete wxLuaState, but you can provide an event handler, eg. wxApp or wxWindow derived class, to get and handle the wxLuaEvents, see also Get/SetEventHandler.
Now the only question is if a) this works automatically even as in an existing GUI or b) how do you "inform" this handler of events external to wxLua....
Hmm. Edit to add this:
From the "state" features you get:
int m_wxluatag_wxEvent; // The lua tag for wxEvents
and
wxEvtHandler *m_evtHandler; // event handler to send wxLuaEvents to
wxWindowID m_id; // event id to send the events with
Which presumably should let you both identify what events are fired by wxLua objects "and" where to reflect them to in order to make it work. In theory. Not sure yet if there is some more direct means to send wxLua events, or even if you need to do that in the first place. Worst case is looking a lot easier. Especially since, with the above, one only needs to figure out which events "belong" to wxLua then throw them to the wxLua handler when detected. No need to even keep track of any of the functions locations, in theory.
Though, since there is a "GetEventHandler" function, which I forgot about already, you just need to know what ID to look for in the events.
I'm always amazed at the amount of things that you find can be added with just a complete reworking of how MUSHclient is written. It comes up in thread after thread... If you think it's so easy, just write your own client and be done with it.
The main issue, which you failed to notice or are ignoring, is bloat. Making a MC download 5-6 times it's current size to add a small amount of features just does not sound like a good idea. Yes, things may be a bit more convenient for some, but is it worth the extra time and space? Also, for many of these issues, MC already has quite a few quick workarounds.
ex: For what the original post has, just copy/paste what you need to notepad/textpad/whatever editor you want, edit the files, save, then send the file back to the MUD. It's a seperate window, and you can just rewrite the same file over and over again if you're concerned about having too much to keep track of. This is how I dealt with area creation for the MUD I play on a few years back so I could look at the help files on the server right next to the mobs or rooms. I still have the whole area backed up in a zip file.
I agree that bloat is an important issue but I think that the amount of time Nick would have to spend is a bigger issue. As you say, these changes only require a complete rewrite of the event and windowing system...
After all, if all this only took an hour for Nick to do, well maybe it would be worth distributing a version of MUSHclient with the bloat just to stop these discussions. :-) But the problem is that it'll take much more than an hour; it will involve lots of research, in addition to actually rewriting the code.
Bloody hell. What bloat? At this point it looks like we are maybe talking about 10-20 lines of fracking code, not 10 MB of extra data. And, as I said, even in the worst case, the damn thing is *already* doing 90% of what is needed to handle event calls, should I turn out to be dead wrong, just to support existing callbacks. We are not talking about brain surgery here, complete redesigns or even gluing an entire additional application onto the side of it. We are talking about what, even in the worst case, shouldn't be more than a *minor* change. And that is still assuming we even need one.
By comparison half the stuff that has been added in the last few major revisions *have* been huge changes that really did add additional bloat. We are talking about a few fracking k here at worst, and probably not even that. Get fracking real!
And just to be clear, it might take only an hour to impliment and **I** am the one doing the fracking research, since I seem to be the only person that *ever* does any at all on these things. Everyone else just whines about how, "Its probably too hard!", every time something comes up. Sorry if I am getting a tad fed up with that.
Why are you so surprised that you are the only one doing the research? You appear to be pretty much the only one who cares about this stuff so much.
If you're so fed up with this whole thing, I earnestly urge you to try writing your own client that supports this. The whole community will benefit, and everybody will learn from it, you most of all from having actually written some code to make it work.
My impression is that you are putting an awful lot of blame on Nick, continually insinuating that he is almost stupid for not seeing how simple the change is. It doesn't matter how simple the change "should be" according to you, what matters is how simple the change is or is not.
He has told you several times that it is very non-trivial from his perspective and you keep throwing it back in his face. There have been several conversations on this forum where you continuously bring up the same points and yet you have not, to my knowledge, written a single, even very small, C++ program demonstrating these supposedly extremely simple changes.
I don't want to be too blunt here but I think it would really, really help you to go out and write some code and see for yourself. Try to see things from Nick's perspective of how the world is instead of what you (and apparently pretty much only you) want the world to be.
I am sorry, but no one here has given a good reason to say its non-trivial, save for the excuse, "I don't know how to do it, so it must be non-trivial." With all do respect to Nick, this isn't a valid argument. There have been 1-2 other case where things "seemed" non-trivial but proved far less complicated that expected.
Note, I finally managed to ask the question right, I guess, on the wxLua list. And according to the poster I am on the right track. Which means, the solution may be as simple as the pseudocode:
OnMessage_Reflect (event) {
current_engine = 0
do while more engines {
result = current_engine.handler(event);
if result = false exit loop;
current_engine ++;
}
}
Plus maybe 1-2 more lines to create this as a reflection point for event messages in a Mushclient class. Wow!!! That's just a huge amount of bloody bloat....
Agruments from ignorance are not useful. And last I looked, I only see *two* people actively complaining here that I should just give up.
You can see there every released MUSHclient version, including its size. From version 3.00, released in 2001, which is 1.2 Mb, to version 3.84 in December 2006, which is 1.8 Mb, there has been a very gradual creep of file size. This has generally been caused by the extra features that everyone is pleased with, like spellchecker, Lua scripting, extra scripting functionality, multi-line triggers, and so on. However the point is that the file size of the installer has only gradually changed in size.
Look at at year ago (version 3.69), which is 1.7 Mb, to today, which is 1.8 Mb. I don't see how this can be described as "huge changes that ... add additional bloat". That is only 0.1 Mb change over a year.
You have asked me to change from straight Lua (129 Kb DLL) to wxLua (5.3 Mb installer). Surely this change alone would be enormous bloat, compared to the 0.1 Mb change over the last 12 months?
You are talking about adding 10-20 lines of code (your figures) but bypassing the problem of needing the extra 5 Mb of wxLua which those 10 lines of code need to call.
It also isn't clear if this additional to ordinary Lua. Do you want every scripter who uses Lua to switch to wxLua? If not, then possibly the client has to support another script language, which is not part of the Windows scripting model.
I'm not trying to be difficult, but it simply isn't clear to me that I can solve your problems by "just adding 10 lines of code". If I could, I would.
Plus maybe 1-2 more lines to create this as a reflection point for event messages in a Mushclient class.
Yes, but how does wxLua come into the equation? Does it get distributed with MUSHclient? Is it an optional extra? When does the engine get created? Do we need another script language in the list? Does the support for plugins need to be changed to allow for that too?
Can you say that the person that gave that psuedo code (and pseudo code is a bit doubtful when someone "thinks this should work") is referring to implementing it into a C++ program which has its own event loop, and is written with MFC?
Hmm. Didn't realize wxLua was that big... Might be easier, ironically, to try to fix Python, since its an optional and has the same issue, where wxLua would probably be "replacing" Lua.
As for the psuedocode. That is mine, based on what I have uncovered. And its not yet clear if that is even needed. The person I am talking to implied that the OS takes a bottom up approach to handling event handlers and might automatically talk to the wxLua one "first", then pass it up the chain to the MFC client. I don't think that is the case.
As to bloat.. What if someone makes a 3MB file that displays icons, which everyone likes so much that they "insist" they need it, then someone else makes a 5MB mapper, then someone else makes a code editor, which is another 10MB. Sure, the client isn't any more "bloated", but it just means 17MB of unsupported third party applications you still have to download to get what amounts to 1-2MB of completely redundant junk that each of those use (not including things like VB Runtimes), which is part of that 5MB extra.
But, ok, I see your point. As nice as providing the casual coder with real tools to do something with may be, it does have what could be unaccectable overhead. How to fix that, such as making a Windows Scripting version that can be optional instead, is something I need to consider. It may turn out that the issue with *it* is a similar enough issue to what already exists for "all" event supporting software, that solving this problem can provide a less bloating solution for everything, without having to use wxLua at all.
As for how wxLua came into the equation in the case of the psuedocode. It *does* have its own event handlers. The point of "message reflection", which is an MFC feature, in case you missed that, would have been to redirect events that belong to wxLua to the engines handler(s), instead of throwing them out. In other words, it allows you to intercept such messages in an MFC application, when **normally** all those things are completely hidden from you.
Python may have the same issues. However, it is optional, not supplied with the client and does use Windows Scripting as an interface. It may be a better candidate under the circumstances. The only problem I see in solving for "it" is that someone is bound to wonder what stops Lua from doing the same thing, and the whole can of worms crops up again.
But yeah. I didn't really think about the size issue in this particular solution. Sigh... Need to think some more about how to avoid depending on wxwidgets as a wrapper for the API layer. :( Would be so much easier if that was installed standard on most systems. Not that it would help as much as I would like, looks like the purely wxLua parts are over 3MB... Grr..
Ok. Maybe I will drop persuit of this one solution. Time to see if you can directly wrap specific API functions in Lua itself and how to get LuaCOM to work right (same issue, so same solution, I think). That should leave overhead almost "entirely" in the script itself, plus one measly extra dll, not the engine. I assume you wouldn't object to making LuaCOM standard, *if* I could find a way to make it integrate? Wasn't that big, if I remember right.
It's very easy to wrap around C functions in Lua. What's harder is wrapping around data, and unfortunately to properly wrap C functions you often need to wrap the data as well.
Quote: And last I looked, I only see *two* people actively complaining here that I should just give up.
By that logic: I only see *one* person actively trying to make this happen. :-)
(BTW, your choice of the word "complaining" is pretty interesting...)
Time to see if you can directly wrap specific API functions in Lua itself and how to get LuaCOM to work right (same issue, so same solution, I think).
You can access any API function my writing a small DLL that is installed via Lua, as I have shown in various posts on this forum. Thus, the client can be made to do virtually anything.
What is hard, and what you are partly asking about as well, is catching operating system events, and getting them to somehow appear inside a script.
As for making LuaCOM standard, I supply on this site a DLL which is compiled for Lua 5.1 (http://www.gammon.com.au/files/mushclient/lua5.1_extras/luacom.zip), for anyone that needs to use COM. Although this file is small (only 90 Kb), I think an optional extra is all that is needed here, as I doubt lots of people have a need for COM.
I've really always wanted to stay away from COM. Unneeded really, and I don't like mucking around with it I think Shadowfyr has a decent idea down, but to actually think about implementing wxLua?? As Nick states, the installer for that alone is huge. Python already includes the Tk/TCL libraries in its download, and since I/anyone who has python and uses it, will already have Tk, its why Im choosing to use it for this project.
Quote:
I'm always amazed at the amount of things that you find can be added with just a complete reworking of how MUSHclient is written. It comes up in thread after thread... If you think it's so easy, just write your own client and be done with it.
Currently I am also doing just that.
Essentially, Its my version of a MUSHclient port for Linux. Xpertmud, Kmuddy, a few other Linux clients out there are pretty decent, however in terms of speed, scripting uses and user friendliness they are entirely lacking.
So in creating this client (as in the very very early stages of it), I am writing my own client in Python, to function much as MUSHclient does, but for Linux.
IE:
Speed
User friendly, without being too buttonish/newbiefied
Memory managment
Scripting choices(Python, Perl, Ruby)
Other features and neccesities(Fast triggers, Reqexp, Ect)
So, feel free to continue telling people to write thier own clients, Thanks!
Well two points. 1) making a DLL to wrapper the API calls is basically doing nothing *except* replacing wx with your own API dll, not a huge improvement. lol 2) The only practical approach to using objects, instead of being stuck with the existing GUI elements or coding non-editable, compiled extensions, which still can't do events (it damn silly that we have to reinvent the wheel by having OnCallPlugin do what the event manager is supposed to be doing imho), is COM. Why? Because presumably LuaCOM includes connection point handling, which handles those same sorts of events.
Now, here is the real silly bit with the argument. Has anyone tried connecting events to event sinks when using LuaCOM yet? Because one would assume its got the "same" problem as Python and the rest because of it. If not, then... Damn, I wish I understood this stuff better.
Please read this if you think that Luacom is just Nick's API: http://www.gammon.com.au/forum/?id=6022
It's a luaforge project to add all COM functions into lua, which in effect can do pretty much anything with Windows that you want... just in a very messy Microsoft fashion.
As for using objects, the event have nothing to do with object oriented programming, since events are objects themselves, they cannot possibly be the core of the design. The main benefits are inheritance and polymorphism, which is covered in any computer science 101 class in existance. This makes things like the aliases and triggers not have to be written completely differently, or passed differently when called. The many scripting language interfaces are probably each inheriting from one class, letting them be called identically within the program.
And for the OnCallPlugin part... I'm very confused what exactly you're saying there. How is the event manager supposed to do anything different? You still have to code what events do, and how the class reacts. Calling plugins really shouldn't even be possible, since the whole point of a plugin is that it is something that can be completely removed from the rest of the world you have.
Sigh.. Look. When you create and object, like a button, they have an *event* generator in them. In the case of a Button, this is usually "Click". So, when you create and object like that you usually do this:
mybutton = object_Handler.create("Button")
'Silly I know, but you have to put it on something. And this is an example only.
mybutton.parent = world.GetFrame
mybutton.name="Fred"
object_handler.connect("Fred_Click", "OnClick")
This is so that when you click the button it automatically calls "OnClick" in your program/script. Events are **not** objects. Objects are descreat chuncks of code that actually execute something. Events are simply data dumped into the system messaging archetecture using "FireEvent". Some place in "Botton" is a bit of code that says something like:
FireEvent(self.name + "_Click");
The event handler, I presume, keeps a table lookup that says, "The event Fred_Click should trigger a call to the address of "OnClick", which happens to be 'blah'."
I don't know where you get the idea that events are objects... But, point here is that the event handler architecture in most applications will start at the farthest "child" of the application, let it attempt to handle the event, then if that doesn't, it gets passed to the next highest level in the application. I.e. if a world window doesn't handle an event, then the main window is handed the event instead. MFC does things **way** differently. It handles "all events" in the main window code. this means every button, every scroll bar, every what ever, all gets passed "only" to the main window. No children ever see it, unless you use MFC's "message reflection" trick to explicitly redirect those messages to another object in the hierarchy, to give it a shot at dealing with the event first.
Now, most script engines don't have their own handler at all, or it relies on its "host" to do so. VBScript for example lets you return a reference to the script function, but requires that you pass that reference to a "connection point" handler in the hosting application. Fine if using IE, since IE also supplies the means to create the objects *and* it supplies the needed connection point system. You still can't use "createobject" to make something, then expect events to work with it, because IE doesn't have the reference data for the object to correctly inform its event generator who to "inform" about the event.
What is bloody confusing though is that connection points seem to imply that they directly call the code, since you are passing a reference to the specific address of the function to them. This may only be in the case of ActiveX though. Non-ActiveX may be forced to use the messaging system, which then means that inside an MFC application its not clear if LuaCOM or anything else will ever *see* the events, sicne they are children of an MFC application, which "shouldn't" pass any of that on to the script engine.
Its confusing as hell.
Now, the issue of using OnCallPlugin is simple. If events can't be handled in the *existing* system, then you need some way to capture and redirect them *external* to that system. What this means is creating all your GUI elements in an ActiveX EXE. This runs independently from Mushclient, but probably, for it to work right, also uses the Mushclient script bindings, like CallPlugin. Now, lets say this is a toolbar with 5 icons, which you click to cast spells, lets say "Light", "Heal", "Fireball", "Fear", "Heal: Fred". The last one heals a party member, so I can show why the code below "needs" to work the way it does. Each of these "could" simply be an event, which when clicked call the specific function needed. Without event management, you have to reinvent the wheel somehow to do this:
function OnCallPlugin (data)
if data contains "Light" then
call Cast_Light(right(data, len(data) - 10))
end if
if data contains "Heal" then
call Cast_Heal(right(data, len(data) - 10))
end if
...
end function
function Cast_Light(data)
send "cast light"
end function
function Cast_Heal(data)
if data <> "" then
send "cast heal " & data
else
send "cast heal"
end if
end function
In other words, the only way to handle a GUI system "not" created in scripting itself, or even "in" that scripting, without event management is to reinvent event management using OnCallPlugin as the "manager". And this just gets absurd when dealing with some pre-existing, closed source, 3rd party application. Lets say one that has 2-3 actually functions, none of which return the "state" of any part of the application, and two dozen *events* which are supposed to automatically inform the application that links to it of what those internal states are... Am I really the only person that thinks that having to code a new EXE for "every" such case, just to translate all the interfaces and events of that application to Mushclient function calls is a) rediculous and b) not something that probably more than 90% of the users of Mushclient are going to be able, never mind want, to do?
Its not about how many instances we "know about" right now where this is a problem or what work arounds exist for them. The issue is how many things are "no one" going to even bother trying to use with it, because the only way to do so is complicated, convoluted and completely redundant to what already existed to do the same thing.
Now.. I might be less frustrated if there was some "easy" way to make a generic EXE that was small, compact and worked by taking the lookup tables in an application/dll and building the correct internal lookups to make it work, including exposing all the same functions and data retrieval points. In other words you would tell "it" to connect the function name to the event and it would automatically translate the correct call to something the script could use... Its one idea I fiddled with, but it "still" requires, at the moment, using "OnCallPlugin" to handle the translated events. And it would be a pain in the ass to code in the first place.
There are many solutions. A lot of them are way more trouble and would waste even more time to get working right than just figuring out why events can't work in the present context and what needs to be done to fix it. The easiest, if we knew how, would be to fix it in the client. Everything else is bending the client, the component you are trying to host *and* the OS into a pretzel to accomidate the problem. And I don't mind doing that **if** its really necessary. I still don't think it actually is *yet*.
Quote: I don't know where you get the idea that events are objects...
Because Shaun is talking about objects in general and you seem to think that "object" is a very particular notion reserved to GUI programming with Windows event handlers.
Wow... the fact that the object/event thing was unclear was unexpected. For a quick explanation: http://en.wikipedia.org/wiki/Object_oriented_programming and please note that the language that MUSHclient is written in is C++, an object oriented language.
As for the example given of light and heal, I have two questions. 1) Why aren't you just calling the functions themselves instead of some function that splits it up? 2) Why don't you just use Lua?
With Lua, you can make a table of functions to be called at whatever point is needed.
function printlight( blah )
send( "cast light" )
end
function printheal( blah )
if blah == "" then
send( "cast heal" )
else
send( "cast heal "..blah )
end
end
functiontable = { light = printlight,
heal = printheal}
function OnPluginCall( data )
command = data:sub( 1, 10 )
restofdata = data:sub( 11 )
functiontable[command](restofdata)
end
All of that is assuming that the first 10 characters is your command portion, and the rest is for arguments, since from the first post, that's the only conclusion that I could draw. Otherwise if you're trying to heal a character by the name of Sunlight, things would get messy.
I'm also completely lost on why you would test for a nil value being passed to the heal function. Any reasonable mud will strip that last space out as routine, and you're just wasting a comparison on it.
Shadowfyr, what you want to do can probably be done --- somehow.
However what we are wrestling with here is quite a few unknowns, where behaviour is buried in the bowels of places that are hard to examine, if you will parden the metaphor.
You want to install some sort of control using the ActiveX mechanism, whose internal workings I am not sure about, and have operating system events (like a mouse click) be passed by Windows, via MFC (which also is large and complex) and eventually reach your script, which itself is running under Lua. However the moment that the button is clicked Lua won't be running (probably).
The scenario would have to be something like this:
The mouse click generates an operating system event.
The MFC main loop detects that and doesn't immediately discard it (which may well happen as the window in question is not in its internal list).
It generates an event in my client code - and I somehow identify which plugin/script it belongs to.
I start the Lua interpreter up, and call your routine that you have previously registered --- again, somehow.
Then if your script decides to not handle the event, but let the operating system take the "default behaviour" somehow this has to be unwound, so we get the OS to do its default thing.
If I were a major MFC expert (rather than a user of it), and an ActiveX expert, maybe I could make all this work.
However to be honest, if I was going to spend that much time -- and this sort of thing tends to be open ended, in other words it might be 100+ hours -- then I might consider whether the bulk of the MUSHclient users would prefer the time to be spent, say, neatening up the configuration windows.
Yep. Events are just messages. While they might, in some strange cases, *contain* a reference to an object (I.e. memory address), they do not themselves constitute an "object". Broadening the term to mean something like, "Discreat chuncks of code or data.", which would be what was implied by calling events such, pretty much makes the term meaningless, since it would describe "everything" from an boolean value to an application.
As to the function table thing.. Sure, if I knew Lua that well I would do it that way. I have barely done anything with it though, so complaining that I am doing it the hard way... And no, my examples just *happened* to be 10 characters, One could presume that they wouldn't always be that. After all, its the *user* that is going to be defining what they call each button, and they could just as easilly call "heal", "My bitching HP restorer!". The only certainty is that the code for the event would take the name of the control and tack it on to the start of the data being sent. The presumption being that other stuff might be included, such as the "name" of the person it targets, so that could be sent as well. Though that might be stored client side in the plugin instead, rather than as part of the control. I mean, the point isn't to create a single instance of something like a toolbar, but a generic system with which a toolbar is *one* option. The example though presume that someone has predesigned a toolbar and that the icons on it can hold the "target", not just their own name. The code would therefor have to look for the location of the ":" that seperates the name from the data, not just the first 10 characters. Sorry I didn't make the example generic enough to be clear about that.
Oh, and more to the point, while Lua contains such lookups, its not a guarrentee that such a "generic" solution for using new and pre-existing components "will" be used in only the Lua language. This means that "my" version would be right for "most" of the languages avialable, just sloppy for Lua.
---
Now, as to your comments Nick. This is why I am doing the leg work. I know that no one here has a clear understanding of how it all fits together, so I am trying to figure it out, so that some solution that will work becomes possible. That may be the easy way (figuring out how it can work with MFC) or the hard way (designing some generic solution using an EXE that can funnel the stuff through the back door). I would prefer the easy way, since the hard way still involves solving a number of issues, which may actually be the *same* issues that would need to be solved to do it in the client. I just don't know at the moment, but I am beginning to strongly suspect that this is the case, say an 80% chance. And to make matters worse, I am not even sure if events from ActiveX *work* the same way as non-Ole events. There is some implication that they bypass the event management completely and directly call the entry point for the function they are given, which would create a completely different can of worms. And, as you point out, its a major unknown what happens then. Its either 1) the enegine remains asleep and everything goes down in flames, 2) they thought of that and the engine will wake up to handle the event, then go to sleep again, or 3) it will do 2, except that it won't sleep again and the client will lock up.
We just don't know, and finding people that *know* the languages involved, instead of merely *using* them is like trying to find an expert on Gene Replication at a Creationist convention...
Quote: We just don't know, and finding people that *know* the languages involved, instead of merely *using* them is like trying to find an expert on Gene Replication at a Creationist convention...
What an odd analogy... :-)
What languages are you talking about? How can one use a programming language without knowing it? Or were you referring to using a library versus understanding its internals and implementation?
Quote: Yep. Events are just messages. While they might, in some strange cases, *contain* a reference to an object (I.e. memory address), they do not themselves constitute an "object". Broadening the term to mean something like, "Discreat chuncks of code or data.", which would be what was implied by calling events such, pretty much makes the term meaningless, since it would describe "everything" from an boolean value to an application.
I'm so glad that you wrote the last line of that part, since that is exactly the definition of an object. The number 3 is an object in true OOP languages, as is the + operator, as is the whole program. A class is a set of data, the means to access that data, and a way to transform that data. An object is an instance of that class. I'm sorry if the actual definition of the term does not match whatever is in your head. You were speaking of message passing, which is a way to get another object to start up a function. If you bothered to look at the link I posted, you would see that I was showing you the information I had, and a way to back it up from an outside source.
Quote: And no, my examples just *happened* to be 10 characters
Well, I was attempting to match your example. I seem to have done so well enough that you've started arguing against the logic of what was done there. Congratulations, you're now arguing with yourself after this point.
Quote: As to the function table thing.. Sure, if I knew Lua that well I would do it that way. I have barely done anything with it though, so complaining that I am doing it the hard way.
And yet your solution was to implement wxLua into MUSHclient, talking about how easy and wonderful it would be. Interesting point of view considering you don't know the language you are talking about, by your own admission.
Quote: Now, as to your comments Nick. This is why I am doing the leg work. I know that no one here has a clear understanding of how it all fits together, so I am trying to figure it out, so that some solution that will work becomes possible.
Nice to know you think Nick has no clear understanding of how MUSHclient works. I'll forward any and all questions over to you from now on. I'd suggest taking the time, as Nick has, and learning each of the scripting languages that are used in MUSHclient. While you're at it, learn C++, and software design. After you are finished with that, you might be in a better position to make various claims about what people know and don't know.
I really hope that you realize that all you are doing is proving more and more with each post that you have no idea what is involved in programming large applications. You have shown no understanding of basic programming terms in several threads, you have completely missed the fact that even a one or two line change in code can result in several kilobytes worth (or more) in the executable, and you constantly suggest things as quick, simple fixes, when they would take hundreds of hours to do.
Essentially, Its my version of a MUSHclient port for Linux. Xpertmud, Kmuddy, a few other Linux clients out there are pretty decent, however in terms of speed, scripting uses and user friendliness they are entirely lacking.
So in creating this client (as in the very very early stages of it), I am writing my own client in Python, to function much as MUSHclient does, but for Linux.
Excellent! I hope you enjoy doing this. It is certainly a challenging job writing a client, and with luck you will learn from the mistakes that previous client writers (such as me) have made, and make yours easy to use, and reliable.
If I was starting from scratch I would certainly do things differently, but I don't really have the energy to start from scratch now. :)
I notice that Zugg, the writer of ZMud, has decided to write a new client (CMud) rather than keep evolving ZMud, which shows that he too finds it hard to keep improving what has probably become a somewhat unwieldy piece of code (no criticism intended here).
Clients like MUSHclient tend to evolve over time, and become a bit unwieldy because you decide on better ways of doing things, but want to have backwards compatibility for people who are used to the old way. Hence there is a fair bit of duplication in MUSHclient (eg. macros / accelerators).
If you can nail down a design from the start, and stick with it, you will probably have a nice, clean client.
Personally I would use Lua from scratch if I made a new client, including doing things like reading in all the configuration stuff (eg. triggers, aliases, world address etc.). Lua is ideal for this, and indeed was initially designed with this purpose in mind.
Just as an aside, some people are finding that MUSHclient, run under Wine, provides quite a decent Linux client.
You would make one very happy camper if you had an option to not attempt to maximize the window at startup. Every time I start it, it remembers the position, but tries to resize the window to the full width, which means that I have to resize it back down to one screen's worth.
Bloody hell.. Are you people intentionally misreading everything I say?
Yes David, I mean the internal implimentation of the code. How the event sink system, Ole and other components work on a deap level, which would allow you to circumvent some of the silly limitations of stuff like MFC that basically say, "Ah now. Don'tcha worry about the details. I'll handle that." And by the same token, I am quite sure Nick knows how Mushclient itself works, he admits to *not* knowing enough beyond MFC to know how or even *if* some solution would be complicated or easy. And neither, from what I can tell, do any of you. I have been digging through what little of the bowels of this stuff as I could easilly track down and still am confused about stuff. As far as I can tell, most of you haven't read anything at all about it. Frankly, every once in a while something like this will come up where people just, "Take the easy way out.", and code what they can, instead of what is possible. Why? Because the documentation on how to do it right is scattered, confusing and archaic, with very few concrete examples, while there are 10,000 examples of simply ignoring the problem and living with the consequences of not understanding what is really going on under the hood. Once people had to know this. MS, in each new version of their compilers, have shoved the archetecture of the whole thing farther and farther beneath the surface, making it less and less likely that the next book on the shelf is going to be titled, "How to solve problems with X, by not doing things MS' way." Heck, the .NET system won't even let you create ActiveX controls any more, because they figured .NET was so much better, never mind that that buries stuff that ActiveX could do under yet another layer of crap.
The irony here is, had I asked some of these questions 10 years ago, I might have gotten answers, only 10 years ago their wouldn't have been a lot of script engines to have a problem with. Its damn frustrating.
And, the joke about Gene Replication at a Creationist convention is that they are more than happy to completely misunderstand the science on the basis of what they **think** is true, while failing to understand anything about the science that produced the book. And, just to be clear, I am describing how a lot of forums on the various subjects work, not here. People here tend to be more innovative, possibly because there are obvious limitations in the system. Pretty much universally, everyplace else, if you want to ask a question about how something works outside the context and assumptions of those who follow the standard chart on how to impliment it, you're SOL. No one knows, because everyone else started with, "Oh wow!", then jumped straight into doing it *exactly* the same way all of the sample files show it being used. In the case of a lot of script engines, that means one of three things, a) if you are using GUI, code the entire application in the script language, b) if you can't do that, run it in IE or some pre-existing environment that has already "solved" the insurmountable problems that none of the examples show "any" solution to or c) don't use *any* GUI elements from in the script.
Not exactly conducive to novel innovations, never mind a better understanding of the OS or libraries involved. Its like trying to make a show like American Chopper and having everyone tell you, "You can't do that, because it would be just way to complicated to make new parts so the bikes look different. Or wait... you mean you're just going to paint them right?" The only solution, in the case of code, is to ignore the detractors, then spend $200 on books, some of which haven't been published in 5 years, like the ATL book, just so you can try to get some sense of how the fracking heck it all works. I should have bought the Ole book instead. The ATL one was helpful, but missing huge chunks of the basics. :( Maybe next month, when I have money to throw at it again. Hopefully it also would explain how ActiveX and normal system events differ, if they truly do.
I'm sure Nick would be happy to put a link up of your finished program once you write it out. Until then, please don't bag on him or David...they DO know what they are doing and talking about. Just because you can't get something to work that only YOU think is necessary doesn't mean Nick should change the whole way that his program works.
Again, I'm sure Nick would be happy to put a link up of YOUR finished program once YOU're done writing it.
Quote: Bloody hell.. Are you people intentionally misreading everything I say?
Well, Shadowfyr... you have a tendency of using terms in non-standard ways. This is confusing to people. For instance the whole thread about dynamic linking was due to an initial misunderstanding based on the fact that what you think static vs. dynamic "should" mean is not what the accepted definition is. Here you first spoke of languages, but what you really meant was libraries.
Maybe you write "quicker than you think", as the saying goes, or maybe your thoughts aren't perfectly clear to begin with because you are still learning all of this, but whatever the reason, I (and I believe other people as well judging from other posts) find your posts rather confusing to read.
My personal belief is that it is hard to have precision in thought without having precision in language. If you (general you) can't articulate something clearly (and better yet, concisely) then chances are that you haven't fully understood it.
As for your other points:
I've said it several times in the past and I'll say it again. I really, really think it would help if you actually wrote some code of your own, even for something very simple. You are trying to understand very, very complicated concepts without even knowing how to write a simple program using the tools in question. It's not surprising that you are having trouble and end up feeling frustrated. I think it would also give you respect for the subtlety and complexity that these problems sometimes have.
You have a tendency to speak with scorn and contempt of people who prefer so-called "easy" solutions, but I think you would develop some degree of sympathy if you actually wore their shoes for a moment.
So please, try to learn the basics of this before jumping so far ahead into the bowels of the internals of the guts of the operating system. Slow down and you will benefit.
There is a saying in Latin: "Festina Lente" -- hurry yourself slowly.
The point is that if you work diligently and quickly but starting from the beginning, you will make much more progress than if you try to rush about without deeply understanding what you are doing.
Thanks for the advice. I know quite a few languages though, so not knowing the specifics of any given language doesn't mean I don't have a decent picture in my mind of what it *should* do to impliment the idea, even if the specifics are a little more vague. I am one of those people that, when completely familiar with the syntax, can code a thousand line program in a few hours, then spend less than half that debugging it. I rarely have to "plan out" the design of anything. I admit that this may be biasing my thinking a bit, since what *seems* obvious to me in the big picture can look really complicated to someone else.
Languages that I don't know well, get me a tad more frustrated, especially when they are ones like C++, where if you are not using something like MFC, require you spend a lot more time telling the system how to do things, than telling it what you want it to do. It doesn't help at all that right now I have the choice between something like GCC, which has, at best, a command line debugger (yuck!) and no sort of GUI based code editor with helpers in it to get around having to code it all the hard way, or... basically nothing. The only C++ I have is so old I am not sure it even supports MFC4.0, never mind anything newer, so testing some solutions are out. GCC doesn't even include MFC. Buying a copy... it so far outside my budget that I might as well try selling a kidney to pay for it. Its not like I am in a position to *write* any of the code needed to test my ideas. At worst, you can justifiably accuse me of jumping the gun and pointing out possible solutions, *before* I have a clear enough picture to show anyone else how the pieces are supposed to fit together. I am sorry about that. Next time I will try to make sure that the puzzle box is directly visible and the pieces are "picture side up". lol
Oh, and you're probably right about writing quicker than I think. I used to stutter and I do tend to still do so in text occationally. Its cause in my case is simply that my brain is reprocessing what I am writing even before I have finished writing it. So, its actually a misnomer. The problem isn't that I don't think fast enough, its that I think too fast and can literally change perspective in mid sentence, at times I am trying to get something complicated out. Been more than a few times I have gone back to read something, only to realize that I have literally produced two halves of two completely different sentences as one written sentence... Kind of problematic when trying to parse the result. lol
However, you are still admonishing me about the subtlety and complexity of something that *if* you understood it either you would have the answers I need. This is like arguing the subtlety and complexity of crystal formation, when maybe the art of producing them is little more than adding food coloring to some high saturated sugar water and dropping a sugar cube on a string into it. That it "looks" subtle and complex may be a given. But neither of us is in a position to say that it really is, unless we understand the mechanics of how to produce it. Once you do, at least in the case of colored sugar crystal candies, its certainly subtle, but hardly complex. At best, you can admonish me for not knowing if it is or not, not that it "is" and I don't appreciate that fact. I have already found that my assumptions about the complexity of "some" aspects of the way this all works have been blown out of proportion by my own lack of understanding. Can we at least agree that your's may be as well and that just maybe this isn't as complex as you insist? Seriously, ignorance is not an insult, its just a statement of fact. Admitting to it means you can progress in understanding, rather than just making snide remarks about how the other guy that is progressing, how ever slowly, is on a wild goose chase.
Believe me, if I had the means to code a simple MFC app and then try to figure out what was going on, I wouldn't be dropping suggestions about possible avenues to a solution here instead, in the obviously vain hope someone else cares enough to take an interest. And by interest I mean more than some other threads commentor who stated, "If you can ever get this to work, it will be great." I am trying to build an glider using sticks and tree bark here and your complaining that I am not Galileo, who also had better materials to work with anyway. Well, I am Antonio Salieri in this case, sadly, there seems to be a lack of Mozarts around. lol
... right now I have the choice between something like GCC, which has, at best, a command line debugger (yuck!) and no sort of GUI based code editor with helpers in it to get around having to code it all the hard way ...
It isn't that bad. Assuming you are using Windows, and have installed Cygwin, you can edit with any Windows text editor. I am very happy with Crimson Editor, which is free, fast, and has syntax colouring.
You can edit with Crimson Editor, and even configure it to make a hotkey do the compile step. So, once you are ready to test you hit F5 (or whatever), and it does:
gcc test.c -o test
You can capture the output of the compile in Crimson Editor "output" window, to read your error messages, and apply changes.
Microsoft have also released "Visual Studio Lite" or whatever it is called exactly, which is a free download of Visual Studio, including C++, VB, and so on.
It was available last year, not sure if it still is. I suspect it is designed to tackle the "I want free software" market, which the GNU tools are catering to quite well.
If you like the integrated environment, it could be worth trying that.
You obviously know assembler, Shadowfyr, it could be worth trying a few C examples, and testing out some of your ideas.
Quote: I am one of those people that, when completely familiar with the syntax, can code a thousand line program in a few hours, then spend less than half that debugging it. I rarely have to "plan out" the design of anything.
Well, there's the problem then. If you don't plan out things, you will never be able to deal with large projects. I do the same with most small scripts and programs, but for anything reasonably large, you NEED to start planning ahead. If you insist that you can just "see the design in my head" then you will get lost, as you have here.
Quote: I admit that this may be biasing my thinking a bit, since what *seems* obvious to me in the big picture can look really complicated to someone else.
Interesting thing to say right after saying that you don't bother planning things out. Ignoring the possiblity that people aren't seing the "big picture" when saying that they are the ones who sit and plan things out just dosen't make any sense.
Quote: The problem isn't that I don't think fast enough, its that I think too fast and can literally change perspective in mid sentence, at times I am trying to get something complicated out. Been more than a few times I have gone back to read something, only to realize that I have literally produced two halves of two completely different sentences as one written sentence... Kind of problematic when trying to parse the result. lol
And of course, you can't possibly write out your notes in notepad, and then just copy them over after you've gone over them a few times. Or you could do what I do, and post a small note, then go back with the lovely edit option that the forums provides for you.
Quote: The problem isn't that I don't think fast enough, its that I think too fast and can literally change perspective in mid sentence, at times I am trying to get something complicated out.
Ah yes, this does wonders for proving that you can just bang out a program in a matter of hours and only need a small debugging phase. I have a similar problem. It results in me needing to plan out quite a bit more than I believe I need to, and then double check everything I've written to make sure I haven't made any little mistakes. Then, after all that, I can start debugging, which should take forever with any decent program. There are still bug fixes going on with MUSHclient, and it's been the most stable thing on my computer since I've started using it. I think I've had notepad crash (stupid poor overflow handling) more than MC.
Quote: However, you are still admonishing me about the subtlety and complexity of something that *if* you understood it either you would have the answers I need.
No one has mentioned this at all. In fact, what people have been saying is that if you understood certain things better, then YOU would have the answers you needed. Which is why a few of us have suggested that you write a sample of what you are trying to do. It would make things clearer, and you would learn more about the topic than you would by saying "So this guy over here said that this is possible." Not only that, but you would have something to point to showing that what you are saying can be done is possible, which is hard to argue with.
Quote: This is like arguing the subtlety and complexity of crystal formation, when maybe the art of producing them is little more than adding food coloring to some high saturated sugar water and dropping a sugar cube on a string into it. That it "looks" subtle and complex may be a given. But neither of us is in a position to say that it really is, unless we understand the mechanics of how to produce it. Once you do, at least in the case of colored sugar crystal candies, its certainly subtle, but hardly complex.
Very good analogy, but I would take it a step further. The crystals are simple, true. But try and get them to grow in a very specific pattern, like an actual cube. Basic elements thrown together can have unpredicted complications when pulled to a larger goal.
Quote: Seriously, ignorance is not an insult, its just a statement of fact. Admitting to it means you can progress in understanding, rather than just making snide remarks about how the other guy that is progressing, how ever slowly, is on a wild goose chase.
Very good... now please admit it and move on. I honestly haven't seen anyone here deny ignorance as much as you have. Even when faced with proof, such as the whole events are objects thing, you have completely skipped over the proof, going on later to try and assert your incorrect definition in later posts.
Quote: Well, I am Antonio Salieri in this case, sadly, there seems to be a lack of Mozarts around. lol
<sarcasm>Umm... you want to teach our children and have theories surronding your involvement in our deaths?</sarcasm> Here's an suggestion. Stop making analogies. They can be easily and unintentionally misinterpreted to the end of days. Just say what you mean and be done with it instead of attempting to add more fuel to the fire.
Quote: I know quite a few languages though, so not knowing the specifics of any given language doesn't mean I don't have a decent picture in my mind of what it *should* do to impliment the idea, even if the specifics are a little more vague.
I think you are confusing two different things. There is knowing a programming language, and then understanding a library. I know C++ well, I daresay perhaps very well, but I have no idea how to write 3d applications using DirectX. Well, actually, I do have some idea, because I'm familiar with OpenGL and know the general principles of 3d, but whatever -- the point is that familiarity in a language won't give you familiarity in sets.
Here's a better example: despite knowing C/C++ well, I would have to learn from almost scratch if I wanted to write GUI applications for Gnome using GTK.
Basically there is a difference between the language you write in and the tool set, libraries, etc. that you use.
Quote: I am one of those people that, when completely familiar with the syntax, can code a thousand line program in a few hours, then spend less than half that debugging it. I rarely have to "plan out" the design of anything. I admit that this may be biasing my thinking a bit, since what *seems* obvious to me in the big picture can look really complicated to someone else.
Not to diminish your claim, but a thousand line program is still relatively small. I regularly write 200-1000 line programs to help me solve homework, or even for homework.
But try writing a 45,000 line program. Or, even a 15,000 line program. It's a completely different beast. Not having a design is a sure recipe for disaster.
Also, sometimes a clear big picture isn't worth very much. The big picture of virtual memory management or disk caching in an operating system really isn't that hard. But the actual implementation is extraordinarily complex.
Give it a shot and see what you think:
http://www.stanford.edu/class/cs140/ Operating Systems
Quote: Languages that I don't know well, get me a tad more frustrated, especially when they are ones like C++, where if you are not using something like MFC, require you spend a lot more time telling the system how to do things, than telling it what you want it to do.
I'm not sure what you mean by this. I'm guessing you mean having to deal with things like memory allocation and deallocation, and having to work in a fairly rigid syntax. But I agree with the general sentiment that some languages incur a greater start-up cost than others depending on what you are doing.
That is why it is important to understand your toolbox. For small, quick programs I use Perl or Lua. When it gets larger, I either structure the Perl/Lua more (using a module-based system, for example, or object orientation) or move to C++ or Java.
Quote: It doesn't help at all that right now I have the choice between something like GCC, which has, at best, a command line debugger (yuck!) and no sort of GUI based code editor with helpers
I know what you mean but your comparison is a little unfair. GCC is just a compiler; it doesn't purport to be any of the above. It's one piece of a tool chain.
gdb is a debugger, and if you really want a GUI environment on top, you can use e.g. ddd, a graphical front-end for gdb. For the GUI, you should think about what features you need specifically. The two things I use a lot are:
- intelligent auto-completion (OmniCppComplete plugin for vim7)
- jumping to a specific function, method or class (vim tag system, using exuberant ctags)
Since those are my main needs, I have found ways to meet them that work very well, arguably better than Visual Studio. Of course, it doesn't hurt that I have been slowly learning vim for years now, and have been working in this whole tool chain for years as well. When I started it was rather daunting.
Quote: The problem isn't that I don't think fast enough, its that I think too fast and can literally change perspective in mid sentence, at times I am trying to get something complicated out.
Oh, that's what I meant. I didn't mean to say you don't think fast. :-) I've run into a number of people (myself included, in the past and sometimes now) who write too quickly and don't stop to collect their thoughts. I (usually) make an effort to think through what I'm going to say before I say it, in the hopes that the result will be more coherent and more precise.
Quote: However, you are still admonishing me about the subtlety and complexity of something that *if* you understood it either you would have the answers I need.
My main complaint is that you appear to be saying it is simple when you don't know the answer yourself. I'm not sure how you can say it's easy when you don't know how to do it. :-) Of course I don't know how to do it either, and for that matter I haven't really looked into it, but on the other hand, I have written a fair amount of code in my time including some that deals with Windows event loops. (Admittedly I have not written an MFC program, and only know the basics of how it works, that much is true.)
Quote: That it "looks" subtle and complex may be a given. But neither of us is in a position to say that it really is, unless we understand the mechanics of how to produce it.
Yes, but as I said above the converse applies too, and that is what I am trying to point out. Neither of us have the process in hand, so arguing that it's easy just because you want it to be easy doesn't really hold much sway. (It would be nice, of course, if it were easy...)
Quote: Can we at least agree that your's may be as well and that just maybe this isn't as complex as you insist? Seriously, ignorance is not an insult, its just a statement of fact. Admitting to it means you can progress in understanding, rather than just making snide remarks about how the other guy that is progressing, how ever slowly, is on a wild goose chase.
The thing is that, to my knowledge, I have made rather few claims in this argument. I freely admit that I don't have the definitive answer to this problem, however, my experience due to many years of programming gives me the definite hunch that it isn't nearly as easy as you think. That is the claim I want to make. I'm not saying you are on a wild goose chase; what I say to that effect is that I think you should learn the basics before trying to work on a large system of many components with complex interactions.
I would be delighted to find out that this is, in fact, a very simple thing to do, and simply a matter of tweaking a line or two of code. Trust me, I think it would be really neat too to have custom GUI control via wxLua. Not neat enough to warrant me spending the time to research it, admittedly, but still pretty neat. It's just that given all the parameters and unknowns I think the solution will take a rather long time to find, much less implement, and what I resent is your insistence that it isn't hard. I think what you really mean is "shouldn't", not "isn't", but unfortunately these complex systems don't always work according to what "should" be the case based on what we desire...
Quote: Microsoft have also released "Visual Studio Lite" or whatever it is called exactly, which is a free download of Visual Studio, including C++, VB, and so on.
Yes, they call it the Express version. See:
http://msdn.microsoft.com/vstudio/express/
Personally, I prefer to use vim with exuberant ctags, a few plugins, and a well-configured .vimrc file. But that's just me. :-)
Hmm. Problem with the "Lite" versions is they often hamstring you with limitations, like *not* giving you MFC at all, or letting you run "test" applications in debug mode, but not compile them to anything that is stand alone. I personally hate the latest batch of "learning edition" ones they put out do to that. Second is, since they don't include the GUI or any of the links needed to use Visual Studio if you already own it, your stuck with a learning curve that looks more like the side of Mount Everest than a comparatively simple cliff face. lol
Did download the one from Borland for kicks, but then never did anything with it. And, most of the latest "MS" version, after 6.0, are tied into the damn .NET stuff, which kind of defeats the purpose of finding a solution for a client that is meant to run on the widest variety of systems possible, including ones that **can't** run a version of .NET.
Now, as to my understanding. I have read the ATL book, a bunch of stuff on OLE, though I admit not what I was looking for, dug through various thread on places about the subject of events, etc. I probably know more than anyone here about how it fits together, despite having missing pieces. Those pieces look, at the moment, more like the 1-2 that inevitably get stuck on someone's shirt or land upside down on the floor of the kitchen, not the gapping hole that you get when you have all the edges, but nothing else has been placed yet. My personal opinion is that, while its probably not going to be a mere one or two lines, its also not going to be like 200 either.
Most of the issues I see arise not do to the complexity of the solution, but the complexity of the hoops some clown put in the way of getting it to work. For example, implimenting a call to the invoke method of an ActiveX control, to tell it to connect an event to a sink "should be" one line. In any language that directly supports the implimentation is it. In raw C++, with no libraries helping you out, you have to do like a dozen other things, from making calls to the system metrics to get ...something... before the OS will "let" you call it. Why? Because you *might* make a call to invoke that is effected by those things, even if what you are trying to call has jack to do with any of them. I gave up on that approach after trying to trace the mess for doing it through the .h and other files in my ancient version of C++ that I do have. Haven't been so annoyed by the convoluted gibberish in someone else's library implimentation since I tried to figure out how the heck command parsing worked on an Apple IIgs, where the code was about 10 machine instructions that are identical to the older Apple I, II, II+, IIe and IIc, except where it made a long jump to some upper memory location where the new IIgs bios was, and proceeding to mangle things beyond all recognition. Near as I could tell, and I know I missed something, the "code" in that location always returned an invalid value, which should have stopped the parser from working at all...
The coders where either way smarter than me, completely insane, or both. lol I felt the same way trying to figure out how invoke calls worked according the the library descriptions for what ever it was I was looking at in the C++ mess. And, since then, I read stuff that implies that about 90% of it is completely unnecessary if all you are doing is telling the object to link an event. Its all there "in case" you need to do one of like 50 other things.
This is one reason why I am sure its simpler than it looks. Yeah, there are bound to be a dozen "complicated" solutions, but in nearly every case those are complicated because they are doing *more* than what I am trying to solve in the first place. Its like trying to fix a tire and having someone insist you read the *entire* repair manual starting with page one, before they let you see page 50, which tells you how to change the tires (which happens to be an after thought in the section about replacing the entire transmission).
Its about finding the "best" solution, not just any solution, and there are lots of *bad* ones that are way more complicated than strictly necessary. Most are "bad" in this case because they assume you are starting from pure scratch and you can't even create the object, much less look at its attributes or call its exposed functions, and calling its "hidden" functions is part of getting to that point, with, much like changing the tires, the use of events being either ignored entirely, or tacked on as an after thought. And that is with ActiveX, which is presumably a well known system. For standard system events.... I haven't yet even tracked down anything that says conclusively *if* ActiveX and standard events even relate to each other, since the former is designed to circumvent a lot of the limitations of the prior structures, due the them being "too" rigid in the first place. Its not just possible, but maybe even likely, that the solution for ActiveX is *nothing* like the solution needed for something like the wx libraries. What I have learned seems to imply this as a real possibility.
Anyway.. Got to dig out some cash and buy the OLE book I guess. There is also a so called "standard edition" of Visual Studio, which if I get the C++ version is cheaper (asseming 6.0 had such a version). Or.. Maybe I can find some relative in college who can get it through a school discount. My previous source... Lets just say, without disparaging any beliefs she thinks she holds, that I have more ethics than she does and thus won't intentionally use even the most selfish fool to serve *my own* selfish desires, unlike someone else I might name...
Quote: Problem with the "Lite" versions is they often hamstring you with limitations, like *not* giving you MFC at all, or letting you run "test" applications in debug mode, but not compile them to anything that is stand alone. I personally hate the latest batch of "learning edition" ones they put out do to that.
Well, there is the problem that MFC is now something of an deprecated technology; Microsoft seems to have moved on to likes like ATL, WTL and most recently C#. It's quite likely that they are pushing people to follow that trend. Frankly it's probably for the best in the long run; my understanding is that they realized some things weren't quite right and tried to fix them with subsequent toolkits.
Despite that, MFC remains very strong, and has the advantage of having lots, LOTS more documentation than, say, ATL/WTL.
Quote: Second is, since they don't include the GUI or any of the links needed to use Visual Studio if you already own it, your stuck with a learning curve that looks more like the side of Mount Everest than a comparatively simple cliff face. lol
Did you even look at the Express version I linked to? It has the GUI you're looking for...
Quote: And, most of the latest "MS" version, after 6.0, are tied into the damn .NET stuff, which kind of defeats the purpose of finding a solution for a client that is meant to run on the widest variety of systems possible, including ones that **can't** run a version of .NET.
No, that isn't true. I have a copy of VS2003 or something like that (which is version 7, I think) and it definitely does not limit you to .NET.
Quote: Most of the issues I see arise not do to the complexity of the solution, but the complexity of the hoops some clown put in the way of getting it to work.
This is the kind of statement you make that grates against my ears. I think that it is very, very dangerous to make claims like this unless you have a really, really good idea how the internals work and understand why design decisions were made the way they were. Now that's not to say that there are no mistakes, but to say that it's just a bunch of "hoops some clown put in the way" seems to me to be a very narrow-minded point of view.
Quote: I gave up on that approach after trying to trace the mess for doing it through the .h and other files in my ancient version of C++ that I do have.
I don't really know what you mean by "ancient version of C++". I'm assuming you mean the Microsoft tool chain. C++ itself hasn't changed very much. It's the libraries Microsoft provides that have changed.
Quote: For standard system events.... I haven't yet even tracked down anything that says conclusively *if* ActiveX and standard events even relate to each other,
ActiveX is a platform built around the Windows way of doing things. So of course they relate in the sense that ActiveX is trying to extend the basic functionality of the operating system. But I think that trying to draw too strict of a comparison is not an appropriate task. My understanding, of course.
Quote: Or.. Maybe I can find some relative in college who can get it through a school discount. My previous source... Lets just say, without disparaging any beliefs she thinks she holds, that I have more ethics than she does and thus won't intentionally use even the most selfish fool to serve *my own* selfish desires, unlike someone else I might name...
Problem with the "Lite" versions is they often hamstring you with limitations, like *not* giving you MFC at all ...
It is true the Express version does not support MFC, however to an extent it seems to me that MFC is part of the problem we are discussing.
I sympathise with your frustation at getting information on how to get these things to work. For example, just when I was coming to grips with MFC, they started saying ATL was "better", but, of course, completely different.
If you were going to make a GUI client (and I think someone here is doing just that), then I would be looking at wxWidgets (formerly known as wxWindows until threats of legal action from Microsoft), which is something that is similar in concept to MFC, but cross-platform. And, of course, wxLua, which you talked about is related to wxWidgets.
Unfortunately, when I last looked, wxWidgets did not use STL, but its own internal structures for lists, maps etc. <sigh>
Sorry, had the distinct impression that MS was "pushing" people to .NET and intentionally leaving out specific toolsets as "depricated". It was seriously pissing off a least a few of the professionals that tried to make the switch. 2003 is still an "older" version though, so almost, sadly, as hard to find copies of as 6.0. What I meant by ancient copy of C++ was Visual C++, like version 3.0 or something...
As for the event models. Yeah, ActiveX on some levels is using the OS the same way, the problem is.. With events its a bit odd. What I have read seems to imply that its event model may not even go through the normal event system. I.e., its never going to be seen by MFC or any other part of the application, because instead of firing an event to the system, it instead does a direct call to the memory address where the entry point to the function for that event is. I may be wrong. Its possible it passes that address to the application and the application is supposed to call it or the ActiveX control manager in the application is keeping a table of those addresses and the ActiveX control is just... Well, it doesn't look like that is happening according to **anything** I have read on how those calls work. What is possible is that such controls are "both" doing a direct call *and* generating a system message, but if so, then it wouldn't be literally impossible to use late bound ActiveX in something like VB without a bridging dll. You can intercept event messages in VB, but **not** apparently those from the ActiveX controls, or bridging wouldn't be necessary. All a bridge really does is provide the system call that is locked out of VB, letting you "link" the event to the function that it needs to call when it happens. It has no manager itself, just a bypass to get around the inability to use the objects "Invoke" methods, which are needed for event handling.
So, as I said. Just because on some level ActiveX does do things like the rest of windows **doesn't** mean that it works 100% the same as direct API created objects. All the messaging and other things needed are probably instead handled by the OLE automation dlls, which are basically black boxes as far as your application is concerned. Event management may actually belong to OLE, not your own application in such cases. Which is *very* different than how standard controls are handled.
As for the lady I mentioned.. Lets just say she is sticking her nose into family business she doesn't have a right to, defending someone who is a lier simply because she can't believe that someone of the same "faith" lies, only shows up when "she" needs something from you and is generally the sort that insist they are "good" people, despite the fact that everyone else around them, unless they attend the same church, think of right wing apologists, not "good" people when you mention their names. That clear enough? ;)
In any case, I refuse to sink to her level and only show up at her place because *I* need to buy something only she can get for me.
Well Nick. I don't think there is "necessarilly" anything preventing some mixing and matching, though you might have to override some things and go to the deep code, not just a different library implimentation. But, since we are starting out on MFC here, trying to look for a way to fix it in something else... doesn't work too well. lol
As I said, I may have to go clear back to V6.0 to be sure to have a version that not using dependencies that are not obviously going to break stuff on 95, for example, and also include all the libraries acutally "in use" in this case.
Quote: Sorry, had the distinct impression that MS was "pushing" people to .NET and intentionally leaving out specific toolsets as "depricated".
And here we have M$'s battle plan for getting all your money. If you notice, nearly every company out there comes out with something that is the "latest and greatest" every few years to get people to switch. Micro$oft, which has a huge corner of the market, is generally in a better position to force people to make the switch by simply not making things backwards compatible. Also, some methods are just better than others. If you take a look at the history of Java, which has been open for use for quite a while, you will see hundreds of methods in the main classes which are depreciated to comply with better standards. Even looking through Lua's documentation, it has a decent amount depreciated, and it's a fairly new language as far as things go.
Quote: As for the lady I mentioned.. Lets just say she is sticking her nose into family business she doesn't have a right to, defending someone who is a lier simply because she can't believe that someone of the same "faith" lies, only shows up when "she" needs something from you and is generally the sort that insist they are "good" people, despite the fact that everyone else around them, unless they attend the same church, think of right wing apologists, not "good" people when you mention their names. That clear enough? ;)
What does this have to do with anything on this board? The moral issues of you and those you know are not really a good topic for here. There are plenty of boards out there that you can vent this off, or have a debate, or whatever will make you feel better.
Quote: As for the event models. Yeah, ActiveX on some levels is using the OS the same way, the problem is.. With events its a bit odd. What I have read seems to imply that its event model may not even go through the normal event system. I.e., its never going to be seen by MFC or any other part of the application, because instead of firing an event to the system, it instead does a direct call to the memory address where the entry point to the function for that event is. I may be wrong.
Well, what might be an issue here is that just because two programs have an "event model" doesn't mean that they're talking about the same event loop. I could write a program that handles Windows events (i.e. messages, like WM_CLOSE), while having my own event loop, such as the code that Nick posted some time ago using a C++ STL priority queue to manage a list of timed events.
Quote: Micro$oft, which has a huge corner of the market, is generally in a better position to force people to make the switch by simply not making things backwards compatible.
Actually I think that Microsoft is generally pretty good about keeping things backwards compatible, at least from the user's perspective. For instance Nick has been able to continue compiling MUSHclient in VC++ 6 and it has been working on very many versions of Windows and still does today, despite his IDE being now at least 5 years old.
When they remove backwards compatibility it tends to be more from the developer's perspective, in that they really, really want you to use the newer technologies and make it harder to use the older stuff in the more recent IDEs. Still, it's possible; after all it's just code (with header files) being compiled against libraries, and if you have said header files and libraries then you're fine...
Quote: What does this have to do with anything on this board?
Well, he started saying something about it, and I think I prompted a lengthier explanation by saying "I have no idea what you just said", because I didn't understand it due to not having any context and the initial statement coming out of the blue. In any case if Shadowfyr wrote more it's probably because of me.
class textedit(Frame):
global Root
Root = Tk()
global Sb
Sb = Scrollbar(Root)
global Tx
Tx = Text(Root)
Does the global keyword make sense in this context?
If you make these class variables you can only ever have one text editor window open. If they are instance variables the limitation becomes OS/hardware.
def __init__(self, parent=None):
try:
Tx.config(font=('Bitstream Vera Sans Mono', 9, 'normal'))
except:
Tx.config(font=('courier', 9, 'normal'))
For me (Python 2.5), attempting to set an invalid font fails without an exception being thrown. The font defaults to the system font, I think. In my case that is Arial. The tkFont module has families() which produces a tuple of all the available font families.
Quote: Any attempt to send the data, or any command, to MUSHclient, crashes mushclient.
In fact any attempt to reference the world global will crash MUSHclient (outside of the original thread).
I'm not sure if this can be worked around. I think the problem is the world variable is a COM object being provided by MUSHclient to the WSH that actually fires the python interpreter, and because we launch a new thread to handle events in our new window, the WSH thinks its job is done and dismantles the environment while our event thread is still running so attempting to access the (now free'd) variable causes a segfault.
Interestingly, putting a self.world = world in the Frame's __init__ will cause a world.Note to work, and then crash :D
As far as I can see you have a choice between not launching the new thread, keeping access to the world variable and preventing MUSHclient from handling events, or launching the new thread, losing the world variable and handling events correctly :(
On the other hand, it might be possible to attack the problem from the other direction, using pywin32 or something to get a new world object from MUSHclient? I'd have to leave it to Nick at this point as I don't know enough about MUSHclient internals to hazard a guess :(
Quote: The 'focus_set()' for some reason still doesn't work, as MUSH retains the focus when edit() is run.
The focus_set() is for the text box inside the Tk window to get the focus for the Tk window. It works in that context. It isn't intended to raise the Tk window.
There is a lift() method in Tkinter for top-level windows that should raise the window... however I can't seem to get it to work :( Part of my problem may be that, for me, the edit window appears on top as the active window when the function runs anyway. (So I've been testing with the lower() function that is supposed to send-to-back.)
Any attempt to send the data, or any command, to MUSHclient, crashes mushclient.
I am inclined to agree with the previous poster on this. Strictly speaking, MUSHclient hasn't crashed, the script engine, possibly calling an invalid COM object, has crashed. Since the whole thing is running as a single application (albeit with multiple threads), the operating system will report that MUSHclient has crashed.
It is really outside the control of MUSHclient, once execution has passed to a script DLL, to stay stable, if the scripting DLL does things that cause the overall application to crash.
I also agree that starting a different thread may be the problem. I can't say for sure that MUSHclient, or the script interface, is thread safe.
I think the whole idea of making a GUI editor, inside MUSHclient, using the scripting interface, is pushing the intended use of scripts to the very boundaries, or possibly beyond, for what they were intended.
As I mentioned in another thread, I can't see how things like events (eg. clicking in a scripted GUI window) will be successfully handled.
(The with keyword is supposed to obviate the .acquire()/.release() calls as of Python 2.5. Supposed to.)
And replace the current global edit() function with:
apps = []
def edit():
global apps
apps.append(TextEditor(master = Tk()))
thread.start_new_thread(apps[-1].mainloop, ())
def poll():
global apps
for app in apps:
app.poll()
And the final step:
Add a timer to your world that fires every 0.1 seconds (or 0.2 seconds or whenever you feel like it really -- remember this is limited by the global timer-granularity preference) and calls the "poll" function.
Ok, now if we need to call a function that uses world we can defer it by quoting it and passing it as the parameter to queue().
For example, if we add the following to CreateMenu():
The File menu now has a "Send" option that dumps the contents of the text box to the mud :)
This seems to work with no great disadvantages. The biggest problems are (1) the delay between clicking something in the editor and the timer firing in MUSHclient to actually handle the code and (2) there is a rumoured memory leak somewhere in the binding between MUSHclient, WSH and Python which is supposedly around 4KB per script call. So you want the timer rate to be as small as possible while keeping the potential leak manageable (0.1 seconds between calls => 40KB/sec => 2.5MB/min => 150MB/hr).
Oh, and as it stands any code still in the queue when the editor window is closed, disappears. (This could be fixed fairly easily.)
PS. Recompiling the script file while an editor window is open makes BAD THINGS happen.
PPS. Just checked the memory leak and with the timer set to 0.1 sec it's leaking about 5MB/min, so on a box with 512MB and a session time around 3-4 hours it's not practical to have a timer interval < 1 sec :(
PPPS. If you have an error in your script when you recompile, the timer will cause you to get a lot of "Could not find poll()" errors. For this reason the first five and last five lines of my .pys are:
This code disables the timers (and remembers their enabled/disabled state) for the duration of the compile (not a bad thing) and if there is an exception or a parse error the timers stay off while the compilation aborts. The next time you recompile (with hopefully fixed code) the timers are reenabled (or not, if they were disabled before you started the first recompile).