Jump to content
The Dark Mod Forums

Understanding the Code


Recommended Posts

Well that was easy. Quite a bit of copy-pasting, but it works nicely and I also understand the creation of dialogs much better now. Sweet! Do you have a filevisitor setup for your guiparser or should I create one?

What will the filevisitor be doing? Creating a list of available GUIs, I reckon? I don't have such a thing yet, this can be added to the GuiManager if you want to take a crack at this. A simple std::set of GUI paths is enough I guess.

 

Question: How can I retrieve the Mod- or Mod_base-directory. Currently I retrieve the engine path and add "darkmod/xdata/" for saving, but it'd be much better to retrieve the mod-path and append "xdata/", so that it's always stored in the right folder. Fidcal for instance said that he likes to setup a new project folder inside the doom folder when creating an FM and retrieving the modpath would ensure that the files are stored in the right place.

I just extended the IGame interface for you. Use this:

 

#include "igame.h"

 

then add a reference to the MODULE_GAMEMANAGER to the module and use the GlobalGameManager() accessor to retrieve the settings:

 

// Returns the setting for fs_game
virtual const std::string& getFSGame() const = 0;

// Returns the setting for fs_game_base (can be empty)
virtual const std::string& getFSGameBase() const = 0;

/**
* greebo: Gets the mod path (e.g. ~/.doom3/gathers/). 
* Returns the mod base path if the mod path itself is empty. 
*/
virtual const std::string& getModPath() const = 0;

/** 
* greebo: Returns the mod base path (e.g. ~/.doom3/darkmod/), 
* can be an empty string if fs_game_base is not set.
*/
virtual const std::string& getModBasePath() const = 0;

 

getModPath is likely what you're after.

Link to comment
Share on other sites

  • Replies 234
  • Created
  • Last Reply

Top Posters In This Topic

Top Posters In This Topic

Posted Images

Thanks. Already changed the code!!

 

What will the filevisitor be doing? Creating a list of available GUIs, I reckon? I don't have such a thing yet, this can be added to the GuiManager if you want to take a crack at this. A simple std::set of GUI paths is enough I guess.

In addition to that, it should also detect the following things:

  • Is this a gui for readables? If not, discard the gui.
  • Is this a gui for two-sided or one-sided readables?

I'd like the gui-browser to only list appropriate guis. So they have to be readable-guis and they have to match the current layout. I'd use a std::map then to store the layout-bool as well. I'll give implementing it a shot...

Link to comment
Share on other sites

The GuiManager itself can maintain this, yes. I'd suggest a std::map<:string guiinfoptr>. The std::string is the VFS path to the GUI, and the GuiInfo carries all the rest of the information.

 

The GuiManager can then provide a simple foreachGui() method which allows clients to traverse the GUI information - the file selector in your dialog then traverses the available GUIs and picks the appropriate ones.

Link to comment
Share on other sites

Ah good idea. Sounds like an interesting task to setup something like this on my own. I'll start working on it this evening probably, or rather tonight, as I've got lots of learning to catch up on. :)

Link to comment
Share on other sites

I am thinking about doing it differently right now. I have added a FileVisitor to the GuiManager which imports all GuiDefinitions. This isn't working as good as I had hoped, because the importer fails on many definitions.

 

But aside from that, I think it'd be good if we checked whether a gui definition is a readable and what layout it provides directly after importing it and store its path in two separate std::sets in the GuiManager, one for OneSided definitions and one for TwoSided. This enables us on the one hand to easily check whether a hand-typed gui-request of the entry-widget matches the pagelayout and also provides a good start for creating a treeview. What do you think?

Link to comment
Share on other sites

@STiFU: I need to get hold of a list of XData pairs for a given page, is there an interface for that?

 

To specify what I need:

"page1_title" : "ATTENTION!"
"page1_body" : "It has come to our understanding that guards took "

I need to load these two values into the GUI state for rendering the preview. The in-game readable script works like this: Find all keyvalue pairs starting with "pageN" (where N is the current page number) and load them into the GUI state, after cutting off the "pageN_" prefix.

 

So, I'd need a method like this:

typedef std::pair<std::string, std::string> KeyVauePair;
typedef std::list<KeyValuePair> KeyValues;

KeyValues getKeyValuesForPage(const std::size_t pageNum);

which returns something like

"title" => "Attention!"
"body" => "It has come..."

Is something like this possible? I see that you're parsing the "pageN_..." stuff into dedicated member variables, but I'd need the raw key value pairs. The readable script is agnostic of the actual names ("title" or "body"), it just loads everything into the GUI state and the GUI is updating itself onTime 0.

 

Or maybe the readable editor can give me such a list, depending on the onesided/twosided selection? I'll investigate that a bit, maybe I can find an easy workaround for me.

 

edit: I think I'll use the existing functions and re-generate those values myself for loading into the GUI state. Let's see how far I can get with those.

Link to comment
Share on other sites

Yeah, I'd say a method like that should rather be kept on the gui-namespace anyway, since it's not in any way XData related.

 

However, I have thought of another way for implementing my task, which is much more flexible and practical. I will implement a checkGuiAppearance() method, which returns ONESIDED, TWOSIDED, NO_READABLE or NO_SUCH_FILE for a given guiPath. This might come in handy for you as well. The advantage of this method over a StringVector is that I don't need to parse all gui in order to check the status of a single gui.

 

I don't know how you were planning text to be passed to the renderer, but if the signature was something like the following you could easily detect how to parse that stuff into a gui by checking for NULLness:

void someRenderTextMethod(const char* title, const char* body,
const char* rightTitle = NULL, const char* rightBody= NULL);

 

Edit: Just saw how you pass the strings. That works too of course!! :)

Link to comment
Share on other sites

I have just written the readable identifier. I discovered that some gui definitions are faulty. I assume that books generally should not contain a "title" window def, but a "LeftTitle" and a "rightTitle" windowdef. Here is the list of faulty definitions:

  • book2_jd_hand_both_curl
  • book_bamber_gothic_both_curl
  • book_bamber_gothic_illum1_test2
  • book_bamber_gothic_left_curl
  • book_bamber_gothic_right_curl
  • book_both_curl
  • book_right_curl
  • book_left_curl
  • book_stone_print_both_curl
  • book_stone_print_left_curl
  • book_stone_print_right_curl
  • book_without_curl
  • mansion_book
  • mansion_book_01 to 08
  • mansion_book_base

 

If the title windowdef is legal for books, I'd have to search for body-defs then instead of title defs. Although, we will probably run into problems with XData and the preview renderer etc. when we try to stuff content inside the gui.

Link to comment
Share on other sites

Yeah sweet!! The preview is missing the last typed key though because you call storeContent() in the Keypress Callback method, which means, that the last keypress has not been submitted to the textview yet, because the callback method didn't return FALSE. Also the rendering of the body does not work right yes, as you probably know... It is not offset right.

 

We nearly had a collision there. I extended updateGuiView a little to enable us to preview Gui or XData definitions from the GuiSelector respectively the XDataSelector. It's already working for the GuiSelector. Check it out if you have to patience to wait until it's loaded up... :) Maybe I should limit the filevisitor to "guis/readables/" to decrease the loadtime.

 

Gotta start learning now. Have been coding way too long again today. But it's so cool to see the editor finally take some shape!!! :)

Link to comment
Share on other sites

Yay, the texts are updating now correctly. But it was just a trade-off, because now the rest of the editor isn't working right anymore... :P (insert, delete, Layout-switching, appending/prepending pages)

 

The problem is that after every change of the textviews (be it caused by the editor controls or by the user) the content of them is stored in the XData definition. The editor updates the textviews successively and those changes cause the xdata content to be destroyed by storePageContents(). A solution to this could probably be to remove the storePageContents() from the onTextChanged() method and have the updateGuiView() directly grab the strings directly from the textviews. I have written a small helper method for that: std::string readTextBuffer(int wEnum)

Link to comment
Share on other sites

Yup... That fixed it. But working on like this is bound to lead to conflicts in the svn, so I'll really start learning now finally!! :D

 

By the way, can you make the background of the preview gray, to match up with the rest of the interface? Also it'd be really cool if the scaling of the preview kept its aspect ratio.

Link to comment
Share on other sites

I need to connect an event/signal on my Selector classes that is thrown when the user clicks on the close-button ('x') of the window. That's "delete-event" or "destroy-event", right? Tried them both and it didn't work apparently. The callback method was never reached. I tried connecting them to this and to getWindow() without any luck. Any idea what I am doing wrong?

 

By the way, I finally found a fix to the GtkEntry warning about the focus-out event, which said that the handler must return FALSE, which he did actually, but that FALSE has to be received within a certain time and calling some method inside the handler might lead to a timeout, resulting in the warning. As I already noted in the SVN, the solution is to connect the event via g_connect_signal_after(..). This would also have fixed our problem with the guiView not updating right because of the keypress-event of the textviews.

Link to comment
Share on other sites

I need to connect an event/signal on my Selector classes that is thrown when the user clicks on the close-button ('x') of the window. That's "delete-event" or "destroy-event", right? Tried them both and it didn't work apparently. The callback method was never reached. I tried connecting them to this and to getWindow() without any luck. Any idea what I am doing wrong?

It's delete-event, yes.

 

But if you need it for doing something after the dialog has been destroyed, you can override the protected _postDestroy() or _preDestroy() methods as well, these are reliably called.

Link to comment
Share on other sites

Ah good, thanks!

 

Couple of notes on the GuiSelector and the changes you recently made:

  • Connecting the switch-page signal after setting the initial page-switch was actually a fix. The way it is now the following happens on a TwoSided readable: The window launches and switches to page 1 first, so the ReadableEditor switches to onesided editing and directly to twosided editing after that because of the initial page-switch of the notebook. But it has a different gui active now, since toggling between twosided and onesided makes it use default guis. Please put the signal_connect back in place or put the page switch anywhere before it. Well, you could also use a boolean of course.
  • I made the treestores (kind of) static, because they will be recreated every time we call the browser otherwise, which takes some time and since the data they are based on is static, there is no need to recreate them multiple times. But maybe the new implementation with the appearance map is a lot faster, so that the recreation is no big deal...
  • Suggestion for the appearanceMap: We could omit the NO_READABLE entries, because we don't need them anyway. This would reduce searchtime and treestore creation time.

I have been playing around a little with identifying not available characters in a font. Checking whether the uv-coordinates are (0,0) is not a solution to the problem as some characters start right there... If we want to do it, we'll have to think of something else, e.g. in the preprocessing where you create the glyph objects for the renderer, we could check if all pixels in the specified area are black and mark the glyph as invalid then.

Link to comment
Share on other sites

Connecting the switch-page signal after setting the initial page-switch was actually a fix. The way it is now the following happens: The window launches and switches to page 1 first, so the ReadableEditor switches to onesided editing and directly to twosided editing after that because of the initial page-switch of the notebook. But it has a different gui active now, since toggling between twosided and onesided makes it use default guis. Please put the signal_connect back in place or put the page switch anywhere before it.

Did I change that? This must have been happening unintentionally when I tried to resolve the conflicts I was getting from SVN - I'll put that back in.

 

I made the treestores (kind of) static, because they will be recreated every time we call the browser otherwise, which takes some time and since the data they are based on is static, there is no need to recreate them multiple times. But maybe the new implementation with the appearance map is a lot faster, so that the recreation is no big deal...

Make those static is a bit over the top - the pointers will stay the same until the DLL is unloaded again, without a chance to alter them. In this case, it's enough if the treemodel is existing throughout the lifetime of the GuiSelector dialog. I also added the g_object_unref() to ensure that the treemodel is actually freed along with the treeview and the dialog.

 

The creation time of the GtkTreeStore* can probably be neglected, it's the GUI parsing which was taking up the most time.

 

Suggestion for the appearanceMap: We could omit the NO_READABLE entries, because we don't need them anyway. This would reduce searchtime and treestore creation time.

Yes, I'll do that.

Link to comment
Share on other sites

Ah damn, I just noticed that I use the NO_READABLE in the checkGuiLayout method of the ReadableEditorDialog, so it might be worth keeping those entries for proper error reporting. We could also extend the Enum with a FILE_NOT_FOUND and have that possibly returned by getGuiAppearance.

Link to comment
Share on other sites

Ok, will change that later then.

 

I just had a look at the PopupMenu class, because you wanted to have the ReadableEditor menus created with it. It is not applicable in our case, because we need a pointer to the ReadableEditorDialog for the userdata parameter. I guess the class could be extended though to allow adding menuitems with custom user data.

Link to comment
Share on other sites

Can you give me an overview about what is left to be done in the ReadableEditor domain? I'd like to have a rough plan with regards to the release of DarkRadiant 1.1.1 (or possibly 1.2.0, as the readable editor is a major feature).

Link to comment
Share on other sites

Scrolling back one page to copy my list of ideas: :)

  • Maybe add options to the DR preferences menu in which the user can specify in which folder xdata definitions are supposed to be stored.
  • Notify the user when he typed a character that is not available in the font.
  • Option to check syntax of a specified file.
  • Need to connect delete-events on Selectors, so that the return value is cleared.
  • We might want to think about integrating the Selectors into the EditorUi, because the preview would work better then.
  • Preview dependent:
    • Option to duplicate and freeze preview (for translators).
    • If the end of a page is reached in the preview, the editor should automatically jump to the next textView field.

 

Discovered a new issue with browsing and previewing XData yesterday. Runtime error after I clicked something. Gotta look into that maybe this evening. I don't know where that one came from.

 

And how far are you with your work? Is the preview of readables already precise? Because on most of them you have to skip a few lines on the body to allow proper writing. Is the script support done? If so, what do we do with it? :)

 

If everything up there is done or decided to be dropped, we could also try to fix the readable guis. If you check out the def-import summary in the tools menu, you'll notice some syntax errors and if you open the onesided-guibrowser you'll notice some books there, which are supposed to go in the twosided browser. Those only have one title set, instead of two.

Link to comment
Share on other sites

Maybe add options to the DR preferences menu in which the user can specify in which folder xdata definitions are supposed to be stored.

This is easy. There are a variety of examples in the initialiseModule() calls in case you need some sample code.

 

- Notify the user when he typed a character that is not available in the font.

- Option to check syntax of a specified file.

I'd postpone the first one for a later release. The user will notice anyhow, as the character doesn't show up in the readable.

 

Syntax-checking an xdata file? Sounds like an optional update for later releases too.

 

Need to connect delete-events on Selectors, so that the return value is cleared.

I can take care of this if you want me to. I assume the return string should always be empty in that case?

 

We might want to think about integrating the Selectors into the EditorUi, because the preview would work better then.

This could be difficult, because the lists are quite large.

 

Option to duplicate and freeze preview (for translators).

I think a specialised translation dialog could help here. Translation sounds like a different usage pattern to me.

 

If the end of a page is reached in the preview, the editor should automatically jump to the next textView field.

Hm, that's kind of difficult, because the Readable Editor just loads the values into the GUI state, without getting any feedback. I've been trying to design the GUIs as general-purpose as possible, and as closest to D3 GUIs as possible, such that it's easy to move these classes to another module without much effort. So adding specialised code (just for use in the Readable Editor) to the GUI classes is something I want to avoid, but maybe I can come up with some clean design.

 

One thing I noticed myself is that \n characters were not properly parsed by the DefTokeniser. Don't know if this is fixed already or still persistent.

 

Discovered a new issue with browsing and previewing XData yesterday. Runtime error after I clicked something. Gotta look into that maybe this evening. I don't know where that one came from.

I might have fixed that one this morning, not sure.

 

And how far are you with your work? Is the preview of readables already precise? Because on most of them you have to skip a few lines on the body to allow proper writing.

The preview is precise. The readables have been set up like this on purpose by Fidcal, so that it's easy to have full-page texts by leaving the title empty. The mapper is supposed to add a few line-breaks to the body if the page has a title.

 

Is the script support done? If so, what do we do with it? :)

The script support is very rudimentary, I just implemented the few statements needed to get the readables going. I think we're set for this first iteration, additions can follow later on.

 

If everything up there is done or decided to be dropped, we could also try to fix the readable guis. If you check out the def-import summary in the tools menu, you'll notice some syntax errors and if you open the onesided-guibrowser you'll notice some books there, which are supposed to go in the twosided browser. Those only have one title set, instead of two.

In the mid-term, we need a better way to determine one- or two-sidedness of the readables. The readable GUI system is much more flexible than what we provided anyway. It's very well possible to design readables with three titles and four body texts, the system is allowing that.

 

The readable script is pumping any data form the xdata/entity to the GUI state and the GUI code in the onTime event is then taking care of loading the values into the respective windowDef.

Link to comment
Share on other sites

I will do only little coding this weekend because I got an exam on monday. So just go ahead and do what you want... :)

 

I can take care of this if you want me to. I assume the return string should always be empty in that case?

Yes!

 

This could be difficult, because the lists are quite large.

Yes, but I was planning to toggle visibility of the edit pane in this case and replace it with the browsers until the user clicks 'cancel' or 'ok'. The default button panel should also be hidden...

 

I think a specialised translation dialog could help here. Translation sounds like a different usage pattern to me.

Yeah. Could also come with a later release.

 

One thing I noticed myself is that \n characters were not properly parsed by the DefTokeniser. Don't know if this is fixed already or still persistent.

I think you're referring to that one screenshot you posted, right? Well XData does not directly support \n anyway, so we don't need to worry about this.

 

I might have fixed that one this morning, not sure.

Yeah, you did. However, it still crashes occasionally for me. There seems to be wrong something else as well. Maybe an issue with my importer... It crashes on "readables/source_material/tdm_page" for instance.

 

In the mid-term, we need a better way to determine one- or two-sidedness of the readables. The readable GUI system is much more flexible than what we provided anyway. It's very well possible to design readables with three titles and four body texts, the system is allowing that.

In that case we should have the readable type detection performed by searching for the body statements and the right title textview should be grayed-out if such statement is not available in the gui to maintain compatibility with the current setup. The insert and delete methods for twosided readables would also have to be altered then.

 

I'd have to refactor the whole XData class and the XDataLoader to fully support the capabilities of the fileformat. That won't be much of a problem, but it would get really messy on the ReadableEditorDialog if we allow for unlimited XData support. I guess we should stick to the current setup and alter the existing gui definitions instead. After all readables basically just consist in titles and bodies (with paragraphs), one each per page.

 

Some further ideas/suggestions:

  • We should show a "definitions loading" screen similar to when the modelbrowser is opened. It always seems a little like DR is collapsing when you click on the guibrowser or press enter / leave focus on the gui entry.
  • This one is probably a little harder. The preview could still do with some tweaking. On the one hand it would be nice if the background was gray instead of black, so that it matches up with the interface, on the other hand it would be really swell if the displayed area of the guiView was cropped to the dimensions of the actual readable. This would especially be useful with reference to the translators dialog, because we could do with some more space there.

 

Edit: Woohoo, my first assignment in the bugtracker... ;)

Link to comment
Share on other sites

The GuiSelector is now adjusted to return "" except when the user is clicking OK. I also added a ModalProgressDialog to the walker class, so that the user can see what's going on.

 

Well XData does not directly support \n anyway, so we don't need to worry about this.

From my knowledge it's fine to use \n in the XData strings - I don't think there is another way of adding line breaks to xdata values.

 

Yeah, you did. However, it still crashes occasionally for me. There seems to be wrong something else as well. Maybe an issue with my importer... It crashes on "readables/source_material/tdm_page" for instance.

I'll check it out when I'll be adjusting the XDataSelector, this is still left to do.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Recent Status Updates

    • nbohr1more

      TDM 15th Anniversary Contest is now active! Please declare your participation: https://forums.thedarkmod.com/index.php?/topic/22413-the-dark-mod-15th-anniversary-contest-entry-thread/
       
      · 0 replies
    • JackFarmer

      @TheUnbeholden
      You cannot receive PMs. Could you please be so kind and check your mailbox if it is full (or maybe you switched off the function)?
      · 1 reply
    • OrbWeaver

      I like the new frob highlight but it would nice if it was less "flickery" while moving over objects (especially barred metal doors).
      · 4 replies
    • nbohr1more

      Please vote in the 15th Anniversary Contest Theme Poll
       
      · 0 replies
    • Ansome

      Well then, it's been about a week since I released my first FM and I must say that I was very pleasantly surprised by its reception. I had expected half as much interest in my short little FM as I received and even less when it came to positive feedback, but I am glad that the aspects of my mission that I put the most heart into were often the most appreciated. It was also delightful to read plenty of honest criticism and helpful feedback, as I've already been given plenty of useful pointers on improving my brushwork, level design, and gameplay difficulty.
      I've gotten back into the groove of chipping away at my reading and game list, as well as the endless FM catalogue here, but I may very well try my hand at the 15th anniversary contest should it materialize. That is assuming my eyes are ready for a few more months of Dark Radiant's bright interface while burning the midnight oil, of course!
      · 4 replies
×
×
  • Create New...