Hello everyone. First time here. I''m posting a debug question because I''ve searched google all over and I can''t find any other instances of this occurring. And even though it may be a common error due to a stupid mistake by me, who is just learning ruby and wx, for some odd reason the internet seems devoid of a solution. I''ve even searched this forum and the error message is not here either. What happens is, the script brings up the login/create window just fine the first time, but if the user enters too short a password and the script tries to bring the same window up a second time for another chance at input, the program crashes with exception "Already Initialized Constant THE_APP". I''ve tried rewriting it multiple ways, even the basic App.run do method. Still no luck. It seems like I''m not doing something that is needed to completely destroy the instance of App, as the second time I call it no matter what it always crashes with the exception. What''s funny is, I had this login/create window already done using the TK library and since I had an old version of the library, it had a bug in PMW which basically caused the same kind of behavior as this bug is causing. I could only bring up one instance of anything, if another was ever created, even after all other instances had been destroyed, the program would crash and tell me that a constant was already initialized. Without a way to fix it, I moved on to shoes, which I quickly dismissed because it was WAY too hard to try and get shoes to work from within my ruby script instead of as a script-launcher. Then I spent a good 5 hours researching a way to make "require ''wx''" work, turns out ubuntu 10.04 needs some special installation procedures. Finally got that working, only to find out that, yep, I can only create one instance of a window per program run......... again.... XD I realize that I can just handle the string check in the button code to avoid this one occurrence. However, that won''t fix the problem if I need to be able to reopen a window later in the program. The real problem is that later on I will be developing a lot of GUI windows for this client that will need to be opened, then closed, then reopened, then closed, then reopened, over and over and over again, in order for players to build. If I can''t do it with the first window, it''s not worth building all the subsequent windows or even continuing on the project until I can find a GUI that allows me to create a second instance of a particular window sometime after the first instance had been destroyed. Here''s the contents of obtainlogin.rb. This file is required in the main ruby script. I''m using Ubuntu 10.04 Lucid and Ruby 1.8 Error: "Already Initialized Constant THE_APP" upon second run of App. class LoginFrame < Frame def initialize() super(nil, -1, ''Login Or Create'') # First create the controls @my_panel = Panel.new(self) @userid_label = StaticText.new(@my_panel, -1, ''User ID:'', DEFAULT_POSITION, DEFAULT_SIZE, ALIGN_CENTER) @userid_textbox = TextCtrl.new(@my_panel, -1, '''') @password_label = StaticText.new(@my_panel, -1, ''Password:'', DEFAULT_POSITION, DEFAULT_SIZE, ALIGN_CENTER) @password_textbox = TextCtrl.new(@my_panel, -1, '''', :style => TE_PASSWORD) @connect_but = Button.new(@my_panel, -1, ''Connect'') # Bind controls to functions evt_button(@connect_but.get_id()) { |event| connect_but_click(event)} # Now do the layout @my_panel_sizer = BoxSizer.new(VERTICAL) @my_panel.set_sizer(@my_panel_sizer) @my_panel_sizer.add(@userid_label, 0, GROW|ALL, 2) @my_panel_sizer.add(@userid_textbox, 0, GROW|ALL, 2) @my_panel_sizer.add(@password_label, 0, GROW|ALL, 2) @my_panel_sizer.add(@password_textbox, 0, GROW|ALL, 2) @my_panel_sizer.add(@connect_but, 0, GROW|ALL, 2) show() end def connect_but_click(event) $userid = @userid_textbox.get_value $password = @password_textbox.get_value close end end class LoginApp < App def on_init LoginFrame.new end end def areThereIllegalCharactersInLoginInfo tBool = false for i in (0...$userid.length) if $userid[i] < 32 or $userid[i] > 126 tBool = true end end for i in (0...$password.length) if $password[i] < 32 or $password[i] > 126 tBool = true end end return tBool end def obtainLoginInfo passBool = false while passBool == false #LoginApp.new.main_loop() # This was the original line, I changed it to try and fix the problem. tApp = LoginApp.new tApp.main_loop() tApp = nil # I added this line to try and fix the problem, it does not help at all. passBool = true if $userid.length < 4 or $userid.length > 20 or $password.length < 4 or $password.length > 20 passBool = false puts "Please provide a User ID and Password which are at least 4 characters long and at most 20 characters long." end if areThereIllegalCharactersInLoginInfo == true passBool = false puts "Please provide a User ID and Password which contain only standard characters. Special characters are not permitted." end end end -- Posted via http://www.ruby-forum.com/.
Hello Ron, First off, welcome to wxRuby. Your lucky I''m up this early, as I should have been in bed an hour ago, but you know how it goes. lol The answer to your solution, is to intercept a evt_close on your window class, to prevent the window from being destroyed. What is happening, is when you run your script, the App instance is initialized with Wx::App.run method. And the thing is, there can only ever be one instance of Wx::App at any run time of your script. So if you exit out of the Main Loop for Wx::App, then it''s going to fail, when you try to re-initialize / re-create your App / Window. Mainly cause your trying to re-create your Window, after wxWidgets has already released the App Instance. The solution to your problem, is two fold. First off, move your logical handling code into your Window class. This will ensure that your code is executed, and allow wxWidgets to continue operating for you. You should never exit the Wx::App main loop, unless your actually exiting the program itself. Second, if you want your window to dis-appear, but the app to remain running, you need to do two things. One, ensure that Wx::App, doesn''t exit when the Main Window Instance (The first / Only instance of a Wx::Frame) is destroyed. This can be done with Wx::App#set_exit_on_frame_destroy() method (Referenced here<http://wxruby.rubyforge.org/doc/app.html#App_setexitonframedelete>). This will ensure that if there are no other Window instances available, that wxWidgets will not close out the app, and de-reference the main instance of the App. The second part, is that there are two ways to handle getting rid of a Window. The first, obviously being the close method, which will close the window, and Destroy the reference to the Window. Which will require you to re-create a new instance of the Window. The second method, is to simply hide the window. This is different from minimize, you just use the hide method on the Frame itself, and it will make the window dis-appear, looking as though it had been closed, but the Window instance will not be destroyed, and you will have it available, to re-display to the end user, should you need to use the window again. I hope that this helps you understand what is going on. L8ers, Mario On Fri, Oct 22, 2010 at 5:16 AM, Ron Shadow <lists at ruby-forum.com> wrote:> Hello everyone. First time here. > > I''m posting a debug question because I''ve searched google all over and I > can''t find any other instances of this occurring. And even though it may > be a common error due to a stupid mistake by me, who is just learning > ruby and wx, for some odd reason the internet seems devoid of a > solution. I''ve even searched this forum and the error message is not > here either. > > What happens is, the script brings up the login/create window just fine > the first time, but if the user enters too short a password and the > script tries to bring the same window up a second time for another > chance at input, the program crashes with exception "Already Initialized > Constant THE_APP". I''ve tried rewriting it multiple ways, even the basic > App.run do method. Still no luck. > > It seems like I''m not doing something that is needed to completely > destroy the instance of App, as the second time I call it no matter what > it always crashes with the exception. > > What''s funny is, I had this login/create window already done using the > TK library and since I had an old version of the library, it had a bug > in PMW which basically caused the same kind of behavior as this bug is > causing. I could only bring up one instance of anything, if another was > ever created, even after all other instances had been destroyed, the > program would crash and tell me that a constant was already initialized. > Without a way to fix it, I moved on to shoes, which I quickly dismissed > because it was WAY too hard to try and get shoes to work from within my > ruby script instead of as a script-launcher. Then I spent a good 5 hours > researching a way to make "require ''wx''" work, turns out ubuntu 10.04 > needs some special installation procedures. Finally got that working, > only to find out that, yep, I can only create one instance of a window > per program run......... again.... XD > > I realize that I can just handle the string check in the button code to > avoid this one occurrence. However, that won''t fix the problem if I need > to be able to reopen a window later in the program. The real problem is > that later on I will be developing a lot of GUI windows for this client > that will need to be opened, then closed, then reopened, then closed, > then reopened, over and over and over again, in order for players to > build. If I can''t do it with the first window, it''s not worth building > all the subsequent windows or even continuing on the project until I can > find a GUI that allows me to create a second instance of a particular > window sometime after the first instance had been destroyed. > > Here''s the contents of obtainlogin.rb. This file is required in the main > ruby script. > > I''m using Ubuntu 10.04 Lucid and Ruby 1.8 > > Error: "Already Initialized Constant THE_APP" upon second run of App. > > > > class LoginFrame < Frame > def initialize() > super(nil, -1, ''Login Or Create'') > # First create the controls > @my_panel = Panel.new(self) > @userid_label = StaticText.new(@my_panel, -1, ''User ID:'', > DEFAULT_POSITION, DEFAULT_SIZE, ALIGN_CENTER) > @userid_textbox = TextCtrl.new(@my_panel, -1, '''') > @password_label = StaticText.new(@my_panel, -1, ''Password:'', > DEFAULT_POSITION, DEFAULT_SIZE, ALIGN_CENTER) > @password_textbox = TextCtrl.new(@my_panel, -1, '''', :style => > TE_PASSWORD) > @connect_but = Button.new(@my_panel, -1, ''Connect'') > # Bind controls to functions > evt_button(@connect_but.get_id()) { |event| > connect_but_click(event)} > # Now do the layout > @my_panel_sizer = BoxSizer.new(VERTICAL) > @my_panel.set_sizer(@my_panel_sizer) > @my_panel_sizer.add(@userid_label, 0, GROW|ALL, 2) > @my_panel_sizer.add(@userid_textbox, 0, GROW|ALL, 2) > @my_panel_sizer.add(@password_label, 0, GROW|ALL, 2) > @my_panel_sizer.add(@password_textbox, 0, GROW|ALL, 2) > @my_panel_sizer.add(@connect_but, 0, GROW|ALL, 2) > show() > end > > def connect_but_click(event) > $userid = @userid_textbox.get_value > $password = @password_textbox.get_value > close > end > > end > > class LoginApp < App > def on_init > LoginFrame.new > end > end > > def areThereIllegalCharactersInLoginInfo > tBool = false > for i in (0...$userid.length) > if $userid[i] < 32 or $userid[i] > 126 > tBool = true > end > end > for i in (0...$password.length) > if $password[i] < 32 or $password[i] > 126 > tBool = true > end > end > return tBool > end > > def obtainLoginInfo > passBool = false > while passBool == false > #LoginApp.new.main_loop() # This was the original line, I changed it > to try and fix the problem. > tApp = LoginApp.new > tApp.main_loop() > tApp = nil # I added this line to try and fix the problem, it does > not help at all. > > passBool = true > if $userid.length < 4 or $userid.length > 20 or $password.length < 4 > or $password.length > 20 > passBool = false > puts "Please provide a User ID and Password which are at least 4 > characters long and at most 20 characters long." > end > if areThereIllegalCharactersInLoginInfo == true > passBool = false > puts "Please provide a User ID and Password which contain only > standard characters. Special characters are not permitted." > end > end > end > > -- > Posted via http://www.ruby-forum.com/. > _______________________________________________ > wxruby-users mailing list > wxruby-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/wxruby-users >-- Mario Steele Lieutenant Commander 3 XO - Geo 99 XO - STO IFT Fleet http://www.trekfederation.com http://geo99.ruby-im.net -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/wxruby-users/attachments/20101022/e29ffb0d/attachment-0001.html>
Hey Mario, thanks for your quick reply. Incredibly informative too, now I have a lot of options to deal with the login screen. I am a little confused though. I still don''t see a way to have more than one window in the entire ruby script. "And the thing is, there can only ever be one instance of Wx::App at any run time of your script." "You should never exit the Wx::App main loop, unless your actually exiting the program itself.">From what you say here it almost sounds as if every ruby script can haveonly one window and no other. What if I needed to use app to show a login screen first, then after that a main game window, etc? I could still have the main script running while the main_loop is running if I gave the window its own thread, but that would still be the only allowable instance of the app in the entire program? If there can only ever be one occurence of app in the code, and to create two different windows from two different classes one would need two occurences of app in the code... XD doesn''t that mean each rubyscript can only ever have one window? I see how the hide method can be useful for the login screen, and I can certainly place the string verification code into the frame class. Definitely a solution for the exception on the login screen. But I still need to have the same ruby script create a main game window after the login screen is finished/hidden. Is there perhaps a way to create a second window and show that one within the execution of the same main_loop? I could automate control of the main_loop in its own thread through global variables. Is there any way at all to have two different windows in the same ruby program? I''m thinking that if instead of requiring obtainlogin.rb I could perhaps execute it as a separate process from the main script, and then I could launch another process later for the main game window, but then global variables wouldn''t be shared with the main script. Would have to mess with pipes to do that? Also, if it''s impossible to have more than one window with wxRuby, is there another rubygem GUI library that anyone knows about which would allow two different windows to be opened in the same ruby script? Somehow it seems like I must be missing something because I wouldn''t expect such a large robust library to be limited to one-window-per-program. -- Posted via http://www.ruby-forum.com/.
Hello Ron, On Fri, Oct 22, 2010 at 3:36 PM, Ron Shadow <lists at ruby-forum.com> wrote:> Hey Mario, thanks for your quick reply. Incredibly informative too, now > I have a lot of options to deal with the login screen. >Your Welcome.> I am a little confused though. I still don''t see a way to have more than > one window in the entire ruby script.Okay, I understand where your confusion is below, I''ll just skip down below all this, and explain it in better detail.> "And the thing is, there can only ever be one instance of Wx::App at any > run time of your script." > "You should never exit the Wx::App main loop, unless your actually > exiting the program itself." > >From what you say here it almost sounds as if every ruby script can have > only one window and no other. What if I needed to use app to show a > login screen first, then after that a main game window, etc? I could > still have the main script running while the main_loop is running if I > gave the window its own thread, but that would still be the only > allowable instance of the app in the entire program? If there can only > ever be one occurence of app in the code, and to create two different > windows from two different classes one would need two occurences of app > in the code... XD doesn''t that mean each rubyscript can only ever > have one window? > > I see how the hide method can be useful for the login screen, and I can > certainly place the string verification code into the frame class. > Definitely a solution for the exception on the login screen. But I still > need to have the same ruby script create a main game window after the > login screen is finished/hidden. > > Is there perhaps a way to create a second window and show that one > within the execution of the same main_loop? I could automate control of > the main_loop in its own thread through global variables. > > Is there any way at all to have two different windows in the same ruby > program? > > I''m thinking that if instead of requiring obtainlogin.rb I could perhaps > execute it as a separate process from the main script, and then I could > launch another process later for the main game window, but then global > variables wouldn''t be shared with the main script. Would have to mess > with pipes to do that? > > Also, if it''s impossible to have more than one window with wxRuby, is > there another rubygem GUI library that anyone knows about which would > allow two different windows to be opened in the same ruby script? > Somehow it seems like I must be missing something because I wouldn''t > expect such a large robust library to be limited to > one-window-per-program.Alright, with all that out of the way, the first thing you will need to realize, is that Wx::App, isn''t a Window Class, and is not sub-classed of a Wx::Window or Wx::Frame. If you goto the API reference documentation, http://wxruby.rubyforge.org/doc/app.html, and look for the Sub-Section of Derived From, you''ll see that Wx::App descends from Wx::EvtHandler and Object. I don''t know what kind of programming background you have, but to look at wxRuby in the fashion of a MVC (Model - View - Controller) setup, Wx::App would be the Controller setup. It''s your Main Entry Point into running your program, and deciding where to go. Wx::App.run, or Wx::App#on_init is your Main Entry point, into your entire program, all your windows will either be created from here, or be setup to be ready to be created from the rest of your program. All your initialization of library functions, and data stores you need, would be done from this method. The View Part, actually falls under the class of Wx::Frame. There''s a common mis-conception when first dealing with wxWidgets in general, the difference between Window, and Frame. Mainly cause of Microsoft Windows, and how their API is setup, Window means Window. An actual window displayed to the user, that has a minimize, maximize, and close button on it. Where as with wxWidgets, what is considered a window, is actually considered a Frame, with a minimize, a maximize, and a close button on it. A Window in wxWidgets is actually considered any control that can be displayed on the screen. You''ll find if you go through the API Documentation, and look at the sub-section Derived From, a good 90 percent of them, have the Window class in it. The exception to the rule, is of course Sizers, Menus, AuiManager, etc, etc, where these are basically internal data structures, that wxWidgets utilizes, to create the necessary UI Elements on Linux, Windows, and Mac OS X. Each Platform, and basically each GUI Toolkit has different methods in which to handle the above cases of items, or may not have them at all (As with Sizers aren''t native to Windows, but is available on Linux with GTK and on OS X with NSView, and with Menus, Windows and Linux with GTK have Menu Items, where as OS X has Data Entries to Represent Menu Items.) So, let''s say with your Example, your wanting to do a Development of a Game, where you have a Login, and a Main Display Window, where the Login is a User Prompt to ask for Login information to get into the game, and the Main Display Window, is where all actual game play occurs. I''ll give you a very basic design to show you how it works, and explain it further with comments. I''m writing the code as I go, so it may not be 100 percent correct, but you should be able to run the code, without any problems. -- CODE BEGINS HERE -- #!/usr/bin/env ruby # Here we are loading wxRuby by any possible means, either by a system # install, or by a Ruby Gems install. If we can''t find a system install, then we # will try to load through RubyGems, if available, and if that fails, we''ll just # return the original error, saying that we can''t load wxRuby, as it''s probably not # installed. begin require ''wx'' rescue e => LoadError begin require ''rubygems'' require ''wx'' rescue LoadError raise e end end # This is the window that will be the Main Display Window class GameWindow < Wx::Frame def initialize # The parent of this window is desktop, so nil is used # We don''t need a specific ID for this window, so -1 is used # Our Title for our new Window is "Game Window" super(nil,-1,"Game Window") # Here we create all of our stuff needed to play the game, # such as UI Elements, and stuff that needs to be displayed in # The game Window. No other window controls are created here. @te Wx::TextCtrl.new(self,-1,:pos=>[0,0],:size=>[200,20],:style=>Wx::TE_RICH2|Wx::TE_AUTO_URL|Wx::TE_PROCESS_ENTER) # After we create our controls, we setup our event handlers, for gathering events. evt_text_enter @te, :input_handle_enter end # This is where we define our Logical methods, to handle game def input_handle_enter Wx::MessageDialog.new(self,"You entered: #{@te.get_value}","User Input", Wx::OK) end end # Now we setup our Login Window, which will be displayed first, then will pass off to # the Main Display Window to continue running. class LoginWindow < Wx::Frame def initialize super(nil,-1,"Login") table = Wx::GridSizer.new(3,2,0,0) table.add(Wx::StaticText.new(self,-1,"Username:"),0,Wx::ALIGN_LEFT) table.add(@user = Wx::TextCtrl.new(self,-1,""),1,Wx::EXPAND|Wx::ALL) table.add(Wx::StaticText.new(self,-1,"Password:"),0,Wx::ALIGN_LEFT) table.add(@pass Wx::TextCtrl.new(self,-1,"",:style=>Wx::TE_PASSWORD),1,WX::EXPAND|Wx::ALL) table.add_spacer table.add(@login = Wx::Button.new(self,-1,"Login>"),1,Wx::EXPAND|Wx::ALL)self.set_sizer(table) evt_button @login, :on_login_push end def on_login_push uname = @user.get_value upass = @pass.get_value unless uname.empty? AND upass.empty? # Attempt to login here, and process success or failure. if success gw = GameWindow.new gw.show self.hide end end end class MyGameApp < Wx::App def on_init lw = LoginWindow.new lw.show end end MyGameApp.new.main_loop -- CODE ENDS HERE -- As you can see, I create the Login Window, which handles the login process, and if it''s successful, then will create the game window, and hide itself. The App is still running, and never exits, and your windows will continue to display, and run, and you won''t get any Pesky THE_APP already initialized segfaults. Now, keep in mind, if you want to call methods on your App class, you can simply use the method Wx::get_app(), or you can use Wx::THE_APP to get the instance of your main App, and execute the method on it. Though, it''s strongly suggested that you don''t put game loops and such that require access to your Game Window, in your App, as your crossing between objects, and the self reference changes between Objects, when you get to that point. EG: Calling a Method on your App class, means self refers to the instance of the App class itself, where as calling a method on your Window class, means self refers to the instance of the Window class. And by that, instance variables will be different between the two, or non-existent between the two. I hope this makes things clearer. Mario -- Mario Steele Lieutenant Commander 3 XO - Geo 99 XO - STO IFT Fleet http://www.trekfederation.com http://geo99.ruby-im.net -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/wxruby-users/attachments/20101023/90697ab1/attachment.html>
Yes, that is much clearer. Thanks for taking the time to write the code and show me. I realize I probably seem like a Ruby noob. I''ve been learning Ruby for almost two weeks and so far I love it. I''ve coded games in VB6 and PHP/MySQL and Flash Actionscript, and I''ve coded other kinds of programs in C++. Ruby is definitely different but I can see a lot of good qualities from different languages packed together into Ruby. I found Rubygame library and it looks great for the graphical combat screen, but has absolutely no utilities like buttons/textboxes/etc, so it''s great that Wx can still be used. I also see what you mean by having to put all the code of the client into the Wx classes. I''d prefer if possible to leave things like the connection protocol, socket communication, macro key functions, sound effect calls, etc, outside of the frame classes and the main_loop. If I wanted to keep handling connection events from the main script while the main_loop was executing, I could use a separate thread for the main_loop, but would there be a way to hide/show a frame from a thread outside the main_loop? Like ''def methodX; self.hide; end'' in one of the frame classes, and ''$loginFrame.methodX'' from outside the main_loop thread? Or $loginFrame.hide? I know I can call methods defined by the main-thread from spawned-thread blocks so it ought to work the same way in reverse if I use global variables for all the frame instances? -- Posted via http://www.ruby-forum.com/.
Hello again Ron, On Sun, Oct 24, 2010 at 2:28 AM, Ron Shadow <lists at ruby-forum.com> wrote:> Yes, that is much clearer. Thanks for taking the time to write the code > and show me. >Not a problem, and I''m glad that you can finally understand where this is.> I realize I probably seem like a Ruby noob. I''ve been learning Ruby for > almost two weeks and so far I love it. I''ve coded games in VB6 and > PHP/MySQL and Flash Actionscript, and I''ve coded other kinds of programs > in C++. Ruby is definitely different but I can see a lot of good > qualities from different languages packed together into Ruby. >Ruby is Unique in the fact that it''s pure Object Oriented, and therefore, fits many encapsulations of elements within a program.> I found Rubygame library and it looks great for the graphical combat > screen, but has absolutely no utilities like buttons/textboxes/etc, so > it''s great that Wx can still be used. >...> I also see what you mean by having to put all the code of the client > into the Wx classes. I''d prefer if possible to leave things like the > connection protocol, socket communication, macro key functions, sound > effect calls, etc, outside of the frame classes and the main_loop. >I understand, I''ll get a bit more indepth here in a moment....> If I wanted to keep handling connection events from the main script > while the main_loop was executing, I could use a separate thread for the > main_loop, but would there be a way to hide/show a frame from a thread > outside the main_loop? Like ''def methodX; self.hide; end'' in one of the > frame classes, and ''$loginFrame.methodX'' from outside the main_loop > thread? Or $loginFrame.hide? > > I know I can call methods defined by the main-thread from spawned-thread > blocks so it ought to work the same way in reverse if I use global > variables for all the frame instances?Threads are a tricky business, especially when you get into Multiple Threads, and that you also need to realize something else. Depending upon what version of the Ruby Interpreter your using, you have to deal with another layer of trouble. In Ruby 1.8, it is designed at the core, to use Green Threads. Which basically means, that a Thread is created internally in the Interpreter that is basically an Emulated Thread, but not a true native thread. This basically means that Ruby is handling all the scheduling and such for each of the threads, instead of the OS itself. Ruby 1.9 on the other hand, actually implements Native threads, where the OS is handling the Threads itself, and not Ruby. What this means to you, is that if you were to use Ruby 1.8 Threads, and you have something like wxWidget''s main_loop running, 99.9999 percent of the time will be spent on main_loop, giving ruby extremely little chance to run any other threads. If at all. Where as Ruby 1.9, it handles Threads natively, which allows main_loop to run in it''s own native thread, and allows you to create other threads, in which to actually run simultaneously as the Main Thread. Which brings me to Thread Safety. The main thing you want to be careful about with dealing with Threads, is using them safely. Thread Safety basically entails using a Mutex, or Semaphore to get a global lock within your program, and allow a certain thread to have exclusive access to the variable data, including updating it with new information, while preventing other threads from having access for the time that your updating the data. If all your doing is Reading Variables, and not assigning to them from another thread, then you should be fine. But if your assigning data from other threads, then you need to create a Mutex, lock it for the period that your updating the data, then unlock it when your finished. If you don''t, then you could get those nice little fatal errors, about access violation of memory addresses. I''m sure with your C++ background, you probably have a good idea what I mean by this. Lastly, another thing you will need to be careful of, is the whole usage of two different libraries, that utilize a tight end Main Loop. RubyGame utilizies a tight end Main Loop to allow processing of drawing, events, and so on, while wxWidgets also has it''s own tight end Main Loop, to handle the same things. Attempting to use these two in conjunction, requires a bit of advanced programming to get to work properly. Not to say that it can''t be done, it can, but it will be hard to do, as you will need to write a sort of merged main loop, that will handle wxRuby events, and handle RubyGame events at the same exact time, to keep both libraries running smoothly, as if they were separate. Thankfully, wxRuby allows you to write your own main_loop function, if you were to sub-class Wx::App. and using Wx::App#pending to see if there are any wxWidgets events pending, and if there are, using Wx::App#dispatch to dispatch events to be executed. Using this in concert with RubyGame, or any other library''s own way of processing their own events, may help you utilize what you want to keep things running smoothly. I do hope that this helps you out, and progresses you further in developing your application / game. L8ers, Mario> -- > Posted via http://www.ruby-forum.com/. > _______________________________________________ > wxruby-users mailing list > wxruby-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/wxruby-users >-- Mario Steele Lieutenant Commander 3 XO - Geo 99 XO - STO IFT Fleet http://www.trekfederation.com http://geo99.ruby-im.net -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/wxruby-users/attachments/20101026/e7d53d6c/attachment-0001.html>
Mario Steele wrote in post #957323: I bit the bullet and just went with the flow, coded the app to load/show/hide from within the main_loop. I have a login screen, main screen, and a player creation screen. Although I can''t help but load/show the player creation and main screens from the socket thread that is outside the main_loop. Even though it''s calling a method from a frame class it''s still calling from outside main_loop, etc. It works 10% of the time, but 90% of the time I get a segmentation fault when trying to show the player creation screen (the .show() method). Isolated it down to that line by using puts before and after it. I''ve searched these forums and found some tips, tried some of them but they haven''t helped yet. I don''t need to boost GC speed because I am getting the fault in the same place all the time, it''s just that 10% of the time it does not occur and the creation screen shows and behaves normally. I tried GC.disable in my script but that didn''t solve the problem, so I don''t think it''s caused by garbage collection.> Green Threads. Which basically means, that a Thread is created > internally > in the Interpreter that is basically an Emulated Thread, but not a true > native thread. This basically means that Ruby is handling all the > scheduling and such for each of the threads, instead of the OS itself. > Ruby > 1.9 on the other hand, actually implements Native threads, where the OS > is > handling the Threads itself, and not Ruby.> What this means to you, is that if you were to use Ruby 1.8 Threads, and > you > have something like wxWidget''s main_loop running, 99.9999 percent of the > time will be spent on main_loop, giving ruby extremely little chance to > run > any other threads. If at all.This answers a big question of mine. The client stops communicating with the server when the GUI is shown, until I start moving the mouse. The client only continues to process the socket thread if I continue to move the mouse. So if I run it on ruby1.9.1 that''ll take care of that problem? Turns out I can''t uninstall ruby1.8 without removing ruby completely. Ruby doesn''t run if I have only 1.9.1 installed, oddly enough. So should I just leave ruby1.8 installed and install ruby1.9.1? Will that mean any script I run will automatically use ruby1.9.1? RVM seems to be way too complicated, not sure if I want to use RVM. XD> If all your doing is Reading Variables, and not assigning to them from > another thread, then you should be fine. But if your assigning data > from > other threads, then you need to create a Mutex, lock it for the period > that > your updating the data, then unlock it when your finished. If you > don''t, > then you could get those nice little fatal errors, about access > violation of > memory addresses. I''m sure with your C++ background, you probably have > a > good idea what I mean by this.I will definitely need to be modifying the properties of the class instances that are initiated within the main_loop, from outside the main_loop in the socket thread. So it sounds like I''ll have to be using locks. Thanks for telling me about that, probably would have taken me a while to find that. Also - this is probably what is causing the segmentation faults? The fact that I don''t have synchronized blocks / mutex locks?> Thankfully, wxRuby allows you to write your own main_loop function, if > you > were to sub-class Wx::App. and using Wx::App#pending to see if there > are > any wxWidgets events pending, and if there are, using Wx::App#dispatch > to > dispatch events to be executed. Using this in concert with RubyGame, or > any > other library''s own way of processing their own events, may help you > utilize > what you want to keep things running smoothly.What if I don''t need to execute any code in the wx main_loop while the Rubygame main_loop is running? I can handle the combat mode using only Rubygame. Does that mean that, instead of rewriting the main_loop, I could just execute the Rubygame main_loop from inside of the wx main_loop? I could tell the wx main_loop to sleep while the Rubygame main_loop is executing, just to make sure it waits for combat to end.> I do hope that this helps you out, and progresses you further in > developing > your application / game. > > L8ers, > > MarioYeah, you''ve been incredibly helpful. I don''t think I would have got WxWidgets to show multiple windows without your explanation on the main_loop etc. Thanks! :) -- Posted via http://www.ruby-forum.com/.
I am currently in the wxRuby chat room, if you wish to talk with me in person, and I can answer some of these questions for you. On Thu, Oct 28, 2010 at 1:27 AM, Ron Shadow <lists at ruby-forum.com> wrote:> Mario Steele wrote in post #957323: > > I bit the bullet and just went with the flow, coded the app to > load/show/hide from within the main_loop. I have a login screen, main > screen, and a player creation screen. Although I can''t help but > load/show the player creation and main screens from the socket thread > that is outside the main_loop. Even though it''s calling a method from a > frame class it''s still calling from outside main_loop, etc. It works 10% > of the time, but 90% of the time I get a segmentation fault when trying > to show the player creation screen (the .show() method). Isolated it > down to that line by using puts before and after it. > > I''ve searched these forums and found some tips, tried some of them but > they haven''t helped yet. I don''t need to boost GC speed because I am > getting the fault in the same place all the time, it''s just that 10% of > the time it does not occur and the creation screen shows and behaves > normally. I tried GC.disable in my script but that didn''t solve the > problem, so I don''t think it''s caused by garbage collection. > > > Green Threads. Which basically means, that a Thread is created > > internally > > in the Interpreter that is basically an Emulated Thread, but not a true > > native thread. This basically means that Ruby is handling all the > > scheduling and such for each of the threads, instead of the OS itself. > > Ruby > > 1.9 on the other hand, actually implements Native threads, where the OS > > is > > handling the Threads itself, and not Ruby. > > > What this means to you, is that if you were to use Ruby 1.8 Threads, and > > you > > have something like wxWidget''s main_loop running, 99.9999 percent of the > > time will be spent on main_loop, giving ruby extremely little chance to > > run > > any other threads. If at all. > > This answers a big question of mine. The client stops communicating with > the server when the GUI is shown, until I start moving the mouse. The > client only continues to process the socket thread if I continue to move > the mouse. So if I run it on ruby1.9.1 that''ll take care of that > problem? > > Turns out I can''t uninstall ruby1.8 without removing ruby completely. > Ruby doesn''t run if I have only 1.9.1 installed, oddly enough. So should > I just leave ruby1.8 installed and install ruby1.9.1? Will that mean any > script I run will automatically use ruby1.9.1? RVM seems to be way too > complicated, not sure if I want to use RVM. XD > > > If all your doing is Reading Variables, and not assigning to them from > > another thread, then you should be fine. But if your assigning data > > from > > other threads, then you need to create a Mutex, lock it for the period > > that > > your updating the data, then unlock it when your finished. If you > > don''t, > > then you could get those nice little fatal errors, about access > > violation of > > memory addresses. I''m sure with your C++ background, you probably have > > a > > good idea what I mean by this. > > I will definitely need to be modifying the properties of the class > instances that are initiated within the main_loop, from outside the > main_loop in the socket thread. So it sounds like I''ll have to be using > locks. Thanks for telling me about that, probably would have taken me a > while to find that. > > Also - this is probably what is causing the segmentation faults? The > fact that I don''t have synchronized blocks / mutex locks? > > > Thankfully, wxRuby allows you to write your own main_loop function, if > > you > > were to sub-class Wx::App. and using Wx::App#pending to see if there > > are > > any wxWidgets events pending, and if there are, using Wx::App#dispatch > > to > > dispatch events to be executed. Using this in concert with RubyGame, or > > any > > other library''s own way of processing their own events, may help you > > utilize > > what you want to keep things running smoothly. > > What if I don''t need to execute any code in the wx main_loop while the > Rubygame main_loop is running? I can handle the combat mode using only > Rubygame. > > Does that mean that, instead of rewriting the main_loop, I could just > execute the Rubygame main_loop from inside of the wx main_loop? I could > tell the wx main_loop to sleep while the Rubygame main_loop is > executing, just to make sure it waits for combat to end. > > > I do hope that this helps you out, and progresses you further in > > developing > > your application / game. > > > > L8ers, > > > > Mario > > Yeah, you''ve been incredibly helpful. I don''t think I would have got > WxWidgets to show multiple windows without your explanation on the > main_loop etc. Thanks! :) > > -- > Posted via http://www.ruby-forum.com/. > _______________________________________________ > wxruby-users mailing list > wxruby-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/wxruby-users >-- Mario Steele Lieutenant Commander 3 XO - Geo 99 XO - STO IFT Fleet http://www.trekfederation.com http://geo99.ruby-im.net -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/wxruby-users/attachments/20101028/4b78b040/attachment-0001.html>
require ''thread'' $mutex = Mutex.new ... # this method is in class MainScreenFrame < Wx::Frame def showPlayerCreationScreen # this method ends up getting called from the socket thread. $mutex.synchronize { $theCreationScreen = PlayerCreationFrame.new() $theCreationScreen.show # segmentation fault occurs on this line # 10% of the time there will be no segmentation fault and the screen will show/behave fine. } end I''ve placed puts at the end of the def initialize method in the PlayerCreationFrame class, and the puts always gets shown before the segmentation fault occurs, so it''s not occurring with initialization of PlayerCreationFrame (unless it occurs as the initialization method ends?). GC.disable has no effect. -- Posted via http://www.ruby-forum.com/.
For those of you who don''t have an IRC Client, and would like to use a Web Page chat system, you can use the following: http://webchat.freenode.net/?channels=wxruby FreeNode no longer allows Mibbit to work, so this will allow you to get into the wxRuby channel without needing to install an IRC Client, or figuring out which room to go to. ;-) On Thu, Oct 28, 2010 at 1:35 AM, Mario Steele <mario at ruby-im.net> wrote:> I am currently in the wxRuby chat room, if you wish to talk with me in > person, and I can answer some of these questions for you. > > > On Thu, Oct 28, 2010 at 1:27 AM, Ron Shadow <lists at ruby-forum.com> wrote: > >> Mario Steele wrote in post #957323: >> >> I bit the bullet and just went with the flow, coded the app to >> load/show/hide from within the main_loop. I have a login screen, main >> screen, and a player creation screen. Although I can''t help but >> load/show the player creation and main screens from the socket thread >> that is outside the main_loop. Even though it''s calling a method from a >> frame class it''s still calling from outside main_loop, etc. It works 10% >> of the time, but 90% of the time I get a segmentation fault when trying >> to show the player creation screen (the .show() method). Isolated it >> down to that line by using puts before and after it. >> >> I''ve searched these forums and found some tips, tried some of them but >> they haven''t helped yet. I don''t need to boost GC speed because I am >> getting the fault in the same place all the time, it''s just that 10% of >> the time it does not occur and the creation screen shows and behaves >> normally. I tried GC.disable in my script but that didn''t solve the >> problem, so I don''t think it''s caused by garbage collection. >> >> > Green Threads. Which basically means, that a Thread is created >> > internally >> > in the Interpreter that is basically an Emulated Thread, but not a true >> > native thread. This basically means that Ruby is handling all the >> > scheduling and such for each of the threads, instead of the OS itself. >> > Ruby >> > 1.9 on the other hand, actually implements Native threads, where the OS >> > is >> > handling the Threads itself, and not Ruby. >> >> > What this means to you, is that if you were to use Ruby 1.8 Threads, and >> > you >> > have something like wxWidget''s main_loop running, 99.9999 percent of the >> > time will be spent on main_loop, giving ruby extremely little chance to >> > run >> > any other threads. If at all. >> >> This answers a big question of mine. The client stops communicating with >> the server when the GUI is shown, until I start moving the mouse. The >> client only continues to process the socket thread if I continue to move >> the mouse. So if I run it on ruby1.9.1 that''ll take care of that >> problem? >> >> Turns out I can''t uninstall ruby1.8 without removing ruby completely. >> Ruby doesn''t run if I have only 1.9.1 installed, oddly enough. So should >> I just leave ruby1.8 installed and install ruby1.9.1? Will that mean any >> script I run will automatically use ruby1.9.1? RVM seems to be way too >> complicated, not sure if I want to use RVM. XD >> >> > If all your doing is Reading Variables, and not assigning to them from >> > another thread, then you should be fine. But if your assigning data >> > from >> > other threads, then you need to create a Mutex, lock it for the period >> > that >> > your updating the data, then unlock it when your finished. If you >> > don''t, >> > then you could get those nice little fatal errors, about access >> > violation of >> > memory addresses. I''m sure with your C++ background, you probably have >> > a >> > good idea what I mean by this. >> >> I will definitely need to be modifying the properties of the class >> instances that are initiated within the main_loop, from outside the >> main_loop in the socket thread. So it sounds like I''ll have to be using >> locks. Thanks for telling me about that, probably would have taken me a >> while to find that. >> >> Also - this is probably what is causing the segmentation faults? The >> fact that I don''t have synchronized blocks / mutex locks? >> >> > Thankfully, wxRuby allows you to write your own main_loop function, if >> > you >> > were to sub-class Wx::App. and using Wx::App#pending to see if there >> > are >> > any wxWidgets events pending, and if there are, using Wx::App#dispatch >> > to >> > dispatch events to be executed. Using this in concert with RubyGame, or >> > any >> > other library''s own way of processing their own events, may help you >> > utilize >> > what you want to keep things running smoothly. >> >> What if I don''t need to execute any code in the wx main_loop while the >> Rubygame main_loop is running? I can handle the combat mode using only >> Rubygame. >> >> Does that mean that, instead of rewriting the main_loop, I could just >> execute the Rubygame main_loop from inside of the wx main_loop? I could >> tell the wx main_loop to sleep while the Rubygame main_loop is >> executing, just to make sure it waits for combat to end. >> >> > I do hope that this helps you out, and progresses you further in >> > developing >> > your application / game. >> > >> > L8ers, >> > >> > Mario >> >> Yeah, you''ve been incredibly helpful. I don''t think I would have got >> WxWidgets to show multiple windows without your explanation on the >> main_loop etc. Thanks! :) >> >> -- >> Posted via http://www.ruby-forum.com/. >> _______________________________________________ >> wxruby-users mailing list >> wxruby-users at rubyforge.org >> http://rubyforge.org/mailman/listinfo/wxruby-users >> > > > > -- > Mario Steele > Lieutenant Commander 3 > XO - Geo 99 > XO - STO IFT Fleet > http://www.trekfederation.com > http://geo99.ruby-im.net > >-- Mario Steele Lieutenant Commander 3 XO - Geo 99 XO - STO IFT Fleet http://www.trekfederation.com http://geo99.ruby-im.net -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/wxruby-users/attachments/20101028/651f7d5b/attachment.html>
Mario Steele wrote in post #957691:> I am currently in the wxRuby chat room, if you wish to talk with me in > person, and I can answer some of these questions for you.Awesome, will drop on by. That''s an IRC chatroom on freenode, right? #wxruby? Or do you mean another kind of chat room? -- Posted via http://www.ruby-forum.com/.