mudlet/src/TMap.cpp

2426 lines
94 KiB
C++
Raw Normal View History

2010-08-25 00:41:43 +02:00
/***************************************************************************
* Copyright (C) 2008-2013 by Heiko Koehn - KoehnHeiko@googlemail.com *
2017-04-16 22:33:35 -07:00
* Copyright (C) 2014-2017 by Ahmed Charles - acharles@outlook.com *
Enhance: add ability to set any glyph as a room symbol (#1543) This is a squashed down commit containing several commits with messages - this is the edited combination of all the messages: As well as being able to use any grapheme it is possible to use a short word as well as anything printable from any of the Unicode Multiple Planes; although the former will become smaller to fit within both the square and round room shapes on the 2D mapper. Adds controls to the profile preference to set the (preferred) font to use to set the room symbols from and a checkbox to only use that font. Additionally a sub-dialog can be brought up which lists the details of all the different symbols on the map - showing the Unicode codepoint(s) for each and showing how they would be rendered if only the selected font is used and if any font is permitted, along with a count of the usages and the rooms that use each one... A status icon is also displayed showing whether the symbol can be rendered entirely with the selected font (green tick), only by using glyphs from other fonts (yellow ! warning) or not with the current fonts on the system (red/white cross). This allows a user to make a sensible selection of a font to use or whether they will have a problem (and a replacement by the replacement character '�') for any symbols. Updates Lua setRoomChar and getRoomChar to handle the wider range of things that can be used. getRoomChar NOW allows for an existing character to be cleared with an empty string or a space as the char attribute. The map format version has been incremented to allow the data needed to be saved directly into the binary file format but failback code is in place that means that this feature can be carried in map and room user data instead for map format versions down to 17 - the current default is 18 and there is limited support to fail gracefully down to the 16 that Mudlet 2.1 uses (all the room letter markings that are not supported will become '?', and the font data will be lost, but the correct room character data will still be in the room user data.) Following review: * I replaced some colour specifications (white and transparent) with Qt constants. * Use the same inline function flushSymbolPixmapCache() to clear the map symbol pixmap cache in all places where it might be useful. * Simplify a couple of places where an if(...) {...} else {...} can be replaced with the (...) ? (...) : (...) operator. * Limit the number of room numbers displayed for each symbol in the new widget - to avoid complications where there are huge numbers of rooms using a symbol. * Replace a use of QTableWidget::clearContents() with QTableWidgets::setRowCount(0) as I was getting some odd, deep in the Qt internal library issues {Fatal Seg. Faults!} with the former, which I suspect, but could not prove, might have been a re-entrancy issue caused by the method containing it being called indirectly by an asynchronous SIGNAL/SLOT originating in the value change from the map symbol font selection QFontComboBox... Revised to NOT do scaling when drawing room symbols from cache: the previous QPainter::drawPixmap(...) performed a scaling operation to make the symbol pixmap fit the specified rectangle. This is the cause behind the poor rendering of text characters as the scaling undoes the benefits of anti-aliasing and takes time to do. This should be faster now because the pixmaps are generated at the size/resolution they are needed (though they do have to be thrown away and regenerated if the zoom or other sizing factors change) - they do however look better to me! Also: * merged (int) TRoom::xzoom and TRoom::yzoom into TRoom::xyzoom. * added the symbol scaling "fudge-factor" to the "Special Options" tab of the "Profile preferences" dialog - it may be helpful to artificially over-size (> 1.00) or under-size (< 1.00) the symbols in some situations. * uses the word symbol rather than just glyph/grapheme in some texts. Also modified 2D mapper "Symbol" tooltip to observe that more than one letter/symbol can be used (although they will be drawn smaller so that they still fit). Add tool-tips to profile preferences dialog for font controls (except for "fudge factor" control (with range x0.50 to x2.00 for scaling of symbol to test rectangle used to fit it into the room shape)... I have consistently mispelled chosen as choosen but I have fixed that now...! Also added tooltips to map glyph usage table/widget. WorkAround: try to force a specific US mirror for zziplib on AppVeyor CI AppVeyor is based in Vancouver, Canada so the nearest SF Mirror is in the US so this commit forces the use of that mirror for that library for the CI build process as an attempt to get around the repeated, intermittent failures to get that library from SourceForge (it is now the only item that needs to be downloaded from there for such builds)... Also adds another CI file that was not mentioned before in the qmake project file and thus did not show up in the Qt IDE. Following extensive discussions it has been made clear that introducing replacements for the lua [gs]etRoomChar(...) is not going to happen. Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2018-03-28 14:06:12 +01:00
* Copyright (C) 2014-2018 by Stephen Lyons - slysven@virginmedia.com *
2010-08-25 00:41:43 +02:00
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#include "TMap.h"
#include "Host.h"
#include "TArea.h"
#include "TConsole.h"
Enhance: fix map downloading code, add manual XML map importing (#326) * Enhance: fix map downloading code, add manual XML map importing A recent move by I.R.E. to using SSL for their public MUD map URLs broke the ability for Mudlet to download those XML format files. This commit addresses this issue (as mentioned in, but not the original problem referred to in https://bugs.launchpad.net/mudlet/+bug/1427364) the revision to the code does now use "https://www.<MUD URL>/maps/map.xml" as a default name for the I.R.E. MUDS - however the method that initiates the download which was moved to TMap class from the dlgMapper one (see below) is now: (bool) TMap::downloadMap( const QString * remoteUrl = Q_NULLPTR, const QString * localFileName = Q_NULLPTR ) which if not supplied with any arguments behaves as before. However the remoteUrl argument may be given as a full QString including the scheme (the bit of the URL at the beginning before the ':') to override that and a second argument may be used to provide a different name to use for the local file name which if is a RELATIVE pathFileName will be resolved in relation to the profile directory. At present no use is made of this additional functionality but it may be useful for use with other MUDs if they should choose to provide XML map files with other remote locations and scripts using a different local filename. As a long-standing thing that needed doing I have finally provided a means to import a map XML file that - for instance - has already been download. It had been noted that there was no way to read those I.R.E. map files even if they had been obtained from a web browser able to correctly handle https: URLs - now both the TLuaInterpreter::loadMap() and the dlgProfilePreference "loadMap" button {NOT the IRE only "map download" one} will both handle files ending in ".xml" (not case sensitive so it'll work MacOS platforms as well!} For the loadMap case it will be necessary to change the filetype filter on the File Selection dialog to select "xml" files. During testing it became clear to me that it was possible to try and read one or more XML files via several mechanisms simultaneously with "unhelpful" consequences. As well as hitting the dlgProfilePreferences IRE "map download" multiple times, the TLuaInterpreter::loadMap() does NOT block until the map has been loaded and as the import time {running of XMLinport::readPackage(...)} is of significant duration for a large map (a debug, without optimisation, build on my 1.8GHz Quad-core took over two minutes to process the current Achaea map file) it is very possible to get conditions where the same profile will try to run XMLinport::readPackage(...) asynchronously - given that a profile only supports ONE map at a time it was necessary to fit a QMutex to prevent the part of the XMLinport class relating to XML Map files being called from different places in the map related code. This means that if a map download is started further downloads and any local map imports will fail until that first download has completed or aborted. Similarly a local import will prevent a download being started. As a side effect this cures: https://bugs.launchpad.net/mudlet/+bug/852861 - "Map download button starts another download thread if one is already going" The previous XML import code was not adding the rooms that it parsed to the relevant TArea::rooms member - although this would be picked-up and fixed by TMap::audit() later on, this would be accompanied by an error message about every single room. The code now builds up this information while parsing the rooms' details and inserts it so that this does not cause report-able problems during the TMap::audit() execution - the data gathered also allows missing areas to be spotted so that if a room claimed to belong to an area that was not included in the preceding areas' data an unnamed area is created for it. As a consequence of the long time to actually parse an XML map file I have enhanced the progress dialog that was originally used to track the map file download. It is now retained until the file is completely imported and shows more information about the process - importantly it shows during the XMLimport::readRoom(...) the room id being processed - and THAT method is the time/cpu hog so seeing something happening during the time that Mudlet otherwise appears to hang is useful feedback even if it adds a few seconds to the overall duration (may be more than a minute). This dialog is now also used during the other routes that involve reading an XML file and there is now a bit of consistence with the on-screen messages. Whilst inspecting XMLimport class I found there was some uncertain initialisation which I have tidied up. In summary: Added: * (bool) TConsole::importMap(const QString & location) * (void) TRoomDB::setAreaRooms(const int areaId, const QSet<int> & roomIds) * image file mudlet_map_download.png used as icon for download/import progress dialog * (bool) TMap::importMap(QFile & file) * (bool) TMap::readXmlMapFile(QFile & file) * (void) TMap::slot_downloadError(QNetworkReply::NetworkError error) * (void) TMap::reportStringToProgressDialog(const QString text) * (void) TMap::reportProgressToProgressDialog(const int current, const int maximum) Revised: * (int)TLuaInterpreter::loadMap( lua_State * ) * Moved XML map download code from dlgMapper class to the TMap one: + (void) dlgMapper::downloadMap() ==> (bool) TMap::downloadMap(const QString * remoteUrl, const QString * localFileName) + (void) dlgMapper::setDownloadProgress(qint64, qint64) ==> (void) TMap::slot_setDownloadProgress(qint64,qint64) + (void) dlgMapper::cancel() ==> (void) TMap::slot_downloadCancel() + (void) dlgMapper::replyFinished(QNetworkReply *) ==> (void) TMap::slot_replyFinished(QNetworkReply *) * Enhanced download progress indication to also include parsing which can take even more time than download! * Provide means to import local XML map file * Prevent trying to import/download more than one map at a time Renamed: * (void) XMLimport::readAreaNames() ==> XMLimport::readArea() - for consistency with related functions Commented out unused: * (void) XMLimport::readUnknownRoomElement() Note the movement of the map file download code to the TMap class does require making the latter a class with the Q_OBJECT macro (which removes the need for Q_DECLARE_TR_FUNCTIONS as a side-effect!) - though as another side-effect the TMap header needed a boost name specifier added to one identifier as that identifier ("property") exists in both boost and QObject classes!!! YOU MAY NEED TO RUN QMAKE ON THE PROJECT IF THE BUILD SYSTEM DOES NOT PICK UP THE ADDITION OF "Q_OBJECT" TO TMAP CLASS. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: Include missing #include, remove unused return value The absence of this was causing build errors on the Travis C.I. platform! Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: move TMap.h to mudlet_MOC_HDRS to fix CMake build issue As we have made TMap inherit from QOject - to have signal/slot functionality that class needs to be run through Qt's MOC - and to do that with the CMake project/build system it needs to be included in the files included in the projects *_MOC_HDRS {and removed from the *_HDRS} variable. Also spotted a trivial error in that specifying a const return value from method is ineffective and pointless - so removed it from: TMap::retrieveMapFileStats(QString,QString *,int *,int *,int *,int *) Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: clean up TMap initialisation/clearing actions Now restores the customEnvColors set up on initialisation but that was cleared when the map replaced with another one that is loaded {which subsequently replaces that element anyway} or imported {which merely writes over it, replacing any matching keys}. Initialises elements that when inspected on the entry to the constructor proper previously were not being set to a consistent value {booleans/ints/floats}. NOTE: This will now clear the map user data member when the map is cleared if the date is required to be saved when one map is loaded OR IMPORTED over an existing one then the data will need to be saved outside of the map - as is already need for areas and rooms user data! Also comment out or remove unused members/methods: * (void) TMap::getConnectedNodesGreaterThanX(int, int) * (void) TMap::getConnectedNodesSmallerThanX(int, int) * (void) TMap::getConnectedNodesGreaterThanY(int, int) * (void) TMap::getConnectedNodesSmallerThanY(int, int) * (void) TMap::astBreitenAnpassung(int, int) * (void) TMap::astHoehenAnpassung(int, int) * (void) TMap::exportMapToDatabase() * (void) TMap::importMapFromDatabase() * (QVector3D) TMap::span * (int) TMap::mViewArea * (QMap<QString, int>) TMap::pixNameTable * (QMap<int, QPixmap>) TMap::pixTable * (bool) TMap::isToDisplayAuditErrorsToConsole Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * ImplimentationFixes: activate a valid optimisation & remove redundant code Adding a true as a non-default 3rd argument to TRoomDB::addRoom(...) call in XMLimport::readRoom(...) enables a significant optimisation (skips a computationally expensive step when ADDING a room to new map) which dramatically reduces the time to parse an XML map file. It also pointed to the fact that the TRoomDB::entranceMap was already correctly being handled and didn't need to be regenerated in XMLimport::readRoom(...) so the code that was added in a previous commit was redundant and could be removed. A code error in TMap::slot_setDownloadProgress(...) that caused an issue that a reviewer found on test has been fixed - the total download filesize that was being sent by the Qt system signal that is connected to this slot was a -1 value (as IS DOCUMENTED) when the Qt system does NOT know the size of a QNetworkReply in advance of reaching the end of the download was incorrectly handled in a previous commit in this change set. Also found during testing that there is no need for an error message for the QNetworkReply::OperationCanceledError case in TMap::slot_replayFinished(...) as it is already handled in the TMap::slot_downloadCancel() slot. Changed the text put up onto the progress widget during the XML room parsing to be a room count - which is likely more useful and to only do it for every hundredth room - which reduces any delay "wasted" in writing to the display - combined, the effects seem satisfactory IMHO. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: provide error messages for TLuaInterpreter::loadMap(...) Errors for the XML map file importing process as initiated from the Lua command should be returned to that command rather than plastered onto the main profile console - this commit attempts to perform that effect. In testing found that there was no error handling for failure to find or open the nominated file so messages for that have been added as well. Due to the previous program logic the action of creating a mapper widget using the main toolbar button automatically loaded the "default" (the newest Mudlet Map file format file from the currently active profile's map sub-directory). Under some previous situations it looked as though a map might be loaded twice as mudlet::slot_mapper() was called both directly and via signal/slot action. These were resolved by turning that slot into a wrapper that now calls the body of code formerly within to a new method mudlet::createMapper( bool isToLoadDefaultMapFile = true ) with a the default value as an argument. This allows other usages of the body of code to be called directly with a suitable argument, which for the TConsole::loadMap() & TConsole::importMap() and the dlgProfilePreferences::downloadMap() cases is false as they are all do not want the "default" map! Also: * spotted a word "area" missing from an advisory text in TRoom::auditRooms(...). Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: fix minor bug, correct a spelling, undo a few capitalisations Under certain, unanticipated (error with no error message) conditions TLuaInterpreter::loadMap(...) would push both a nil and then a false value onto the stack for return {wrong} but only indicate one value {correct}. The textual matters were found during peer review. off-by: Stephen Lyons <slysven@virginmedia.com>
2016-10-13 09:18:48 +01:00
#include "TEvent.h"
#include "TRoomDB.h"
Enhance: fix map downloading code, add manual XML map importing (#326) * Enhance: fix map downloading code, add manual XML map importing A recent move by I.R.E. to using SSL for their public MUD map URLs broke the ability for Mudlet to download those XML format files. This commit addresses this issue (as mentioned in, but not the original problem referred to in https://bugs.launchpad.net/mudlet/+bug/1427364) the revision to the code does now use "https://www.<MUD URL>/maps/map.xml" as a default name for the I.R.E. MUDS - however the method that initiates the download which was moved to TMap class from the dlgMapper one (see below) is now: (bool) TMap::downloadMap( const QString * remoteUrl = Q_NULLPTR, const QString * localFileName = Q_NULLPTR ) which if not supplied with any arguments behaves as before. However the remoteUrl argument may be given as a full QString including the scheme (the bit of the URL at the beginning before the ':') to override that and a second argument may be used to provide a different name to use for the local file name which if is a RELATIVE pathFileName will be resolved in relation to the profile directory. At present no use is made of this additional functionality but it may be useful for use with other MUDs if they should choose to provide XML map files with other remote locations and scripts using a different local filename. As a long-standing thing that needed doing I have finally provided a means to import a map XML file that - for instance - has already been download. It had been noted that there was no way to read those I.R.E. map files even if they had been obtained from a web browser able to correctly handle https: URLs - now both the TLuaInterpreter::loadMap() and the dlgProfilePreference "loadMap" button {NOT the IRE only "map download" one} will both handle files ending in ".xml" (not case sensitive so it'll work MacOS platforms as well!} For the loadMap case it will be necessary to change the filetype filter on the File Selection dialog to select "xml" files. During testing it became clear to me that it was possible to try and read one or more XML files via several mechanisms simultaneously with "unhelpful" consequences. As well as hitting the dlgProfilePreferences IRE "map download" multiple times, the TLuaInterpreter::loadMap() does NOT block until the map has been loaded and as the import time {running of XMLinport::readPackage(...)} is of significant duration for a large map (a debug, without optimisation, build on my 1.8GHz Quad-core took over two minutes to process the current Achaea map file) it is very possible to get conditions where the same profile will try to run XMLinport::readPackage(...) asynchronously - given that a profile only supports ONE map at a time it was necessary to fit a QMutex to prevent the part of the XMLinport class relating to XML Map files being called from different places in the map related code. This means that if a map download is started further downloads and any local map imports will fail until that first download has completed or aborted. Similarly a local import will prevent a download being started. As a side effect this cures: https://bugs.launchpad.net/mudlet/+bug/852861 - "Map download button starts another download thread if one is already going" The previous XML import code was not adding the rooms that it parsed to the relevant TArea::rooms member - although this would be picked-up and fixed by TMap::audit() later on, this would be accompanied by an error message about every single room. The code now builds up this information while parsing the rooms' details and inserts it so that this does not cause report-able problems during the TMap::audit() execution - the data gathered also allows missing areas to be spotted so that if a room claimed to belong to an area that was not included in the preceding areas' data an unnamed area is created for it. As a consequence of the long time to actually parse an XML map file I have enhanced the progress dialog that was originally used to track the map file download. It is now retained until the file is completely imported and shows more information about the process - importantly it shows during the XMLimport::readRoom(...) the room id being processed - and THAT method is the time/cpu hog so seeing something happening during the time that Mudlet otherwise appears to hang is useful feedback even if it adds a few seconds to the overall duration (may be more than a minute). This dialog is now also used during the other routes that involve reading an XML file and there is now a bit of consistence with the on-screen messages. Whilst inspecting XMLimport class I found there was some uncertain initialisation which I have tidied up. In summary: Added: * (bool) TConsole::importMap(const QString & location) * (void) TRoomDB::setAreaRooms(const int areaId, const QSet<int> & roomIds) * image file mudlet_map_download.png used as icon for download/import progress dialog * (bool) TMap::importMap(QFile & file) * (bool) TMap::readXmlMapFile(QFile & file) * (void) TMap::slot_downloadError(QNetworkReply::NetworkError error) * (void) TMap::reportStringToProgressDialog(const QString text) * (void) TMap::reportProgressToProgressDialog(const int current, const int maximum) Revised: * (int)TLuaInterpreter::loadMap( lua_State * ) * Moved XML map download code from dlgMapper class to the TMap one: + (void) dlgMapper::downloadMap() ==> (bool) TMap::downloadMap(const QString * remoteUrl, const QString * localFileName) + (void) dlgMapper::setDownloadProgress(qint64, qint64) ==> (void) TMap::slot_setDownloadProgress(qint64,qint64) + (void) dlgMapper::cancel() ==> (void) TMap::slot_downloadCancel() + (void) dlgMapper::replyFinished(QNetworkReply *) ==> (void) TMap::slot_replyFinished(QNetworkReply *) * Enhanced download progress indication to also include parsing which can take even more time than download! * Provide means to import local XML map file * Prevent trying to import/download more than one map at a time Renamed: * (void) XMLimport::readAreaNames() ==> XMLimport::readArea() - for consistency with related functions Commented out unused: * (void) XMLimport::readUnknownRoomElement() Note the movement of the map file download code to the TMap class does require making the latter a class with the Q_OBJECT macro (which removes the need for Q_DECLARE_TR_FUNCTIONS as a side-effect!) - though as another side-effect the TMap header needed a boost name specifier added to one identifier as that identifier ("property") exists in both boost and QObject classes!!! YOU MAY NEED TO RUN QMAKE ON THE PROJECT IF THE BUILD SYSTEM DOES NOT PICK UP THE ADDITION OF "Q_OBJECT" TO TMAP CLASS. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: Include missing #include, remove unused return value The absence of this was causing build errors on the Travis C.I. platform! Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: move TMap.h to mudlet_MOC_HDRS to fix CMake build issue As we have made TMap inherit from QOject - to have signal/slot functionality that class needs to be run through Qt's MOC - and to do that with the CMake project/build system it needs to be included in the files included in the projects *_MOC_HDRS {and removed from the *_HDRS} variable. Also spotted a trivial error in that specifying a const return value from method is ineffective and pointless - so removed it from: TMap::retrieveMapFileStats(QString,QString *,int *,int *,int *,int *) Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: clean up TMap initialisation/clearing actions Now restores the customEnvColors set up on initialisation but that was cleared when the map replaced with another one that is loaded {which subsequently replaces that element anyway} or imported {which merely writes over it, replacing any matching keys}. Initialises elements that when inspected on the entry to the constructor proper previously were not being set to a consistent value {booleans/ints/floats}. NOTE: This will now clear the map user data member when the map is cleared if the date is required to be saved when one map is loaded OR IMPORTED over an existing one then the data will need to be saved outside of the map - as is already need for areas and rooms user data! Also comment out or remove unused members/methods: * (void) TMap::getConnectedNodesGreaterThanX(int, int) * (void) TMap::getConnectedNodesSmallerThanX(int, int) * (void) TMap::getConnectedNodesGreaterThanY(int, int) * (void) TMap::getConnectedNodesSmallerThanY(int, int) * (void) TMap::astBreitenAnpassung(int, int) * (void) TMap::astHoehenAnpassung(int, int) * (void) TMap::exportMapToDatabase() * (void) TMap::importMapFromDatabase() * (QVector3D) TMap::span * (int) TMap::mViewArea * (QMap<QString, int>) TMap::pixNameTable * (QMap<int, QPixmap>) TMap::pixTable * (bool) TMap::isToDisplayAuditErrorsToConsole Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * ImplimentationFixes: activate a valid optimisation & remove redundant code Adding a true as a non-default 3rd argument to TRoomDB::addRoom(...) call in XMLimport::readRoom(...) enables a significant optimisation (skips a computationally expensive step when ADDING a room to new map) which dramatically reduces the time to parse an XML map file. It also pointed to the fact that the TRoomDB::entranceMap was already correctly being handled and didn't need to be regenerated in XMLimport::readRoom(...) so the code that was added in a previous commit was redundant and could be removed. A code error in TMap::slot_setDownloadProgress(...) that caused an issue that a reviewer found on test has been fixed - the total download filesize that was being sent by the Qt system signal that is connected to this slot was a -1 value (as IS DOCUMENTED) when the Qt system does NOT know the size of a QNetworkReply in advance of reaching the end of the download was incorrectly handled in a previous commit in this change set. Also found during testing that there is no need for an error message for the QNetworkReply::OperationCanceledError case in TMap::slot_replayFinished(...) as it is already handled in the TMap::slot_downloadCancel() slot. Changed the text put up onto the progress widget during the XML room parsing to be a room count - which is likely more useful and to only do it for every hundredth room - which reduces any delay "wasted" in writing to the display - combined, the effects seem satisfactory IMHO. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: provide error messages for TLuaInterpreter::loadMap(...) Errors for the XML map file importing process as initiated from the Lua command should be returned to that command rather than plastered onto the main profile console - this commit attempts to perform that effect. In testing found that there was no error handling for failure to find or open the nominated file so messages for that have been added as well. Due to the previous program logic the action of creating a mapper widget using the main toolbar button automatically loaded the "default" (the newest Mudlet Map file format file from the currently active profile's map sub-directory). Under some previous situations it looked as though a map might be loaded twice as mudlet::slot_mapper() was called both directly and via signal/slot action. These were resolved by turning that slot into a wrapper that now calls the body of code formerly within to a new method mudlet::createMapper( bool isToLoadDefaultMapFile = true ) with a the default value as an argument. This allows other usages of the body of code to be called directly with a suitable argument, which for the TConsole::loadMap() & TConsole::importMap() and the dlgProfilePreferences::downloadMap() cases is false as they are all do not want the "default" map! Also: * spotted a word "area" missing from an advisory text in TRoom::auditRooms(...). Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: fix minor bug, correct a spelling, undo a few capitalisations Under certain, unanticipated (error with no error message) conditions TLuaInterpreter::loadMap(...) would push both a nil and then a false value onto the stack for return {wrong} but only indicate one value {correct}. The textual matters were found during peer review. off-by: Stephen Lyons <slysven@virginmedia.com>
2016-10-13 09:18:48 +01:00
#include "XMLimport.h"
2017-04-14 00:40:02 -07:00
#include "dlgMapper.h"
#include "dlgTriggerEditor.h"
#include "mudlet.h"
#include "pre_guard.h"
#include <QElapsedTimer>
#include <QFileDialog>
#include <QMessageBox>
Enhance: fix map downloading code, add manual XML map importing (#326) * Enhance: fix map downloading code, add manual XML map importing A recent move by I.R.E. to using SSL for their public MUD map URLs broke the ability for Mudlet to download those XML format files. This commit addresses this issue (as mentioned in, but not the original problem referred to in https://bugs.launchpad.net/mudlet/+bug/1427364) the revision to the code does now use "https://www.<MUD URL>/maps/map.xml" as a default name for the I.R.E. MUDS - however the method that initiates the download which was moved to TMap class from the dlgMapper one (see below) is now: (bool) TMap::downloadMap( const QString * remoteUrl = Q_NULLPTR, const QString * localFileName = Q_NULLPTR ) which if not supplied with any arguments behaves as before. However the remoteUrl argument may be given as a full QString including the scheme (the bit of the URL at the beginning before the ':') to override that and a second argument may be used to provide a different name to use for the local file name which if is a RELATIVE pathFileName will be resolved in relation to the profile directory. At present no use is made of this additional functionality but it may be useful for use with other MUDs if they should choose to provide XML map files with other remote locations and scripts using a different local filename. As a long-standing thing that needed doing I have finally provided a means to import a map XML file that - for instance - has already been download. It had been noted that there was no way to read those I.R.E. map files even if they had been obtained from a web browser able to correctly handle https: URLs - now both the TLuaInterpreter::loadMap() and the dlgProfilePreference "loadMap" button {NOT the IRE only "map download" one} will both handle files ending in ".xml" (not case sensitive so it'll work MacOS platforms as well!} For the loadMap case it will be necessary to change the filetype filter on the File Selection dialog to select "xml" files. During testing it became clear to me that it was possible to try and read one or more XML files via several mechanisms simultaneously with "unhelpful" consequences. As well as hitting the dlgProfilePreferences IRE "map download" multiple times, the TLuaInterpreter::loadMap() does NOT block until the map has been loaded and as the import time {running of XMLinport::readPackage(...)} is of significant duration for a large map (a debug, without optimisation, build on my 1.8GHz Quad-core took over two minutes to process the current Achaea map file) it is very possible to get conditions where the same profile will try to run XMLinport::readPackage(...) asynchronously - given that a profile only supports ONE map at a time it was necessary to fit a QMutex to prevent the part of the XMLinport class relating to XML Map files being called from different places in the map related code. This means that if a map download is started further downloads and any local map imports will fail until that first download has completed or aborted. Similarly a local import will prevent a download being started. As a side effect this cures: https://bugs.launchpad.net/mudlet/+bug/852861 - "Map download button starts another download thread if one is already going" The previous XML import code was not adding the rooms that it parsed to the relevant TArea::rooms member - although this would be picked-up and fixed by TMap::audit() later on, this would be accompanied by an error message about every single room. The code now builds up this information while parsing the rooms' details and inserts it so that this does not cause report-able problems during the TMap::audit() execution - the data gathered also allows missing areas to be spotted so that if a room claimed to belong to an area that was not included in the preceding areas' data an unnamed area is created for it. As a consequence of the long time to actually parse an XML map file I have enhanced the progress dialog that was originally used to track the map file download. It is now retained until the file is completely imported and shows more information about the process - importantly it shows during the XMLimport::readRoom(...) the room id being processed - and THAT method is the time/cpu hog so seeing something happening during the time that Mudlet otherwise appears to hang is useful feedback even if it adds a few seconds to the overall duration (may be more than a minute). This dialog is now also used during the other routes that involve reading an XML file and there is now a bit of consistence with the on-screen messages. Whilst inspecting XMLimport class I found there was some uncertain initialisation which I have tidied up. In summary: Added: * (bool) TConsole::importMap(const QString & location) * (void) TRoomDB::setAreaRooms(const int areaId, const QSet<int> & roomIds) * image file mudlet_map_download.png used as icon for download/import progress dialog * (bool) TMap::importMap(QFile & file) * (bool) TMap::readXmlMapFile(QFile & file) * (void) TMap::slot_downloadError(QNetworkReply::NetworkError error) * (void) TMap::reportStringToProgressDialog(const QString text) * (void) TMap::reportProgressToProgressDialog(const int current, const int maximum) Revised: * (int)TLuaInterpreter::loadMap( lua_State * ) * Moved XML map download code from dlgMapper class to the TMap one: + (void) dlgMapper::downloadMap() ==> (bool) TMap::downloadMap(const QString * remoteUrl, const QString * localFileName) + (void) dlgMapper::setDownloadProgress(qint64, qint64) ==> (void) TMap::slot_setDownloadProgress(qint64,qint64) + (void) dlgMapper::cancel() ==> (void) TMap::slot_downloadCancel() + (void) dlgMapper::replyFinished(QNetworkReply *) ==> (void) TMap::slot_replyFinished(QNetworkReply *) * Enhanced download progress indication to also include parsing which can take even more time than download! * Provide means to import local XML map file * Prevent trying to import/download more than one map at a time Renamed: * (void) XMLimport::readAreaNames() ==> XMLimport::readArea() - for consistency with related functions Commented out unused: * (void) XMLimport::readUnknownRoomElement() Note the movement of the map file download code to the TMap class does require making the latter a class with the Q_OBJECT macro (which removes the need for Q_DECLARE_TR_FUNCTIONS as a side-effect!) - though as another side-effect the TMap header needed a boost name specifier added to one identifier as that identifier ("property") exists in both boost and QObject classes!!! YOU MAY NEED TO RUN QMAKE ON THE PROJECT IF THE BUILD SYSTEM DOES NOT PICK UP THE ADDITION OF "Q_OBJECT" TO TMAP CLASS. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: Include missing #include, remove unused return value The absence of this was causing build errors on the Travis C.I. platform! Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: move TMap.h to mudlet_MOC_HDRS to fix CMake build issue As we have made TMap inherit from QOject - to have signal/slot functionality that class needs to be run through Qt's MOC - and to do that with the CMake project/build system it needs to be included in the files included in the projects *_MOC_HDRS {and removed from the *_HDRS} variable. Also spotted a trivial error in that specifying a const return value from method is ineffective and pointless - so removed it from: TMap::retrieveMapFileStats(QString,QString *,int *,int *,int *,int *) Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: clean up TMap initialisation/clearing actions Now restores the customEnvColors set up on initialisation but that was cleared when the map replaced with another one that is loaded {which subsequently replaces that element anyway} or imported {which merely writes over it, replacing any matching keys}. Initialises elements that when inspected on the entry to the constructor proper previously were not being set to a consistent value {booleans/ints/floats}. NOTE: This will now clear the map user data member when the map is cleared if the date is required to be saved when one map is loaded OR IMPORTED over an existing one then the data will need to be saved outside of the map - as is already need for areas and rooms user data! Also comment out or remove unused members/methods: * (void) TMap::getConnectedNodesGreaterThanX(int, int) * (void) TMap::getConnectedNodesSmallerThanX(int, int) * (void) TMap::getConnectedNodesGreaterThanY(int, int) * (void) TMap::getConnectedNodesSmallerThanY(int, int) * (void) TMap::astBreitenAnpassung(int, int) * (void) TMap::astHoehenAnpassung(int, int) * (void) TMap::exportMapToDatabase() * (void) TMap::importMapFromDatabase() * (QVector3D) TMap::span * (int) TMap::mViewArea * (QMap<QString, int>) TMap::pixNameTable * (QMap<int, QPixmap>) TMap::pixTable * (bool) TMap::isToDisplayAuditErrorsToConsole Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * ImplimentationFixes: activate a valid optimisation & remove redundant code Adding a true as a non-default 3rd argument to TRoomDB::addRoom(...) call in XMLimport::readRoom(...) enables a significant optimisation (skips a computationally expensive step when ADDING a room to new map) which dramatically reduces the time to parse an XML map file. It also pointed to the fact that the TRoomDB::entranceMap was already correctly being handled and didn't need to be regenerated in XMLimport::readRoom(...) so the code that was added in a previous commit was redundant and could be removed. A code error in TMap::slot_setDownloadProgress(...) that caused an issue that a reviewer found on test has been fixed - the total download filesize that was being sent by the Qt system signal that is connected to this slot was a -1 value (as IS DOCUMENTED) when the Qt system does NOT know the size of a QNetworkReply in advance of reaching the end of the download was incorrectly handled in a previous commit in this change set. Also found during testing that there is no need for an error message for the QNetworkReply::OperationCanceledError case in TMap::slot_replayFinished(...) as it is already handled in the TMap::slot_downloadCancel() slot. Changed the text put up onto the progress widget during the XML room parsing to be a room count - which is likely more useful and to only do it for every hundredth room - which reduces any delay "wasted" in writing to the display - combined, the effects seem satisfactory IMHO. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: provide error messages for TLuaInterpreter::loadMap(...) Errors for the XML map file importing process as initiated from the Lua command should be returned to that command rather than plastered onto the main profile console - this commit attempts to perform that effect. In testing found that there was no error handling for failure to find or open the nominated file so messages for that have been added as well. Due to the previous program logic the action of creating a mapper widget using the main toolbar button automatically loaded the "default" (the newest Mudlet Map file format file from the currently active profile's map sub-directory). Under some previous situations it looked as though a map might be loaded twice as mudlet::slot_mapper() was called both directly and via signal/slot action. These were resolved by turning that slot into a wrapper that now calls the body of code formerly within to a new method mudlet::createMapper( bool isToLoadDefaultMapFile = true ) with a the default value as an argument. This allows other usages of the body of code to be called directly with a suitable argument, which for the TConsole::loadMap() & TConsole::importMap() and the dlgProfilePreferences::downloadMap() cases is false as they are all do not want the "default" map! Also: * spotted a word "area" missing from an advisory text in TRoom::auditRooms(...). Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: fix minor bug, correct a spelling, undo a few capitalisations Under certain, unanticipated (error with no error message) conditions TLuaInterpreter::loadMap(...) would push both a nil and then a false value onto the stack for return {wrong} but only indicate one value {correct}. The textual matters were found during peer review. off-by: Stephen Lyons <slysven@virginmedia.com>
2016-10-13 09:18:48 +01:00
#include <QProgressDialog>
#include "post_guard.h"
2010-08-25 00:41:43 +02:00
TMap::TMap(Host* pH)
: mpRoomDB(new TRoomDB(this))
, mpHost(pH)
, m2DPanMode(false)
, mLeftDown(false)
, mRightDown(false)
, m2DPanXStart(0.0f)
, m2DPanYStart(0.0f)
, mTargetID(0)
, mpM(Q_NULLPTR)
, mpMapper(Q_NULLPTR)
, mMapGraphNeedsUpdate(true)
, mNewMove(true)
// default map version that new maps will get
, mDefaultVersion(18)
// maximum version of the map format that this Mudlet can understand and will
// allow the user to load
Enhance: add ability to set any glyph as a room symbol (#1543) This is a squashed down commit containing several commits with messages - this is the edited combination of all the messages: As well as being able to use any grapheme it is possible to use a short word as well as anything printable from any of the Unicode Multiple Planes; although the former will become smaller to fit within both the square and round room shapes on the 2D mapper. Adds controls to the profile preference to set the (preferred) font to use to set the room symbols from and a checkbox to only use that font. Additionally a sub-dialog can be brought up which lists the details of all the different symbols on the map - showing the Unicode codepoint(s) for each and showing how they would be rendered if only the selected font is used and if any font is permitted, along with a count of the usages and the rooms that use each one... A status icon is also displayed showing whether the symbol can be rendered entirely with the selected font (green tick), only by using glyphs from other fonts (yellow ! warning) or not with the current fonts on the system (red/white cross). This allows a user to make a sensible selection of a font to use or whether they will have a problem (and a replacement by the replacement character '�') for any symbols. Updates Lua setRoomChar and getRoomChar to handle the wider range of things that can be used. getRoomChar NOW allows for an existing character to be cleared with an empty string or a space as the char attribute. The map format version has been incremented to allow the data needed to be saved directly into the binary file format but failback code is in place that means that this feature can be carried in map and room user data instead for map format versions down to 17 - the current default is 18 and there is limited support to fail gracefully down to the 16 that Mudlet 2.1 uses (all the room letter markings that are not supported will become '?', and the font data will be lost, but the correct room character data will still be in the room user data.) Following review: * I replaced some colour specifications (white and transparent) with Qt constants. * Use the same inline function flushSymbolPixmapCache() to clear the map symbol pixmap cache in all places where it might be useful. * Simplify a couple of places where an if(...) {...} else {...} can be replaced with the (...) ? (...) : (...) operator. * Limit the number of room numbers displayed for each symbol in the new widget - to avoid complications where there are huge numbers of rooms using a symbol. * Replace a use of QTableWidget::clearContents() with QTableWidgets::setRowCount(0) as I was getting some odd, deep in the Qt internal library issues {Fatal Seg. Faults!} with the former, which I suspect, but could not prove, might have been a re-entrancy issue caused by the method containing it being called indirectly by an asynchronous SIGNAL/SLOT originating in the value change from the map symbol font selection QFontComboBox... Revised to NOT do scaling when drawing room symbols from cache: the previous QPainter::drawPixmap(...) performed a scaling operation to make the symbol pixmap fit the specified rectangle. This is the cause behind the poor rendering of text characters as the scaling undoes the benefits of anti-aliasing and takes time to do. This should be faster now because the pixmaps are generated at the size/resolution they are needed (though they do have to be thrown away and regenerated if the zoom or other sizing factors change) - they do however look better to me! Also: * merged (int) TRoom::xzoom and TRoom::yzoom into TRoom::xyzoom. * added the symbol scaling "fudge-factor" to the "Special Options" tab of the "Profile preferences" dialog - it may be helpful to artificially over-size (> 1.00) or under-size (< 1.00) the symbols in some situations. * uses the word symbol rather than just glyph/grapheme in some texts. Also modified 2D mapper "Symbol" tooltip to observe that more than one letter/symbol can be used (although they will be drawn smaller so that they still fit). Add tool-tips to profile preferences dialog for font controls (except for "fudge factor" control (with range x0.50 to x2.00 for scaling of symbol to test rectangle used to fit it into the room shape)... I have consistently mispelled chosen as choosen but I have fixed that now...! Also added tooltips to map glyph usage table/widget. WorkAround: try to force a specific US mirror for zziplib on AppVeyor CI AppVeyor is based in Vancouver, Canada so the nearest SF Mirror is in the US so this commit forces the use of that mirror for that library for the CI build process as an attempt to get around the repeated, intermittent failures to get that library from SourceForge (it is now the only item that needs to be downloaded from there for such builds)... Also adds another CI file that was not mentioned before in the qmake project file and thus did not show up in the Qt IDE. Following extensive discussions it has been made clear that introducing replacements for the lua [gs]etRoomChar(...) is not going to happen. Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2018-03-28 14:06:12 +01:00
, mMaxVersion(19)
// minimum version this instance of Mudlet will allow the user to save maps in
, mMinVersion(16)
Enhance: add ability to set any glyph as a room symbol (#1543) This is a squashed down commit containing several commits with messages - this is the edited combination of all the messages: As well as being able to use any grapheme it is possible to use a short word as well as anything printable from any of the Unicode Multiple Planes; although the former will become smaller to fit within both the square and round room shapes on the 2D mapper. Adds controls to the profile preference to set the (preferred) font to use to set the room symbols from and a checkbox to only use that font. Additionally a sub-dialog can be brought up which lists the details of all the different symbols on the map - showing the Unicode codepoint(s) for each and showing how they would be rendered if only the selected font is used and if any font is permitted, along with a count of the usages and the rooms that use each one... A status icon is also displayed showing whether the symbol can be rendered entirely with the selected font (green tick), only by using glyphs from other fonts (yellow ! warning) or not with the current fonts on the system (red/white cross). This allows a user to make a sensible selection of a font to use or whether they will have a problem (and a replacement by the replacement character '�') for any symbols. Updates Lua setRoomChar and getRoomChar to handle the wider range of things that can be used. getRoomChar NOW allows for an existing character to be cleared with an empty string or a space as the char attribute. The map format version has been incremented to allow the data needed to be saved directly into the binary file format but failback code is in place that means that this feature can be carried in map and room user data instead for map format versions down to 17 - the current default is 18 and there is limited support to fail gracefully down to the 16 that Mudlet 2.1 uses (all the room letter markings that are not supported will become '?', and the font data will be lost, but the correct room character data will still be in the room user data.) Following review: * I replaced some colour specifications (white and transparent) with Qt constants. * Use the same inline function flushSymbolPixmapCache() to clear the map symbol pixmap cache in all places where it might be useful. * Simplify a couple of places where an if(...) {...} else {...} can be replaced with the (...) ? (...) : (...) operator. * Limit the number of room numbers displayed for each symbol in the new widget - to avoid complications where there are huge numbers of rooms using a symbol. * Replace a use of QTableWidget::clearContents() with QTableWidgets::setRowCount(0) as I was getting some odd, deep in the Qt internal library issues {Fatal Seg. Faults!} with the former, which I suspect, but could not prove, might have been a re-entrancy issue caused by the method containing it being called indirectly by an asynchronous SIGNAL/SLOT originating in the value change from the map symbol font selection QFontComboBox... Revised to NOT do scaling when drawing room symbols from cache: the previous QPainter::drawPixmap(...) performed a scaling operation to make the symbol pixmap fit the specified rectangle. This is the cause behind the poor rendering of text characters as the scaling undoes the benefits of anti-aliasing and takes time to do. This should be faster now because the pixmaps are generated at the size/resolution they are needed (though they do have to be thrown away and regenerated if the zoom or other sizing factors change) - they do however look better to me! Also: * merged (int) TRoom::xzoom and TRoom::yzoom into TRoom::xyzoom. * added the symbol scaling "fudge-factor" to the "Special Options" tab of the "Profile preferences" dialog - it may be helpful to artificially over-size (> 1.00) or under-size (< 1.00) the symbols in some situations. * uses the word symbol rather than just glyph/grapheme in some texts. Also modified 2D mapper "Symbol" tooltip to observe that more than one letter/symbol can be used (although they will be drawn smaller so that they still fit). Add tool-tips to profile preferences dialog for font controls (except for "fudge factor" control (with range x0.50 to x2.00 for scaling of symbol to test rectangle used to fit it into the room shape)... I have consistently mispelled chosen as choosen but I have fixed that now...! Also added tooltips to map glyph usage table/widget. WorkAround: try to force a specific US mirror for zziplib on AppVeyor CI AppVeyor is based in Vancouver, Canada so the nearest SF Mirror is in the US so this commit forces the use of that mirror for that library for the CI build process as an attempt to get around the repeated, intermittent failures to get that library from SourceForge (it is now the only item that needs to be downloaded from there for such builds)... Also adds another CI file that was not mentioned before in the qmake project file and thus did not show up in the Qt IDE. Following extensive discussions it has been made clear that introducing replacements for the lua [gs]etRoomChar(...) is not going to happen. Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2018-03-28 14:06:12 +01:00
, mMapSymbolFont(QFont(QStringLiteral("Bitstream Vera Sans Mono"), 12, QFont::Normal))
, mMapSymbolFontFudgeFactor(1.0)
, mIsOnlyMapSymbolFontToBeUsed(false)
, mIsFileViewingRecommended(false)
, mpNetworkAccessManager(Q_NULLPTR)
, mpProgressDialog(Q_NULLPTR)
, mpNetworkReply(Q_NULLPTR)
, mExpectedFileSize(0)
2010-08-25 00:41:43 +02:00
{
Enhance: fix map downloading code, add manual XML map importing (#326) * Enhance: fix map downloading code, add manual XML map importing A recent move by I.R.E. to using SSL for their public MUD map URLs broke the ability for Mudlet to download those XML format files. This commit addresses this issue (as mentioned in, but not the original problem referred to in https://bugs.launchpad.net/mudlet/+bug/1427364) the revision to the code does now use "https://www.<MUD URL>/maps/map.xml" as a default name for the I.R.E. MUDS - however the method that initiates the download which was moved to TMap class from the dlgMapper one (see below) is now: (bool) TMap::downloadMap( const QString * remoteUrl = Q_NULLPTR, const QString * localFileName = Q_NULLPTR ) which if not supplied with any arguments behaves as before. However the remoteUrl argument may be given as a full QString including the scheme (the bit of the URL at the beginning before the ':') to override that and a second argument may be used to provide a different name to use for the local file name which if is a RELATIVE pathFileName will be resolved in relation to the profile directory. At present no use is made of this additional functionality but it may be useful for use with other MUDs if they should choose to provide XML map files with other remote locations and scripts using a different local filename. As a long-standing thing that needed doing I have finally provided a means to import a map XML file that - for instance - has already been download. It had been noted that there was no way to read those I.R.E. map files even if they had been obtained from a web browser able to correctly handle https: URLs - now both the TLuaInterpreter::loadMap() and the dlgProfilePreference "loadMap" button {NOT the IRE only "map download" one} will both handle files ending in ".xml" (not case sensitive so it'll work MacOS platforms as well!} For the loadMap case it will be necessary to change the filetype filter on the File Selection dialog to select "xml" files. During testing it became clear to me that it was possible to try and read one or more XML files via several mechanisms simultaneously with "unhelpful" consequences. As well as hitting the dlgProfilePreferences IRE "map download" multiple times, the TLuaInterpreter::loadMap() does NOT block until the map has been loaded and as the import time {running of XMLinport::readPackage(...)} is of significant duration for a large map (a debug, without optimisation, build on my 1.8GHz Quad-core took over two minutes to process the current Achaea map file) it is very possible to get conditions where the same profile will try to run XMLinport::readPackage(...) asynchronously - given that a profile only supports ONE map at a time it was necessary to fit a QMutex to prevent the part of the XMLinport class relating to XML Map files being called from different places in the map related code. This means that if a map download is started further downloads and any local map imports will fail until that first download has completed or aborted. Similarly a local import will prevent a download being started. As a side effect this cures: https://bugs.launchpad.net/mudlet/+bug/852861 - "Map download button starts another download thread if one is already going" The previous XML import code was not adding the rooms that it parsed to the relevant TArea::rooms member - although this would be picked-up and fixed by TMap::audit() later on, this would be accompanied by an error message about every single room. The code now builds up this information while parsing the rooms' details and inserts it so that this does not cause report-able problems during the TMap::audit() execution - the data gathered also allows missing areas to be spotted so that if a room claimed to belong to an area that was not included in the preceding areas' data an unnamed area is created for it. As a consequence of the long time to actually parse an XML map file I have enhanced the progress dialog that was originally used to track the map file download. It is now retained until the file is completely imported and shows more information about the process - importantly it shows during the XMLimport::readRoom(...) the room id being processed - and THAT method is the time/cpu hog so seeing something happening during the time that Mudlet otherwise appears to hang is useful feedback even if it adds a few seconds to the overall duration (may be more than a minute). This dialog is now also used during the other routes that involve reading an XML file and there is now a bit of consistence with the on-screen messages. Whilst inspecting XMLimport class I found there was some uncertain initialisation which I have tidied up. In summary: Added: * (bool) TConsole::importMap(const QString & location) * (void) TRoomDB::setAreaRooms(const int areaId, const QSet<int> & roomIds) * image file mudlet_map_download.png used as icon for download/import progress dialog * (bool) TMap::importMap(QFile & file) * (bool) TMap::readXmlMapFile(QFile & file) * (void) TMap::slot_downloadError(QNetworkReply::NetworkError error) * (void) TMap::reportStringToProgressDialog(const QString text) * (void) TMap::reportProgressToProgressDialog(const int current, const int maximum) Revised: * (int)TLuaInterpreter::loadMap( lua_State * ) * Moved XML map download code from dlgMapper class to the TMap one: + (void) dlgMapper::downloadMap() ==> (bool) TMap::downloadMap(const QString * remoteUrl, const QString * localFileName) + (void) dlgMapper::setDownloadProgress(qint64, qint64) ==> (void) TMap::slot_setDownloadProgress(qint64,qint64) + (void) dlgMapper::cancel() ==> (void) TMap::slot_downloadCancel() + (void) dlgMapper::replyFinished(QNetworkReply *) ==> (void) TMap::slot_replyFinished(QNetworkReply *) * Enhanced download progress indication to also include parsing which can take even more time than download! * Provide means to import local XML map file * Prevent trying to import/download more than one map at a time Renamed: * (void) XMLimport::readAreaNames() ==> XMLimport::readArea() - for consistency with related functions Commented out unused: * (void) XMLimport::readUnknownRoomElement() Note the movement of the map file download code to the TMap class does require making the latter a class with the Q_OBJECT macro (which removes the need for Q_DECLARE_TR_FUNCTIONS as a side-effect!) - though as another side-effect the TMap header needed a boost name specifier added to one identifier as that identifier ("property") exists in both boost and QObject classes!!! YOU MAY NEED TO RUN QMAKE ON THE PROJECT IF THE BUILD SYSTEM DOES NOT PICK UP THE ADDITION OF "Q_OBJECT" TO TMAP CLASS. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: Include missing #include, remove unused return value The absence of this was causing build errors on the Travis C.I. platform! Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: move TMap.h to mudlet_MOC_HDRS to fix CMake build issue As we have made TMap inherit from QOject - to have signal/slot functionality that class needs to be run through Qt's MOC - and to do that with the CMake project/build system it needs to be included in the files included in the projects *_MOC_HDRS {and removed from the *_HDRS} variable. Also spotted a trivial error in that specifying a const return value from method is ineffective and pointless - so removed it from: TMap::retrieveMapFileStats(QString,QString *,int *,int *,int *,int *) Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: clean up TMap initialisation/clearing actions Now restores the customEnvColors set up on initialisation but that was cleared when the map replaced with another one that is loaded {which subsequently replaces that element anyway} or imported {which merely writes over it, replacing any matching keys}. Initialises elements that when inspected on the entry to the constructor proper previously were not being set to a consistent value {booleans/ints/floats}. NOTE: This will now clear the map user data member when the map is cleared if the date is required to be saved when one map is loaded OR IMPORTED over an existing one then the data will need to be saved outside of the map - as is already need for areas and rooms user data! Also comment out or remove unused members/methods: * (void) TMap::getConnectedNodesGreaterThanX(int, int) * (void) TMap::getConnectedNodesSmallerThanX(int, int) * (void) TMap::getConnectedNodesGreaterThanY(int, int) * (void) TMap::getConnectedNodesSmallerThanY(int, int) * (void) TMap::astBreitenAnpassung(int, int) * (void) TMap::astHoehenAnpassung(int, int) * (void) TMap::exportMapToDatabase() * (void) TMap::importMapFromDatabase() * (QVector3D) TMap::span * (int) TMap::mViewArea * (QMap<QString, int>) TMap::pixNameTable * (QMap<int, QPixmap>) TMap::pixTable * (bool) TMap::isToDisplayAuditErrorsToConsole Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * ImplimentationFixes: activate a valid optimisation & remove redundant code Adding a true as a non-default 3rd argument to TRoomDB::addRoom(...) call in XMLimport::readRoom(...) enables a significant optimisation (skips a computationally expensive step when ADDING a room to new map) which dramatically reduces the time to parse an XML map file. It also pointed to the fact that the TRoomDB::entranceMap was already correctly being handled and didn't need to be regenerated in XMLimport::readRoom(...) so the code that was added in a previous commit was redundant and could be removed. A code error in TMap::slot_setDownloadProgress(...) that caused an issue that a reviewer found on test has been fixed - the total download filesize that was being sent by the Qt system signal that is connected to this slot was a -1 value (as IS DOCUMENTED) when the Qt system does NOT know the size of a QNetworkReply in advance of reaching the end of the download was incorrectly handled in a previous commit in this change set. Also found during testing that there is no need for an error message for the QNetworkReply::OperationCanceledError case in TMap::slot_replayFinished(...) as it is already handled in the TMap::slot_downloadCancel() slot. Changed the text put up onto the progress widget during the XML room parsing to be a room count - which is likely more useful and to only do it for every hundredth room - which reduces any delay "wasted" in writing to the display - combined, the effects seem satisfactory IMHO. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: provide error messages for TLuaInterpreter::loadMap(...) Errors for the XML map file importing process as initiated from the Lua command should be returned to that command rather than plastered onto the main profile console - this commit attempts to perform that effect. In testing found that there was no error handling for failure to find or open the nominated file so messages for that have been added as well. Due to the previous program logic the action of creating a mapper widget using the main toolbar button automatically loaded the "default" (the newest Mudlet Map file format file from the currently active profile's map sub-directory). Under some previous situations it looked as though a map might be loaded twice as mudlet::slot_mapper() was called both directly and via signal/slot action. These were resolved by turning that slot into a wrapper that now calls the body of code formerly within to a new method mudlet::createMapper( bool isToLoadDefaultMapFile = true ) with a the default value as an argument. This allows other usages of the body of code to be called directly with a suitable argument, which for the TConsole::loadMap() & TConsole::importMap() and the dlgProfilePreferences::downloadMap() cases is false as they are all do not want the "default" map! Also: * spotted a word "area" missing from an advisory text in TRoom::auditRooms(...). Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: fix minor bug, correct a spelling, undo a few capitalisations Under certain, unanticipated (error with no error message) conditions TLuaInterpreter::loadMap(...) would push both a nil and then a false value onto the stack for return {wrong} but only indicate one value {correct}. The textual matters were found during peer review. off-by: Stephen Lyons <slysven@virginmedia.com>
2016-10-13 09:18:48 +01:00
mSaveVersion = mDefaultVersion; // Can not be set initialiser list because of ordering issues (?)
// It needs to be set (for when writing new
// map files) as it triggers some version features
// that NEED a new map file format to be usable, it
// can be changed by control in last tab of profile
// preference dialog.
mVersion = mDefaultVersion; // This is overwritten during a map restore and
// is the loaded file version
2011-01-20 22:06:21 +01:00
customEnvColors[257] = mpHost->mRed_2;
customEnvColors[258] = mpHost->mGreen_2;
customEnvColors[259] = mpHost->mYellow_2;
customEnvColors[260] = mpHost->mBlue_2;
customEnvColors[261] = mpHost->mMagenta_2;
customEnvColors[262] = mpHost->mCyan_2;
customEnvColors[263] = mpHost->mWhite_2;
customEnvColors[264] = mpHost->mBlack_2;
customEnvColors[265] = mpHost->mLightRed_2;
customEnvColors[266] = mpHost->mLightGreen_2;
customEnvColors[267] = mpHost->mLightYellow_2;
customEnvColors[268] = mpHost->mLightBlue_2;
customEnvColors[269] = mpHost->mLightMagenta_2;
customEnvColors[270] = mpHost->mLightCyan_2;
customEnvColors[271] = mpHost->mLightWhite_2;
2011-01-22 19:23:56 +01:00
customEnvColors[272] = mpHost->mLightBlack_2;
unitVectors[1] = QVector3D(0, -1, 0);
unitVectors[2] = QVector3D(1, -1, 0);
unitVectors[3] = QVector3D(-1, -1, 0);
unitVectors[4] = QVector3D(1, 0, 0);
unitVectors[5] = QVector3D(-1, 0, 0);
unitVectors[6] = QVector3D(0, 1, 0);
unitVectors[7] = QVector3D(1, 1, 0);
unitVectors[8] = QVector3D(-1, 1, 0);
unitVectors[9] = QVector3D(0, 0, 1);
unitVectors[10] = QVector3D(0, 0, -1);
reverseDirections[1] = 6; //contains complementary directions
reverseDirections[2] = 8;
reverseDirections[3] = 7;
reverseDirections[4] = 5;
reverseDirections[5] = 4;
reverseDirections[6] = 1;
reverseDirections[7] = 3;
reverseDirections[8] = 2;
reverseDirections[9] = 10;
reverseDirections[10] = 9;
reverseDirections[11] = 12;
reverseDirections[12] = 11;
Enhance: fix map downloading code, add manual XML map importing (#326) * Enhance: fix map downloading code, add manual XML map importing A recent move by I.R.E. to using SSL for their public MUD map URLs broke the ability for Mudlet to download those XML format files. This commit addresses this issue (as mentioned in, but not the original problem referred to in https://bugs.launchpad.net/mudlet/+bug/1427364) the revision to the code does now use "https://www.<MUD URL>/maps/map.xml" as a default name for the I.R.E. MUDS - however the method that initiates the download which was moved to TMap class from the dlgMapper one (see below) is now: (bool) TMap::downloadMap( const QString * remoteUrl = Q_NULLPTR, const QString * localFileName = Q_NULLPTR ) which if not supplied with any arguments behaves as before. However the remoteUrl argument may be given as a full QString including the scheme (the bit of the URL at the beginning before the ':') to override that and a second argument may be used to provide a different name to use for the local file name which if is a RELATIVE pathFileName will be resolved in relation to the profile directory. At present no use is made of this additional functionality but it may be useful for use with other MUDs if they should choose to provide XML map files with other remote locations and scripts using a different local filename. As a long-standing thing that needed doing I have finally provided a means to import a map XML file that - for instance - has already been download. It had been noted that there was no way to read those I.R.E. map files even if they had been obtained from a web browser able to correctly handle https: URLs - now both the TLuaInterpreter::loadMap() and the dlgProfilePreference "loadMap" button {NOT the IRE only "map download" one} will both handle files ending in ".xml" (not case sensitive so it'll work MacOS platforms as well!} For the loadMap case it will be necessary to change the filetype filter on the File Selection dialog to select "xml" files. During testing it became clear to me that it was possible to try and read one or more XML files via several mechanisms simultaneously with "unhelpful" consequences. As well as hitting the dlgProfilePreferences IRE "map download" multiple times, the TLuaInterpreter::loadMap() does NOT block until the map has been loaded and as the import time {running of XMLinport::readPackage(...)} is of significant duration for a large map (a debug, without optimisation, build on my 1.8GHz Quad-core took over two minutes to process the current Achaea map file) it is very possible to get conditions where the same profile will try to run XMLinport::readPackage(...) asynchronously - given that a profile only supports ONE map at a time it was necessary to fit a QMutex to prevent the part of the XMLinport class relating to XML Map files being called from different places in the map related code. This means that if a map download is started further downloads and any local map imports will fail until that first download has completed or aborted. Similarly a local import will prevent a download being started. As a side effect this cures: https://bugs.launchpad.net/mudlet/+bug/852861 - "Map download button starts another download thread if one is already going" The previous XML import code was not adding the rooms that it parsed to the relevant TArea::rooms member - although this would be picked-up and fixed by TMap::audit() later on, this would be accompanied by an error message about every single room. The code now builds up this information while parsing the rooms' details and inserts it so that this does not cause report-able problems during the TMap::audit() execution - the data gathered also allows missing areas to be spotted so that if a room claimed to belong to an area that was not included in the preceding areas' data an unnamed area is created for it. As a consequence of the long time to actually parse an XML map file I have enhanced the progress dialog that was originally used to track the map file download. It is now retained until the file is completely imported and shows more information about the process - importantly it shows during the XMLimport::readRoom(...) the room id being processed - and THAT method is the time/cpu hog so seeing something happening during the time that Mudlet otherwise appears to hang is useful feedback even if it adds a few seconds to the overall duration (may be more than a minute). This dialog is now also used during the other routes that involve reading an XML file and there is now a bit of consistence with the on-screen messages. Whilst inspecting XMLimport class I found there was some uncertain initialisation which I have tidied up. In summary: Added: * (bool) TConsole::importMap(const QString & location) * (void) TRoomDB::setAreaRooms(const int areaId, const QSet<int> & roomIds) * image file mudlet_map_download.png used as icon for download/import progress dialog * (bool) TMap::importMap(QFile & file) * (bool) TMap::readXmlMapFile(QFile & file) * (void) TMap::slot_downloadError(QNetworkReply::NetworkError error) * (void) TMap::reportStringToProgressDialog(const QString text) * (void) TMap::reportProgressToProgressDialog(const int current, const int maximum) Revised: * (int)TLuaInterpreter::loadMap( lua_State * ) * Moved XML map download code from dlgMapper class to the TMap one: + (void) dlgMapper::downloadMap() ==> (bool) TMap::downloadMap(const QString * remoteUrl, const QString * localFileName) + (void) dlgMapper::setDownloadProgress(qint64, qint64) ==> (void) TMap::slot_setDownloadProgress(qint64,qint64) + (void) dlgMapper::cancel() ==> (void) TMap::slot_downloadCancel() + (void) dlgMapper::replyFinished(QNetworkReply *) ==> (void) TMap::slot_replyFinished(QNetworkReply *) * Enhanced download progress indication to also include parsing which can take even more time than download! * Provide means to import local XML map file * Prevent trying to import/download more than one map at a time Renamed: * (void) XMLimport::readAreaNames() ==> XMLimport::readArea() - for consistency with related functions Commented out unused: * (void) XMLimport::readUnknownRoomElement() Note the movement of the map file download code to the TMap class does require making the latter a class with the Q_OBJECT macro (which removes the need for Q_DECLARE_TR_FUNCTIONS as a side-effect!) - though as another side-effect the TMap header needed a boost name specifier added to one identifier as that identifier ("property") exists in both boost and QObject classes!!! YOU MAY NEED TO RUN QMAKE ON THE PROJECT IF THE BUILD SYSTEM DOES NOT PICK UP THE ADDITION OF "Q_OBJECT" TO TMAP CLASS. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: Include missing #include, remove unused return value The absence of this was causing build errors on the Travis C.I. platform! Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: move TMap.h to mudlet_MOC_HDRS to fix CMake build issue As we have made TMap inherit from QOject - to have signal/slot functionality that class needs to be run through Qt's MOC - and to do that with the CMake project/build system it needs to be included in the files included in the projects *_MOC_HDRS {and removed from the *_HDRS} variable. Also spotted a trivial error in that specifying a const return value from method is ineffective and pointless - so removed it from: TMap::retrieveMapFileStats(QString,QString *,int *,int *,int *,int *) Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: clean up TMap initialisation/clearing actions Now restores the customEnvColors set up on initialisation but that was cleared when the map replaced with another one that is loaded {which subsequently replaces that element anyway} or imported {which merely writes over it, replacing any matching keys}. Initialises elements that when inspected on the entry to the constructor proper previously were not being set to a consistent value {booleans/ints/floats}. NOTE: This will now clear the map user data member when the map is cleared if the date is required to be saved when one map is loaded OR IMPORTED over an existing one then the data will need to be saved outside of the map - as is already need for areas and rooms user data! Also comment out or remove unused members/methods: * (void) TMap::getConnectedNodesGreaterThanX(int, int) * (void) TMap::getConnectedNodesSmallerThanX(int, int) * (void) TMap::getConnectedNodesGreaterThanY(int, int) * (void) TMap::getConnectedNodesSmallerThanY(int, int) * (void) TMap::astBreitenAnpassung(int, int) * (void) TMap::astHoehenAnpassung(int, int) * (void) TMap::exportMapToDatabase() * (void) TMap::importMapFromDatabase() * (QVector3D) TMap::span * (int) TMap::mViewArea * (QMap<QString, int>) TMap::pixNameTable * (QMap<int, QPixmap>) TMap::pixTable * (bool) TMap::isToDisplayAuditErrorsToConsole Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * ImplimentationFixes: activate a valid optimisation & remove redundant code Adding a true as a non-default 3rd argument to TRoomDB::addRoom(...) call in XMLimport::readRoom(...) enables a significant optimisation (skips a computationally expensive step when ADDING a room to new map) which dramatically reduces the time to parse an XML map file. It also pointed to the fact that the TRoomDB::entranceMap was already correctly being handled and didn't need to be regenerated in XMLimport::readRoom(...) so the code that was added in a previous commit was redundant and could be removed. A code error in TMap::slot_setDownloadProgress(...) that caused an issue that a reviewer found on test has been fixed - the total download filesize that was being sent by the Qt system signal that is connected to this slot was a -1 value (as IS DOCUMENTED) when the Qt system does NOT know the size of a QNetworkReply in advance of reaching the end of the download was incorrectly handled in a previous commit in this change set. Also found during testing that there is no need for an error message for the QNetworkReply::OperationCanceledError case in TMap::slot_replayFinished(...) as it is already handled in the TMap::slot_downloadCancel() slot. Changed the text put up onto the progress widget during the XML room parsing to be a room count - which is likely more useful and to only do it for every hundredth room - which reduces any delay "wasted" in writing to the display - combined, the effects seem satisfactory IMHO. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: provide error messages for TLuaInterpreter::loadMap(...) Errors for the XML map file importing process as initiated from the Lua command should be returned to that command rather than plastered onto the main profile console - this commit attempts to perform that effect. In testing found that there was no error handling for failure to find or open the nominated file so messages for that have been added as well. Due to the previous program logic the action of creating a mapper widget using the main toolbar button automatically loaded the "default" (the newest Mudlet Map file format file from the currently active profile's map sub-directory). Under some previous situations it looked as though a map might be loaded twice as mudlet::slot_mapper() was called both directly and via signal/slot action. These were resolved by turning that slot into a wrapper that now calls the body of code formerly within to a new method mudlet::createMapper( bool isToLoadDefaultMapFile = true ) with a the default value as an argument. This allows other usages of the body of code to be called directly with a suitable argument, which for the TConsole::loadMap() & TConsole::importMap() and the dlgProfilePreferences::downloadMap() cases is false as they are all do not want the "default" map! Also: * spotted a word "area" missing from an advisory text in TRoom::auditRooms(...). Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: fix minor bug, correct a spelling, undo a few capitalisations Under certain, unanticipated (error with no error message) conditions TLuaInterpreter::loadMap(...) would push both a nil and then a false value onto the stack for return {wrong} but only indicate one value {correct}. The textual matters were found during peer review. off-by: Stephen Lyons <slysven@virginmedia.com>
2016-10-13 09:18:48 +01:00
// According to Qt Docs we should really only have one of these
// (QNetworkAccessManager) for the whole application, but: each profile's
// TLuaInterpreter; each profile's ctelnet and now each profile's TMap
// (was dlgMapper) instance has one...!
mpNetworkAccessManager = new QNetworkAccessManager(this);
Enhance: fix map downloading code, add manual XML map importing (#326) * Enhance: fix map downloading code, add manual XML map importing A recent move by I.R.E. to using SSL for their public MUD map URLs broke the ability for Mudlet to download those XML format files. This commit addresses this issue (as mentioned in, but not the original problem referred to in https://bugs.launchpad.net/mudlet/+bug/1427364) the revision to the code does now use "https://www.<MUD URL>/maps/map.xml" as a default name for the I.R.E. MUDS - however the method that initiates the download which was moved to TMap class from the dlgMapper one (see below) is now: (bool) TMap::downloadMap( const QString * remoteUrl = Q_NULLPTR, const QString * localFileName = Q_NULLPTR ) which if not supplied with any arguments behaves as before. However the remoteUrl argument may be given as a full QString including the scheme (the bit of the URL at the beginning before the ':') to override that and a second argument may be used to provide a different name to use for the local file name which if is a RELATIVE pathFileName will be resolved in relation to the profile directory. At present no use is made of this additional functionality but it may be useful for use with other MUDs if they should choose to provide XML map files with other remote locations and scripts using a different local filename. As a long-standing thing that needed doing I have finally provided a means to import a map XML file that - for instance - has already been download. It had been noted that there was no way to read those I.R.E. map files even if they had been obtained from a web browser able to correctly handle https: URLs - now both the TLuaInterpreter::loadMap() and the dlgProfilePreference "loadMap" button {NOT the IRE only "map download" one} will both handle files ending in ".xml" (not case sensitive so it'll work MacOS platforms as well!} For the loadMap case it will be necessary to change the filetype filter on the File Selection dialog to select "xml" files. During testing it became clear to me that it was possible to try and read one or more XML files via several mechanisms simultaneously with "unhelpful" consequences. As well as hitting the dlgProfilePreferences IRE "map download" multiple times, the TLuaInterpreter::loadMap() does NOT block until the map has been loaded and as the import time {running of XMLinport::readPackage(...)} is of significant duration for a large map (a debug, without optimisation, build on my 1.8GHz Quad-core took over two minutes to process the current Achaea map file) it is very possible to get conditions where the same profile will try to run XMLinport::readPackage(...) asynchronously - given that a profile only supports ONE map at a time it was necessary to fit a QMutex to prevent the part of the XMLinport class relating to XML Map files being called from different places in the map related code. This means that if a map download is started further downloads and any local map imports will fail until that first download has completed or aborted. Similarly a local import will prevent a download being started. As a side effect this cures: https://bugs.launchpad.net/mudlet/+bug/852861 - "Map download button starts another download thread if one is already going" The previous XML import code was not adding the rooms that it parsed to the relevant TArea::rooms member - although this would be picked-up and fixed by TMap::audit() later on, this would be accompanied by an error message about every single room. The code now builds up this information while parsing the rooms' details and inserts it so that this does not cause report-able problems during the TMap::audit() execution - the data gathered also allows missing areas to be spotted so that if a room claimed to belong to an area that was not included in the preceding areas' data an unnamed area is created for it. As a consequence of the long time to actually parse an XML map file I have enhanced the progress dialog that was originally used to track the map file download. It is now retained until the file is completely imported and shows more information about the process - importantly it shows during the XMLimport::readRoom(...) the room id being processed - and THAT method is the time/cpu hog so seeing something happening during the time that Mudlet otherwise appears to hang is useful feedback even if it adds a few seconds to the overall duration (may be more than a minute). This dialog is now also used during the other routes that involve reading an XML file and there is now a bit of consistence with the on-screen messages. Whilst inspecting XMLimport class I found there was some uncertain initialisation which I have tidied up. In summary: Added: * (bool) TConsole::importMap(const QString & location) * (void) TRoomDB::setAreaRooms(const int areaId, const QSet<int> & roomIds) * image file mudlet_map_download.png used as icon for download/import progress dialog * (bool) TMap::importMap(QFile & file) * (bool) TMap::readXmlMapFile(QFile & file) * (void) TMap::slot_downloadError(QNetworkReply::NetworkError error) * (void) TMap::reportStringToProgressDialog(const QString text) * (void) TMap::reportProgressToProgressDialog(const int current, const int maximum) Revised: * (int)TLuaInterpreter::loadMap( lua_State * ) * Moved XML map download code from dlgMapper class to the TMap one: + (void) dlgMapper::downloadMap() ==> (bool) TMap::downloadMap(const QString * remoteUrl, const QString * localFileName) + (void) dlgMapper::setDownloadProgress(qint64, qint64) ==> (void) TMap::slot_setDownloadProgress(qint64,qint64) + (void) dlgMapper::cancel() ==> (void) TMap::slot_downloadCancel() + (void) dlgMapper::replyFinished(QNetworkReply *) ==> (void) TMap::slot_replyFinished(QNetworkReply *) * Enhanced download progress indication to also include parsing which can take even more time than download! * Provide means to import local XML map file * Prevent trying to import/download more than one map at a time Renamed: * (void) XMLimport::readAreaNames() ==> XMLimport::readArea() - for consistency with related functions Commented out unused: * (void) XMLimport::readUnknownRoomElement() Note the movement of the map file download code to the TMap class does require making the latter a class with the Q_OBJECT macro (which removes the need for Q_DECLARE_TR_FUNCTIONS as a side-effect!) - though as another side-effect the TMap header needed a boost name specifier added to one identifier as that identifier ("property") exists in both boost and QObject classes!!! YOU MAY NEED TO RUN QMAKE ON THE PROJECT IF THE BUILD SYSTEM DOES NOT PICK UP THE ADDITION OF "Q_OBJECT" TO TMAP CLASS. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: Include missing #include, remove unused return value The absence of this was causing build errors on the Travis C.I. platform! Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: move TMap.h to mudlet_MOC_HDRS to fix CMake build issue As we have made TMap inherit from QOject - to have signal/slot functionality that class needs to be run through Qt's MOC - and to do that with the CMake project/build system it needs to be included in the files included in the projects *_MOC_HDRS {and removed from the *_HDRS} variable. Also spotted a trivial error in that specifying a const return value from method is ineffective and pointless - so removed it from: TMap::retrieveMapFileStats(QString,QString *,int *,int *,int *,int *) Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: clean up TMap initialisation/clearing actions Now restores the customEnvColors set up on initialisation but that was cleared when the map replaced with another one that is loaded {which subsequently replaces that element anyway} or imported {which merely writes over it, replacing any matching keys}. Initialises elements that when inspected on the entry to the constructor proper previously were not being set to a consistent value {booleans/ints/floats}. NOTE: This will now clear the map user data member when the map is cleared if the date is required to be saved when one map is loaded OR IMPORTED over an existing one then the data will need to be saved outside of the map - as is already need for areas and rooms user data! Also comment out or remove unused members/methods: * (void) TMap::getConnectedNodesGreaterThanX(int, int) * (void) TMap::getConnectedNodesSmallerThanX(int, int) * (void) TMap::getConnectedNodesGreaterThanY(int, int) * (void) TMap::getConnectedNodesSmallerThanY(int, int) * (void) TMap::astBreitenAnpassung(int, int) * (void) TMap::astHoehenAnpassung(int, int) * (void) TMap::exportMapToDatabase() * (void) TMap::importMapFromDatabase() * (QVector3D) TMap::span * (int) TMap::mViewArea * (QMap<QString, int>) TMap::pixNameTable * (QMap<int, QPixmap>) TMap::pixTable * (bool) TMap::isToDisplayAuditErrorsToConsole Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * ImplimentationFixes: activate a valid optimisation & remove redundant code Adding a true as a non-default 3rd argument to TRoomDB::addRoom(...) call in XMLimport::readRoom(...) enables a significant optimisation (skips a computationally expensive step when ADDING a room to new map) which dramatically reduces the time to parse an XML map file. It also pointed to the fact that the TRoomDB::entranceMap was already correctly being handled and didn't need to be regenerated in XMLimport::readRoom(...) so the code that was added in a previous commit was redundant and could be removed. A code error in TMap::slot_setDownloadProgress(...) that caused an issue that a reviewer found on test has been fixed - the total download filesize that was being sent by the Qt system signal that is connected to this slot was a -1 value (as IS DOCUMENTED) when the Qt system does NOT know the size of a QNetworkReply in advance of reaching the end of the download was incorrectly handled in a previous commit in this change set. Also found during testing that there is no need for an error message for the QNetworkReply::OperationCanceledError case in TMap::slot_replayFinished(...) as it is already handled in the TMap::slot_downloadCancel() slot. Changed the text put up onto the progress widget during the XML room parsing to be a room count - which is likely more useful and to only do it for every hundredth room - which reduces any delay "wasted" in writing to the display - combined, the effects seem satisfactory IMHO. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: provide error messages for TLuaInterpreter::loadMap(...) Errors for the XML map file importing process as initiated from the Lua command should be returned to that command rather than plastered onto the main profile console - this commit attempts to perform that effect. In testing found that there was no error handling for failure to find or open the nominated file so messages for that have been added as well. Due to the previous program logic the action of creating a mapper widget using the main toolbar button automatically loaded the "default" (the newest Mudlet Map file format file from the currently active profile's map sub-directory). Under some previous situations it looked as though a map might be loaded twice as mudlet::slot_mapper() was called both directly and via signal/slot action. These were resolved by turning that slot into a wrapper that now calls the body of code formerly within to a new method mudlet::createMapper( bool isToLoadDefaultMapFile = true ) with a the default value as an argument. This allows other usages of the body of code to be called directly with a suitable argument, which for the TConsole::loadMap() & TConsole::importMap() and the dlgProfilePreferences::downloadMap() cases is false as they are all do not want the "default" map! Also: * spotted a word "area" missing from an advisory text in TRoom::auditRooms(...). Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: fix minor bug, correct a spelling, undo a few capitalisations Under certain, unanticipated (error with no error message) conditions TLuaInterpreter::loadMap(...) would push both a nil and then a false value onto the stack for return {wrong} but only indicate one value {correct}. The textual matters were found during peer review. off-by: Stephen Lyons <slysven@virginmedia.com>
2016-10-13 09:18:48 +01:00
connect(mpNetworkAccessManager, &QNetworkAccessManager::finished, this, &TMap::slot_replyFinished);
2010-08-25 00:41:43 +02:00
}
TMap::~TMap()
{
2014-08-27 20:24:25 -07:00
delete mpRoomDB;
if (!mStoredMessages.isEmpty()) {
Revision: route most of map auditing messages to errors.txt file As the amount of messages produced by the new/improve map auditing/clean-up code can be large for old map files this commit causes them to be sent to a profile specific file that is already opened by the Host class but has not been used for some time. An option (a check-box) on the "map" tab of the "profile preferences" dialog controls whether the equivalent information is also shown on the profile's main console as in the past. If the option (a global one) which is saved between sessions/runs is NOT enabled then an advisory is sent to the console advising the user to review the file contents if a "significant" issue was detected. If it is enabled a similar message advising that the information has also been saved. In either case, as the file is appended to, and not rewritten each time, the message includes details of the first line of the report so that it can be located in the file. One difference between the on-screen and the file versions of the information is that the former puts up the issues as they are detected whereas the latter groups the information by subject, first the general overall issues, then the area ones, in order of the areas' id numbers and then the room ones, in room order. Following earlier discussions in these Pull Request I have attempted to edit all uses of the word "Id" in user visible places to be "id" instead. This threw up some other messages with issues in several files that I have tweaked here as well! Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2016-05-03 04:58:31 +01:00
qWarning() << "TMap::~TMap() Instance being destroyed before it could display some messages,\n"
<< "messages are:\n"
<< "------------";
foreach (QString message, mStoredMessages) {
qWarning() << message << "\n------------";
}
}
2014-08-27 20:24:25 -07:00
}
void TMap::mapClear()
{
2013-03-22 12:47:58 +01:00
mpRoomDB->clearMapDB();
envColors.clear();
Enhance: fix map downloading code, add manual XML map importing (#326) * Enhance: fix map downloading code, add manual XML map importing A recent move by I.R.E. to using SSL for their public MUD map URLs broke the ability for Mudlet to download those XML format files. This commit addresses this issue (as mentioned in, but not the original problem referred to in https://bugs.launchpad.net/mudlet/+bug/1427364) the revision to the code does now use "https://www.<MUD URL>/maps/map.xml" as a default name for the I.R.E. MUDS - however the method that initiates the download which was moved to TMap class from the dlgMapper one (see below) is now: (bool) TMap::downloadMap( const QString * remoteUrl = Q_NULLPTR, const QString * localFileName = Q_NULLPTR ) which if not supplied with any arguments behaves as before. However the remoteUrl argument may be given as a full QString including the scheme (the bit of the URL at the beginning before the ':') to override that and a second argument may be used to provide a different name to use for the local file name which if is a RELATIVE pathFileName will be resolved in relation to the profile directory. At present no use is made of this additional functionality but it may be useful for use with other MUDs if they should choose to provide XML map files with other remote locations and scripts using a different local filename. As a long-standing thing that needed doing I have finally provided a means to import a map XML file that - for instance - has already been download. It had been noted that there was no way to read those I.R.E. map files even if they had been obtained from a web browser able to correctly handle https: URLs - now both the TLuaInterpreter::loadMap() and the dlgProfilePreference "loadMap" button {NOT the IRE only "map download" one} will both handle files ending in ".xml" (not case sensitive so it'll work MacOS platforms as well!} For the loadMap case it will be necessary to change the filetype filter on the File Selection dialog to select "xml" files. During testing it became clear to me that it was possible to try and read one or more XML files via several mechanisms simultaneously with "unhelpful" consequences. As well as hitting the dlgProfilePreferences IRE "map download" multiple times, the TLuaInterpreter::loadMap() does NOT block until the map has been loaded and as the import time {running of XMLinport::readPackage(...)} is of significant duration for a large map (a debug, without optimisation, build on my 1.8GHz Quad-core took over two minutes to process the current Achaea map file) it is very possible to get conditions where the same profile will try to run XMLinport::readPackage(...) asynchronously - given that a profile only supports ONE map at a time it was necessary to fit a QMutex to prevent the part of the XMLinport class relating to XML Map files being called from different places in the map related code. This means that if a map download is started further downloads and any local map imports will fail until that first download has completed or aborted. Similarly a local import will prevent a download being started. As a side effect this cures: https://bugs.launchpad.net/mudlet/+bug/852861 - "Map download button starts another download thread if one is already going" The previous XML import code was not adding the rooms that it parsed to the relevant TArea::rooms member - although this would be picked-up and fixed by TMap::audit() later on, this would be accompanied by an error message about every single room. The code now builds up this information while parsing the rooms' details and inserts it so that this does not cause report-able problems during the TMap::audit() execution - the data gathered also allows missing areas to be spotted so that if a room claimed to belong to an area that was not included in the preceding areas' data an unnamed area is created for it. As a consequence of the long time to actually parse an XML map file I have enhanced the progress dialog that was originally used to track the map file download. It is now retained until the file is completely imported and shows more information about the process - importantly it shows during the XMLimport::readRoom(...) the room id being processed - and THAT method is the time/cpu hog so seeing something happening during the time that Mudlet otherwise appears to hang is useful feedback even if it adds a few seconds to the overall duration (may be more than a minute). This dialog is now also used during the other routes that involve reading an XML file and there is now a bit of consistence with the on-screen messages. Whilst inspecting XMLimport class I found there was some uncertain initialisation which I have tidied up. In summary: Added: * (bool) TConsole::importMap(const QString & location) * (void) TRoomDB::setAreaRooms(const int areaId, const QSet<int> & roomIds) * image file mudlet_map_download.png used as icon for download/import progress dialog * (bool) TMap::importMap(QFile & file) * (bool) TMap::readXmlMapFile(QFile & file) * (void) TMap::slot_downloadError(QNetworkReply::NetworkError error) * (void) TMap::reportStringToProgressDialog(const QString text) * (void) TMap::reportProgressToProgressDialog(const int current, const int maximum) Revised: * (int)TLuaInterpreter::loadMap( lua_State * ) * Moved XML map download code from dlgMapper class to the TMap one: + (void) dlgMapper::downloadMap() ==> (bool) TMap::downloadMap(const QString * remoteUrl, const QString * localFileName) + (void) dlgMapper::setDownloadProgress(qint64, qint64) ==> (void) TMap::slot_setDownloadProgress(qint64,qint64) + (void) dlgMapper::cancel() ==> (void) TMap::slot_downloadCancel() + (void) dlgMapper::replyFinished(QNetworkReply *) ==> (void) TMap::slot_replyFinished(QNetworkReply *) * Enhanced download progress indication to also include parsing which can take even more time than download! * Provide means to import local XML map file * Prevent trying to import/download more than one map at a time Renamed: * (void) XMLimport::readAreaNames() ==> XMLimport::readArea() - for consistency with related functions Commented out unused: * (void) XMLimport::readUnknownRoomElement() Note the movement of the map file download code to the TMap class does require making the latter a class with the Q_OBJECT macro (which removes the need for Q_DECLARE_TR_FUNCTIONS as a side-effect!) - though as another side-effect the TMap header needed a boost name specifier added to one identifier as that identifier ("property") exists in both boost and QObject classes!!! YOU MAY NEED TO RUN QMAKE ON THE PROJECT IF THE BUILD SYSTEM DOES NOT PICK UP THE ADDITION OF "Q_OBJECT" TO TMAP CLASS. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: Include missing #include, remove unused return value The absence of this was causing build errors on the Travis C.I. platform! Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: move TMap.h to mudlet_MOC_HDRS to fix CMake build issue As we have made TMap inherit from QOject - to have signal/slot functionality that class needs to be run through Qt's MOC - and to do that with the CMake project/build system it needs to be included in the files included in the projects *_MOC_HDRS {and removed from the *_HDRS} variable. Also spotted a trivial error in that specifying a const return value from method is ineffective and pointless - so removed it from: TMap::retrieveMapFileStats(QString,QString *,int *,int *,int *,int *) Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: clean up TMap initialisation/clearing actions Now restores the customEnvColors set up on initialisation but that was cleared when the map replaced with another one that is loaded {which subsequently replaces that element anyway} or imported {which merely writes over it, replacing any matching keys}. Initialises elements that when inspected on the entry to the constructor proper previously were not being set to a consistent value {booleans/ints/floats}. NOTE: This will now clear the map user data member when the map is cleared if the date is required to be saved when one map is loaded OR IMPORTED over an existing one then the data will need to be saved outside of the map - as is already need for areas and rooms user data! Also comment out or remove unused members/methods: * (void) TMap::getConnectedNodesGreaterThanX(int, int) * (void) TMap::getConnectedNodesSmallerThanX(int, int) * (void) TMap::getConnectedNodesGreaterThanY(int, int) * (void) TMap::getConnectedNodesSmallerThanY(int, int) * (void) TMap::astBreitenAnpassung(int, int) * (void) TMap::astHoehenAnpassung(int, int) * (void) TMap::exportMapToDatabase() * (void) TMap::importMapFromDatabase() * (QVector3D) TMap::span * (int) TMap::mViewArea * (QMap<QString, int>) TMap::pixNameTable * (QMap<int, QPixmap>) TMap::pixTable * (bool) TMap::isToDisplayAuditErrorsToConsole Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * ImplimentationFixes: activate a valid optimisation & remove redundant code Adding a true as a non-default 3rd argument to TRoomDB::addRoom(...) call in XMLimport::readRoom(...) enables a significant optimisation (skips a computationally expensive step when ADDING a room to new map) which dramatically reduces the time to parse an XML map file. It also pointed to the fact that the TRoomDB::entranceMap was already correctly being handled and didn't need to be regenerated in XMLimport::readRoom(...) so the code that was added in a previous commit was redundant and could be removed. A code error in TMap::slot_setDownloadProgress(...) that caused an issue that a reviewer found on test has been fixed - the total download filesize that was being sent by the Qt system signal that is connected to this slot was a -1 value (as IS DOCUMENTED) when the Qt system does NOT know the size of a QNetworkReply in advance of reaching the end of the download was incorrectly handled in a previous commit in this change set. Also found during testing that there is no need for an error message for the QNetworkReply::OperationCanceledError case in TMap::slot_replayFinished(...) as it is already handled in the TMap::slot_downloadCancel() slot. Changed the text put up onto the progress widget during the XML room parsing to be a room count - which is likely more useful and to only do it for every hundredth room - which reduces any delay "wasted" in writing to the display - combined, the effects seem satisfactory IMHO. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: provide error messages for TLuaInterpreter::loadMap(...) Errors for the XML map file importing process as initiated from the Lua command should be returned to that command rather than plastered onto the main profile console - this commit attempts to perform that effect. In testing found that there was no error handling for failure to find or open the nominated file so messages for that have been added as well. Due to the previous program logic the action of creating a mapper widget using the main toolbar button automatically loaded the "default" (the newest Mudlet Map file format file from the currently active profile's map sub-directory). Under some previous situations it looked as though a map might be loaded twice as mudlet::slot_mapper() was called both directly and via signal/slot action. These were resolved by turning that slot into a wrapper that now calls the body of code formerly within to a new method mudlet::createMapper( bool isToLoadDefaultMapFile = true ) with a the default value as an argument. This allows other usages of the body of code to be called directly with a suitable argument, which for the TConsole::loadMap() & TConsole::importMap() and the dlgProfilePreferences::downloadMap() cases is false as they are all do not want the "default" map! Also: * spotted a word "area" missing from an advisory text in TRoom::auditRooms(...). Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: fix minor bug, correct a spelling, undo a few capitalisations Under certain, unanticipated (error with no error message) conditions TLuaInterpreter::loadMap(...) would push both a nil and then a false value onto the stack for return {wrong} but only indicate one value {correct}. The textual matters were found during peer review. off-by: Stephen Lyons <slysven@virginmedia.com>
2016-10-13 09:18:48 +01:00
mRoomIdHash.clear();
mTargetID = 0;
mPathList.clear();
mDirList.clear();
mWeightList.clear();
customEnvColors.clear();
Enhance: fix map downloading code, add manual XML map importing (#326) * Enhance: fix map downloading code, add manual XML map importing A recent move by I.R.E. to using SSL for their public MUD map URLs broke the ability for Mudlet to download those XML format files. This commit addresses this issue (as mentioned in, but not the original problem referred to in https://bugs.launchpad.net/mudlet/+bug/1427364) the revision to the code does now use "https://www.<MUD URL>/maps/map.xml" as a default name for the I.R.E. MUDS - however the method that initiates the download which was moved to TMap class from the dlgMapper one (see below) is now: (bool) TMap::downloadMap( const QString * remoteUrl = Q_NULLPTR, const QString * localFileName = Q_NULLPTR ) which if not supplied with any arguments behaves as before. However the remoteUrl argument may be given as a full QString including the scheme (the bit of the URL at the beginning before the ':') to override that and a second argument may be used to provide a different name to use for the local file name which if is a RELATIVE pathFileName will be resolved in relation to the profile directory. At present no use is made of this additional functionality but it may be useful for use with other MUDs if they should choose to provide XML map files with other remote locations and scripts using a different local filename. As a long-standing thing that needed doing I have finally provided a means to import a map XML file that - for instance - has already been download. It had been noted that there was no way to read those I.R.E. map files even if they had been obtained from a web browser able to correctly handle https: URLs - now both the TLuaInterpreter::loadMap() and the dlgProfilePreference "loadMap" button {NOT the IRE only "map download" one} will both handle files ending in ".xml" (not case sensitive so it'll work MacOS platforms as well!} For the loadMap case it will be necessary to change the filetype filter on the File Selection dialog to select "xml" files. During testing it became clear to me that it was possible to try and read one or more XML files via several mechanisms simultaneously with "unhelpful" consequences. As well as hitting the dlgProfilePreferences IRE "map download" multiple times, the TLuaInterpreter::loadMap() does NOT block until the map has been loaded and as the import time {running of XMLinport::readPackage(...)} is of significant duration for a large map (a debug, without optimisation, build on my 1.8GHz Quad-core took over two minutes to process the current Achaea map file) it is very possible to get conditions where the same profile will try to run XMLinport::readPackage(...) asynchronously - given that a profile only supports ONE map at a time it was necessary to fit a QMutex to prevent the part of the XMLinport class relating to XML Map files being called from different places in the map related code. This means that if a map download is started further downloads and any local map imports will fail until that first download has completed or aborted. Similarly a local import will prevent a download being started. As a side effect this cures: https://bugs.launchpad.net/mudlet/+bug/852861 - "Map download button starts another download thread if one is already going" The previous XML import code was not adding the rooms that it parsed to the relevant TArea::rooms member - although this would be picked-up and fixed by TMap::audit() later on, this would be accompanied by an error message about every single room. The code now builds up this information while parsing the rooms' details and inserts it so that this does not cause report-able problems during the TMap::audit() execution - the data gathered also allows missing areas to be spotted so that if a room claimed to belong to an area that was not included in the preceding areas' data an unnamed area is created for it. As a consequence of the long time to actually parse an XML map file I have enhanced the progress dialog that was originally used to track the map file download. It is now retained until the file is completely imported and shows more information about the process - importantly it shows during the XMLimport::readRoom(...) the room id being processed - and THAT method is the time/cpu hog so seeing something happening during the time that Mudlet otherwise appears to hang is useful feedback even if it adds a few seconds to the overall duration (may be more than a minute). This dialog is now also used during the other routes that involve reading an XML file and there is now a bit of consistence with the on-screen messages. Whilst inspecting XMLimport class I found there was some uncertain initialisation which I have tidied up. In summary: Added: * (bool) TConsole::importMap(const QString & location) * (void) TRoomDB::setAreaRooms(const int areaId, const QSet<int> & roomIds) * image file mudlet_map_download.png used as icon for download/import progress dialog * (bool) TMap::importMap(QFile & file) * (bool) TMap::readXmlMapFile(QFile & file) * (void) TMap::slot_downloadError(QNetworkReply::NetworkError error) * (void) TMap::reportStringToProgressDialog(const QString text) * (void) TMap::reportProgressToProgressDialog(const int current, const int maximum) Revised: * (int)TLuaInterpreter::loadMap( lua_State * ) * Moved XML map download code from dlgMapper class to the TMap one: + (void) dlgMapper::downloadMap() ==> (bool) TMap::downloadMap(const QString * remoteUrl, const QString * localFileName) + (void) dlgMapper::setDownloadProgress(qint64, qint64) ==> (void) TMap::slot_setDownloadProgress(qint64,qint64) + (void) dlgMapper::cancel() ==> (void) TMap::slot_downloadCancel() + (void) dlgMapper::replyFinished(QNetworkReply *) ==> (void) TMap::slot_replyFinished(QNetworkReply *) * Enhanced download progress indication to also include parsing which can take even more time than download! * Provide means to import local XML map file * Prevent trying to import/download more than one map at a time Renamed: * (void) XMLimport::readAreaNames() ==> XMLimport::readArea() - for consistency with related functions Commented out unused: * (void) XMLimport::readUnknownRoomElement() Note the movement of the map file download code to the TMap class does require making the latter a class with the Q_OBJECT macro (which removes the need for Q_DECLARE_TR_FUNCTIONS as a side-effect!) - though as another side-effect the TMap header needed a boost name specifier added to one identifier as that identifier ("property") exists in both boost and QObject classes!!! YOU MAY NEED TO RUN QMAKE ON THE PROJECT IF THE BUILD SYSTEM DOES NOT PICK UP THE ADDITION OF "Q_OBJECT" TO TMAP CLASS. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: Include missing #include, remove unused return value The absence of this was causing build errors on the Travis C.I. platform! Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: move TMap.h to mudlet_MOC_HDRS to fix CMake build issue As we have made TMap inherit from QOject - to have signal/slot functionality that class needs to be run through Qt's MOC - and to do that with the CMake project/build system it needs to be included in the files included in the projects *_MOC_HDRS {and removed from the *_HDRS} variable. Also spotted a trivial error in that specifying a const return value from method is ineffective and pointless - so removed it from: TMap::retrieveMapFileStats(QString,QString *,int *,int *,int *,int *) Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: clean up TMap initialisation/clearing actions Now restores the customEnvColors set up on initialisation but that was cleared when the map replaced with another one that is loaded {which subsequently replaces that element anyway} or imported {which merely writes over it, replacing any matching keys}. Initialises elements that when inspected on the entry to the constructor proper previously were not being set to a consistent value {booleans/ints/floats}. NOTE: This will now clear the map user data member when the map is cleared if the date is required to be saved when one map is loaded OR IMPORTED over an existing one then the data will need to be saved outside of the map - as is already need for areas and rooms user data! Also comment out or remove unused members/methods: * (void) TMap::getConnectedNodesGreaterThanX(int, int) * (void) TMap::getConnectedNodesSmallerThanX(int, int) * (void) TMap::getConnectedNodesGreaterThanY(int, int) * (void) TMap::getConnectedNodesSmallerThanY(int, int) * (void) TMap::astBreitenAnpassung(int, int) * (void) TMap::astHoehenAnpassung(int, int) * (void) TMap::exportMapToDatabase() * (void) TMap::importMapFromDatabase() * (QVector3D) TMap::span * (int) TMap::mViewArea * (QMap<QString, int>) TMap::pixNameTable * (QMap<int, QPixmap>) TMap::pixTable * (bool) TMap::isToDisplayAuditErrorsToConsole Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * ImplimentationFixes: activate a valid optimisation & remove redundant code Adding a true as a non-default 3rd argument to TRoomDB::addRoom(...) call in XMLimport::readRoom(...) enables a significant optimisation (skips a computationally expensive step when ADDING a room to new map) which dramatically reduces the time to parse an XML map file. It also pointed to the fact that the TRoomDB::entranceMap was already correctly being handled and didn't need to be regenerated in XMLimport::readRoom(...) so the code that was added in a previous commit was redundant and could be removed. A code error in TMap::slot_setDownloadProgress(...) that caused an issue that a reviewer found on test has been fixed - the total download filesize that was being sent by the Qt system signal that is connected to this slot was a -1 value (as IS DOCUMENTED) when the Qt system does NOT know the size of a QNetworkReply in advance of reaching the end of the download was incorrectly handled in a previous commit in this change set. Also found during testing that there is no need for an error message for the QNetworkReply::OperationCanceledError case in TMap::slot_replayFinished(...) as it is already handled in the TMap::slot_downloadCancel() slot. Changed the text put up onto the progress widget during the XML room parsing to be a room count - which is likely more useful and to only do it for every hundredth room - which reduces any delay "wasted" in writing to the display - combined, the effects seem satisfactory IMHO. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: provide error messages for TLuaInterpreter::loadMap(...) Errors for the XML map file importing process as initiated from the Lua command should be returned to that command rather than plastered onto the main profile console - this commit attempts to perform that effect. In testing found that there was no error handling for failure to find or open the nominated file so messages for that have been added as well. Due to the previous program logic the action of creating a mapper widget using the main toolbar button automatically loaded the "default" (the newest Mudlet Map file format file from the currently active profile's map sub-directory). Under some previous situations it looked as though a map might be loaded twice as mudlet::slot_mapper() was called both directly and via signal/slot action. These were resolved by turning that slot into a wrapper that now calls the body of code formerly within to a new method mudlet::createMapper( bool isToLoadDefaultMapFile = true ) with a the default value as an argument. This allows other usages of the body of code to be called directly with a suitable argument, which for the TConsole::loadMap() & TConsole::importMap() and the dlgProfilePreferences::downloadMap() cases is false as they are all do not want the "default" map! Also: * spotted a word "area" missing from an advisory text in TRoom::auditRooms(...). Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: fix minor bug, correct a spelling, undo a few capitalisations Under certain, unanticipated (error with no error message) conditions TLuaInterpreter::loadMap(...) would push both a nil and then a false value onto the stack for return {wrong} but only indicate one value {correct}. The textual matters were found during peer review. off-by: Stephen Lyons <slysven@virginmedia.com>
2016-10-13 09:18:48 +01:00
// Need to restore the default colours:
customEnvColors[257] = mpHost->mRed_2;
customEnvColors[258] = mpHost->mGreen_2;
customEnvColors[259] = mpHost->mYellow_2;
customEnvColors[260] = mpHost->mBlue_2;
customEnvColors[261] = mpHost->mMagenta_2;
customEnvColors[262] = mpHost->mCyan_2;
customEnvColors[263] = mpHost->mWhite_2;
customEnvColors[264] = mpHost->mBlack_2;
customEnvColors[265] = mpHost->mLightRed_2;
customEnvColors[266] = mpHost->mLightGreen_2;
customEnvColors[267] = mpHost->mLightYellow_2;
customEnvColors[268] = mpHost->mLightBlue_2;
customEnvColors[269] = mpHost->mLightMagenta_2;
customEnvColors[270] = mpHost->mLightCyan_2;
customEnvColors[271] = mpHost->mLightWhite_2;
customEnvColors[272] = mpHost->mLightBlack_2;
roomidToIndex.clear();
// Not used: pixNameTable.clear();
// Not used: pixTable.clear();
Enhance: fix map downloading code, add manual XML map importing (#326) * Enhance: fix map downloading code, add manual XML map importing A recent move by I.R.E. to using SSL for their public MUD map URLs broke the ability for Mudlet to download those XML format files. This commit addresses this issue (as mentioned in, but not the original problem referred to in https://bugs.launchpad.net/mudlet/+bug/1427364) the revision to the code does now use "https://www.<MUD URL>/maps/map.xml" as a default name for the I.R.E. MUDS - however the method that initiates the download which was moved to TMap class from the dlgMapper one (see below) is now: (bool) TMap::downloadMap( const QString * remoteUrl = Q_NULLPTR, const QString * localFileName = Q_NULLPTR ) which if not supplied with any arguments behaves as before. However the remoteUrl argument may be given as a full QString including the scheme (the bit of the URL at the beginning before the ':') to override that and a second argument may be used to provide a different name to use for the local file name which if is a RELATIVE pathFileName will be resolved in relation to the profile directory. At present no use is made of this additional functionality but it may be useful for use with other MUDs if they should choose to provide XML map files with other remote locations and scripts using a different local filename. As a long-standing thing that needed doing I have finally provided a means to import a map XML file that - for instance - has already been download. It had been noted that there was no way to read those I.R.E. map files even if they had been obtained from a web browser able to correctly handle https: URLs - now both the TLuaInterpreter::loadMap() and the dlgProfilePreference "loadMap" button {NOT the IRE only "map download" one} will both handle files ending in ".xml" (not case sensitive so it'll work MacOS platforms as well!} For the loadMap case it will be necessary to change the filetype filter on the File Selection dialog to select "xml" files. During testing it became clear to me that it was possible to try and read one or more XML files via several mechanisms simultaneously with "unhelpful" consequences. As well as hitting the dlgProfilePreferences IRE "map download" multiple times, the TLuaInterpreter::loadMap() does NOT block until the map has been loaded and as the import time {running of XMLinport::readPackage(...)} is of significant duration for a large map (a debug, without optimisation, build on my 1.8GHz Quad-core took over two minutes to process the current Achaea map file) it is very possible to get conditions where the same profile will try to run XMLinport::readPackage(...) asynchronously - given that a profile only supports ONE map at a time it was necessary to fit a QMutex to prevent the part of the XMLinport class relating to XML Map files being called from different places in the map related code. This means that if a map download is started further downloads and any local map imports will fail until that first download has completed or aborted. Similarly a local import will prevent a download being started. As a side effect this cures: https://bugs.launchpad.net/mudlet/+bug/852861 - "Map download button starts another download thread if one is already going" The previous XML import code was not adding the rooms that it parsed to the relevant TArea::rooms member - although this would be picked-up and fixed by TMap::audit() later on, this would be accompanied by an error message about every single room. The code now builds up this information while parsing the rooms' details and inserts it so that this does not cause report-able problems during the TMap::audit() execution - the data gathered also allows missing areas to be spotted so that if a room claimed to belong to an area that was not included in the preceding areas' data an unnamed area is created for it. As a consequence of the long time to actually parse an XML map file I have enhanced the progress dialog that was originally used to track the map file download. It is now retained until the file is completely imported and shows more information about the process - importantly it shows during the XMLimport::readRoom(...) the room id being processed - and THAT method is the time/cpu hog so seeing something happening during the time that Mudlet otherwise appears to hang is useful feedback even if it adds a few seconds to the overall duration (may be more than a minute). This dialog is now also used during the other routes that involve reading an XML file and there is now a bit of consistence with the on-screen messages. Whilst inspecting XMLimport class I found there was some uncertain initialisation which I have tidied up. In summary: Added: * (bool) TConsole::importMap(const QString & location) * (void) TRoomDB::setAreaRooms(const int areaId, const QSet<int> & roomIds) * image file mudlet_map_download.png used as icon for download/import progress dialog * (bool) TMap::importMap(QFile & file) * (bool) TMap::readXmlMapFile(QFile & file) * (void) TMap::slot_downloadError(QNetworkReply::NetworkError error) * (void) TMap::reportStringToProgressDialog(const QString text) * (void) TMap::reportProgressToProgressDialog(const int current, const int maximum) Revised: * (int)TLuaInterpreter::loadMap( lua_State * ) * Moved XML map download code from dlgMapper class to the TMap one: + (void) dlgMapper::downloadMap() ==> (bool) TMap::downloadMap(const QString * remoteUrl, const QString * localFileName) + (void) dlgMapper::setDownloadProgress(qint64, qint64) ==> (void) TMap::slot_setDownloadProgress(qint64,qint64) + (void) dlgMapper::cancel() ==> (void) TMap::slot_downloadCancel() + (void) dlgMapper::replyFinished(QNetworkReply *) ==> (void) TMap::slot_replyFinished(QNetworkReply *) * Enhanced download progress indication to also include parsing which can take even more time than download! * Provide means to import local XML map file * Prevent trying to import/download more than one map at a time Renamed: * (void) XMLimport::readAreaNames() ==> XMLimport::readArea() - for consistency with related functions Commented out unused: * (void) XMLimport::readUnknownRoomElement() Note the movement of the map file download code to the TMap class does require making the latter a class with the Q_OBJECT macro (which removes the need for Q_DECLARE_TR_FUNCTIONS as a side-effect!) - though as another side-effect the TMap header needed a boost name specifier added to one identifier as that identifier ("property") exists in both boost and QObject classes!!! YOU MAY NEED TO RUN QMAKE ON THE PROJECT IF THE BUILD SYSTEM DOES NOT PICK UP THE ADDITION OF "Q_OBJECT" TO TMAP CLASS. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: Include missing #include, remove unused return value The absence of this was causing build errors on the Travis C.I. platform! Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: move TMap.h to mudlet_MOC_HDRS to fix CMake build issue As we have made TMap inherit from QOject - to have signal/slot functionality that class needs to be run through Qt's MOC - and to do that with the CMake project/build system it needs to be included in the files included in the projects *_MOC_HDRS {and removed from the *_HDRS} variable. Also spotted a trivial error in that specifying a const return value from method is ineffective and pointless - so removed it from: TMap::retrieveMapFileStats(QString,QString *,int *,int *,int *,int *) Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: clean up TMap initialisation/clearing actions Now restores the customEnvColors set up on initialisation but that was cleared when the map replaced with another one that is loaded {which subsequently replaces that element anyway} or imported {which merely writes over it, replacing any matching keys}. Initialises elements that when inspected on the entry to the constructor proper previously were not being set to a consistent value {booleans/ints/floats}. NOTE: This will now clear the map user data member when the map is cleared if the date is required to be saved when one map is loaded OR IMPORTED over an existing one then the data will need to be saved outside of the map - as is already need for areas and rooms user data! Also comment out or remove unused members/methods: * (void) TMap::getConnectedNodesGreaterThanX(int, int) * (void) TMap::getConnectedNodesSmallerThanX(int, int) * (void) TMap::getConnectedNodesGreaterThanY(int, int) * (void) TMap::getConnectedNodesSmallerThanY(int, int) * (void) TMap::astBreitenAnpassung(int, int) * (void) TMap::astHoehenAnpassung(int, int) * (void) TMap::exportMapToDatabase() * (void) TMap::importMapFromDatabase() * (QVector3D) TMap::span * (int) TMap::mViewArea * (QMap<QString, int>) TMap::pixNameTable * (QMap<int, QPixmap>) TMap::pixTable * (bool) TMap::isToDisplayAuditErrorsToConsole Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * ImplimentationFixes: activate a valid optimisation & remove redundant code Adding a true as a non-default 3rd argument to TRoomDB::addRoom(...) call in XMLimport::readRoom(...) enables a significant optimisation (skips a computationally expensive step when ADDING a room to new map) which dramatically reduces the time to parse an XML map file. It also pointed to the fact that the TRoomDB::entranceMap was already correctly being handled and didn't need to be regenerated in XMLimport::readRoom(...) so the code that was added in a previous commit was redundant and could be removed. A code error in TMap::slot_setDownloadProgress(...) that caused an issue that a reviewer found on test has been fixed - the total download filesize that was being sent by the Qt system signal that is connected to this slot was a -1 value (as IS DOCUMENTED) when the Qt system does NOT know the size of a QNetworkReply in advance of reaching the end of the download was incorrectly handled in a previous commit in this change set. Also found during testing that there is no need for an error message for the QNetworkReply::OperationCanceledError case in TMap::slot_replayFinished(...) as it is already handled in the TMap::slot_downloadCancel() slot. Changed the text put up onto the progress widget during the XML room parsing to be a room count - which is likely more useful and to only do it for every hundredth room - which reduces any delay "wasted" in writing to the display - combined, the effects seem satisfactory IMHO. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: provide error messages for TLuaInterpreter::loadMap(...) Errors for the XML map file importing process as initiated from the Lua command should be returned to that command rather than plastered onto the main profile console - this commit attempts to perform that effect. In testing found that there was no error handling for failure to find or open the nominated file so messages for that have been added as well. Due to the previous program logic the action of creating a mapper widget using the main toolbar button automatically loaded the "default" (the newest Mudlet Map file format file from the currently active profile's map sub-directory). Under some previous situations it looked as though a map might be loaded twice as mudlet::slot_mapper() was called both directly and via signal/slot action. These were resolved by turning that slot into a wrapper that now calls the body of code formerly within to a new method mudlet::createMapper( bool isToLoadDefaultMapFile = true ) with a the default value as an argument. This allows other usages of the body of code to be called directly with a suitable argument, which for the TConsole::loadMap() & TConsole::importMap() and the dlgProfilePreferences::downloadMap() cases is false as they are all do not want the "default" map! Also: * spotted a word "area" missing from an advisory text in TRoom::auditRooms(...). Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: fix minor bug, correct a spelling, undo a few capitalisations Under certain, unanticipated (error with no error message) conditions TLuaInterpreter::loadMap(...) would push both a nil and then a false value onto the stack for return {wrong} but only indicate one value {correct}. The textual matters were found during peer review. off-by: Stephen Lyons <slysven@virginmedia.com>
2016-10-13 09:18:48 +01:00
edgeHash.clear();
locations.clear();
mMapGraphNeedsUpdate = true;
mNewMove = true;
mapLabels.clear();
Enhance: fix map downloading code, add manual XML map importing (#326) * Enhance: fix map downloading code, add manual XML map importing A recent move by I.R.E. to using SSL for their public MUD map URLs broke the ability for Mudlet to download those XML format files. This commit addresses this issue (as mentioned in, but not the original problem referred to in https://bugs.launchpad.net/mudlet/+bug/1427364) the revision to the code does now use "https://www.<MUD URL>/maps/map.xml" as a default name for the I.R.E. MUDS - however the method that initiates the download which was moved to TMap class from the dlgMapper one (see below) is now: (bool) TMap::downloadMap( const QString * remoteUrl = Q_NULLPTR, const QString * localFileName = Q_NULLPTR ) which if not supplied with any arguments behaves as before. However the remoteUrl argument may be given as a full QString including the scheme (the bit of the URL at the beginning before the ':') to override that and a second argument may be used to provide a different name to use for the local file name which if is a RELATIVE pathFileName will be resolved in relation to the profile directory. At present no use is made of this additional functionality but it may be useful for use with other MUDs if they should choose to provide XML map files with other remote locations and scripts using a different local filename. As a long-standing thing that needed doing I have finally provided a means to import a map XML file that - for instance - has already been download. It had been noted that there was no way to read those I.R.E. map files even if they had been obtained from a web browser able to correctly handle https: URLs - now both the TLuaInterpreter::loadMap() and the dlgProfilePreference "loadMap" button {NOT the IRE only "map download" one} will both handle files ending in ".xml" (not case sensitive so it'll work MacOS platforms as well!} For the loadMap case it will be necessary to change the filetype filter on the File Selection dialog to select "xml" files. During testing it became clear to me that it was possible to try and read one or more XML files via several mechanisms simultaneously with "unhelpful" consequences. As well as hitting the dlgProfilePreferences IRE "map download" multiple times, the TLuaInterpreter::loadMap() does NOT block until the map has been loaded and as the import time {running of XMLinport::readPackage(...)} is of significant duration for a large map (a debug, without optimisation, build on my 1.8GHz Quad-core took over two minutes to process the current Achaea map file) it is very possible to get conditions where the same profile will try to run XMLinport::readPackage(...) asynchronously - given that a profile only supports ONE map at a time it was necessary to fit a QMutex to prevent the part of the XMLinport class relating to XML Map files being called from different places in the map related code. This means that if a map download is started further downloads and any local map imports will fail until that first download has completed or aborted. Similarly a local import will prevent a download being started. As a side effect this cures: https://bugs.launchpad.net/mudlet/+bug/852861 - "Map download button starts another download thread if one is already going" The previous XML import code was not adding the rooms that it parsed to the relevant TArea::rooms member - although this would be picked-up and fixed by TMap::audit() later on, this would be accompanied by an error message about every single room. The code now builds up this information while parsing the rooms' details and inserts it so that this does not cause report-able problems during the TMap::audit() execution - the data gathered also allows missing areas to be spotted so that if a room claimed to belong to an area that was not included in the preceding areas' data an unnamed area is created for it. As a consequence of the long time to actually parse an XML map file I have enhanced the progress dialog that was originally used to track the map file download. It is now retained until the file is completely imported and shows more information about the process - importantly it shows during the XMLimport::readRoom(...) the room id being processed - and THAT method is the time/cpu hog so seeing something happening during the time that Mudlet otherwise appears to hang is useful feedback even if it adds a few seconds to the overall duration (may be more than a minute). This dialog is now also used during the other routes that involve reading an XML file and there is now a bit of consistence with the on-screen messages. Whilst inspecting XMLimport class I found there was some uncertain initialisation which I have tidied up. In summary: Added: * (bool) TConsole::importMap(const QString & location) * (void) TRoomDB::setAreaRooms(const int areaId, const QSet<int> & roomIds) * image file mudlet_map_download.png used as icon for download/import progress dialog * (bool) TMap::importMap(QFile & file) * (bool) TMap::readXmlMapFile(QFile & file) * (void) TMap::slot_downloadError(QNetworkReply::NetworkError error) * (void) TMap::reportStringToProgressDialog(const QString text) * (void) TMap::reportProgressToProgressDialog(const int current, const int maximum) Revised: * (int)TLuaInterpreter::loadMap( lua_State * ) * Moved XML map download code from dlgMapper class to the TMap one: + (void) dlgMapper::downloadMap() ==> (bool) TMap::downloadMap(const QString * remoteUrl, const QString * localFileName) + (void) dlgMapper::setDownloadProgress(qint64, qint64) ==> (void) TMap::slot_setDownloadProgress(qint64,qint64) + (void) dlgMapper::cancel() ==> (void) TMap::slot_downloadCancel() + (void) dlgMapper::replyFinished(QNetworkReply *) ==> (void) TMap::slot_replyFinished(QNetworkReply *) * Enhanced download progress indication to also include parsing which can take even more time than download! * Provide means to import local XML map file * Prevent trying to import/download more than one map at a time Renamed: * (void) XMLimport::readAreaNames() ==> XMLimport::readArea() - for consistency with related functions Commented out unused: * (void) XMLimport::readUnknownRoomElement() Note the movement of the map file download code to the TMap class does require making the latter a class with the Q_OBJECT macro (which removes the need for Q_DECLARE_TR_FUNCTIONS as a side-effect!) - though as another side-effect the TMap header needed a boost name specifier added to one identifier as that identifier ("property") exists in both boost and QObject classes!!! YOU MAY NEED TO RUN QMAKE ON THE PROJECT IF THE BUILD SYSTEM DOES NOT PICK UP THE ADDITION OF "Q_OBJECT" TO TMAP CLASS. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: Include missing #include, remove unused return value The absence of this was causing build errors on the Travis C.I. platform! Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: move TMap.h to mudlet_MOC_HDRS to fix CMake build issue As we have made TMap inherit from QOject - to have signal/slot functionality that class needs to be run through Qt's MOC - and to do that with the CMake project/build system it needs to be included in the files included in the projects *_MOC_HDRS {and removed from the *_HDRS} variable. Also spotted a trivial error in that specifying a const return value from method is ineffective and pointless - so removed it from: TMap::retrieveMapFileStats(QString,QString *,int *,int *,int *,int *) Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: clean up TMap initialisation/clearing actions Now restores the customEnvColors set up on initialisation but that was cleared when the map replaced with another one that is loaded {which subsequently replaces that element anyway} or imported {which merely writes over it, replacing any matching keys}. Initialises elements that when inspected on the entry to the constructor proper previously were not being set to a consistent value {booleans/ints/floats}. NOTE: This will now clear the map user data member when the map is cleared if the date is required to be saved when one map is loaded OR IMPORTED over an existing one then the data will need to be saved outside of the map - as is already need for areas and rooms user data! Also comment out or remove unused members/methods: * (void) TMap::getConnectedNodesGreaterThanX(int, int) * (void) TMap::getConnectedNodesSmallerThanX(int, int) * (void) TMap::getConnectedNodesGreaterThanY(int, int) * (void) TMap::getConnectedNodesSmallerThanY(int, int) * (void) TMap::astBreitenAnpassung(int, int) * (void) TMap::astHoehenAnpassung(int, int) * (void) TMap::exportMapToDatabase() * (void) TMap::importMapFromDatabase() * (QVector3D) TMap::span * (int) TMap::mViewArea * (QMap<QString, int>) TMap::pixNameTable * (QMap<int, QPixmap>) TMap::pixTable * (bool) TMap::isToDisplayAuditErrorsToConsole Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * ImplimentationFixes: activate a valid optimisation & remove redundant code Adding a true as a non-default 3rd argument to TRoomDB::addRoom(...) call in XMLimport::readRoom(...) enables a significant optimisation (skips a computationally expensive step when ADDING a room to new map) which dramatically reduces the time to parse an XML map file. It also pointed to the fact that the TRoomDB::entranceMap was already correctly being handled and didn't need to be regenerated in XMLimport::readRoom(...) so the code that was added in a previous commit was redundant and could be removed. A code error in TMap::slot_setDownloadProgress(...) that caused an issue that a reviewer found on test has been fixed - the total download filesize that was being sent by the Qt system signal that is connected to this slot was a -1 value (as IS DOCUMENTED) when the Qt system does NOT know the size of a QNetworkReply in advance of reaching the end of the download was incorrectly handled in a previous commit in this change set. Also found during testing that there is no need for an error message for the QNetworkReply::OperationCanceledError case in TMap::slot_replayFinished(...) as it is already handled in the TMap::slot_downloadCancel() slot. Changed the text put up onto the progress widget during the XML room parsing to be a room count - which is likely more useful and to only do it for every hundredth room - which reduces any delay "wasted" in writing to the display - combined, the effects seem satisfactory IMHO. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: provide error messages for TLuaInterpreter::loadMap(...) Errors for the XML map file importing process as initiated from the Lua command should be returned to that command rather than plastered onto the main profile console - this commit attempts to perform that effect. In testing found that there was no error handling for failure to find or open the nominated file so messages for that have been added as well. Due to the previous program logic the action of creating a mapper widget using the main toolbar button automatically loaded the "default" (the newest Mudlet Map file format file from the currently active profile's map sub-directory). Under some previous situations it looked as though a map might be loaded twice as mudlet::slot_mapper() was called both directly and via signal/slot action. These were resolved by turning that slot into a wrapper that now calls the body of code formerly within to a new method mudlet::createMapper( bool isToLoadDefaultMapFile = true ) with a the default value as an argument. This allows other usages of the body of code to be called directly with a suitable argument, which for the TConsole::loadMap() & TConsole::importMap() and the dlgProfilePreferences::downloadMap() cases is false as they are all do not want the "default" map! Also: * spotted a word "area" missing from an advisory text in TRoom::auditRooms(...). Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: fix minor bug, correct a spelling, undo a few capitalisations Under certain, unanticipated (error with no error message) conditions TLuaInterpreter::loadMap(...) would push both a nil and then a false value onto the stack for return {wrong} but only indicate one value {correct}. The textual matters were found during peer review. off-by: Stephen Lyons <slysven@virginmedia.com>
2016-10-13 09:18:48 +01:00
mVersion = mDefaultVersion;
mUserData.clear();
// mSaveVersion is not reset - so that any new Mudlet map file saves are to
// whatever version was previously set/deduced
}
void TMap::logError(QString& msg)
{
auto orange = QColor(255, 128, 0);
auto black = QColor(Qt::black);
QString s1 = QString("[MAP ERROR:]%1\n").arg(msg);
if (mpHost->mpEditorDialog) {
mpHost->mpEditorDialog->mpErrorConsole->printDebug(orange, black, s1);
}
}
Enhance: fix map downloading code, add manual XML map importing (#326) * Enhance: fix map downloading code, add manual XML map importing A recent move by I.R.E. to using SSL for their public MUD map URLs broke the ability for Mudlet to download those XML format files. This commit addresses this issue (as mentioned in, but not the original problem referred to in https://bugs.launchpad.net/mudlet/+bug/1427364) the revision to the code does now use "https://www.<MUD URL>/maps/map.xml" as a default name for the I.R.E. MUDS - however the method that initiates the download which was moved to TMap class from the dlgMapper one (see below) is now: (bool) TMap::downloadMap( const QString * remoteUrl = Q_NULLPTR, const QString * localFileName = Q_NULLPTR ) which if not supplied with any arguments behaves as before. However the remoteUrl argument may be given as a full QString including the scheme (the bit of the URL at the beginning before the ':') to override that and a second argument may be used to provide a different name to use for the local file name which if is a RELATIVE pathFileName will be resolved in relation to the profile directory. At present no use is made of this additional functionality but it may be useful for use with other MUDs if they should choose to provide XML map files with other remote locations and scripts using a different local filename. As a long-standing thing that needed doing I have finally provided a means to import a map XML file that - for instance - has already been download. It had been noted that there was no way to read those I.R.E. map files even if they had been obtained from a web browser able to correctly handle https: URLs - now both the TLuaInterpreter::loadMap() and the dlgProfilePreference "loadMap" button {NOT the IRE only "map download" one} will both handle files ending in ".xml" (not case sensitive so it'll work MacOS platforms as well!} For the loadMap case it will be necessary to change the filetype filter on the File Selection dialog to select "xml" files. During testing it became clear to me that it was possible to try and read one or more XML files via several mechanisms simultaneously with "unhelpful" consequences. As well as hitting the dlgProfilePreferences IRE "map download" multiple times, the TLuaInterpreter::loadMap() does NOT block until the map has been loaded and as the import time {running of XMLinport::readPackage(...)} is of significant duration for a large map (a debug, without optimisation, build on my 1.8GHz Quad-core took over two minutes to process the current Achaea map file) it is very possible to get conditions where the same profile will try to run XMLinport::readPackage(...) asynchronously - given that a profile only supports ONE map at a time it was necessary to fit a QMutex to prevent the part of the XMLinport class relating to XML Map files being called from different places in the map related code. This means that if a map download is started further downloads and any local map imports will fail until that first download has completed or aborted. Similarly a local import will prevent a download being started. As a side effect this cures: https://bugs.launchpad.net/mudlet/+bug/852861 - "Map download button starts another download thread if one is already going" The previous XML import code was not adding the rooms that it parsed to the relevant TArea::rooms member - although this would be picked-up and fixed by TMap::audit() later on, this would be accompanied by an error message about every single room. The code now builds up this information while parsing the rooms' details and inserts it so that this does not cause report-able problems during the TMap::audit() execution - the data gathered also allows missing areas to be spotted so that if a room claimed to belong to an area that was not included in the preceding areas' data an unnamed area is created for it. As a consequence of the long time to actually parse an XML map file I have enhanced the progress dialog that was originally used to track the map file download. It is now retained until the file is completely imported and shows more information about the process - importantly it shows during the XMLimport::readRoom(...) the room id being processed - and THAT method is the time/cpu hog so seeing something happening during the time that Mudlet otherwise appears to hang is useful feedback even if it adds a few seconds to the overall duration (may be more than a minute). This dialog is now also used during the other routes that involve reading an XML file and there is now a bit of consistence with the on-screen messages. Whilst inspecting XMLimport class I found there was some uncertain initialisation which I have tidied up. In summary: Added: * (bool) TConsole::importMap(const QString & location) * (void) TRoomDB::setAreaRooms(const int areaId, const QSet<int> & roomIds) * image file mudlet_map_download.png used as icon for download/import progress dialog * (bool) TMap::importMap(QFile & file) * (bool) TMap::readXmlMapFile(QFile & file) * (void) TMap::slot_downloadError(QNetworkReply::NetworkError error) * (void) TMap::reportStringToProgressDialog(const QString text) * (void) TMap::reportProgressToProgressDialog(const int current, const int maximum) Revised: * (int)TLuaInterpreter::loadMap( lua_State * ) * Moved XML map download code from dlgMapper class to the TMap one: + (void) dlgMapper::downloadMap() ==> (bool) TMap::downloadMap(const QString * remoteUrl, const QString * localFileName) + (void) dlgMapper::setDownloadProgress(qint64, qint64) ==> (void) TMap::slot_setDownloadProgress(qint64,qint64) + (void) dlgMapper::cancel() ==> (void) TMap::slot_downloadCancel() + (void) dlgMapper::replyFinished(QNetworkReply *) ==> (void) TMap::slot_replyFinished(QNetworkReply *) * Enhanced download progress indication to also include parsing which can take even more time than download! * Provide means to import local XML map file * Prevent trying to import/download more than one map at a time Renamed: * (void) XMLimport::readAreaNames() ==> XMLimport::readArea() - for consistency with related functions Commented out unused: * (void) XMLimport::readUnknownRoomElement() Note the movement of the map file download code to the TMap class does require making the latter a class with the Q_OBJECT macro (which removes the need for Q_DECLARE_TR_FUNCTIONS as a side-effect!) - though as another side-effect the TMap header needed a boost name specifier added to one identifier as that identifier ("property") exists in both boost and QObject classes!!! YOU MAY NEED TO RUN QMAKE ON THE PROJECT IF THE BUILD SYSTEM DOES NOT PICK UP THE ADDITION OF "Q_OBJECT" TO TMAP CLASS. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: Include missing #include, remove unused return value The absence of this was causing build errors on the Travis C.I. platform! Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: move TMap.h to mudlet_MOC_HDRS to fix CMake build issue As we have made TMap inherit from QOject - to have signal/slot functionality that class needs to be run through Qt's MOC - and to do that with the CMake project/build system it needs to be included in the files included in the projects *_MOC_HDRS {and removed from the *_HDRS} variable. Also spotted a trivial error in that specifying a const return value from method is ineffective and pointless - so removed it from: TMap::retrieveMapFileStats(QString,QString *,int *,int *,int *,int *) Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: clean up TMap initialisation/clearing actions Now restores the customEnvColors set up on initialisation but that was cleared when the map replaced with another one that is loaded {which subsequently replaces that element anyway} or imported {which merely writes over it, replacing any matching keys}. Initialises elements that when inspected on the entry to the constructor proper previously were not being set to a consistent value {booleans/ints/floats}. NOTE: This will now clear the map user data member when the map is cleared if the date is required to be saved when one map is loaded OR IMPORTED over an existing one then the data will need to be saved outside of the map - as is already need for areas and rooms user data! Also comment out or remove unused members/methods: * (void) TMap::getConnectedNodesGreaterThanX(int, int) * (void) TMap::getConnectedNodesSmallerThanX(int, int) * (void) TMap::getConnectedNodesGreaterThanY(int, int) * (void) TMap::getConnectedNodesSmallerThanY(int, int) * (void) TMap::astBreitenAnpassung(int, int) * (void) TMap::astHoehenAnpassung(int, int) * (void) TMap::exportMapToDatabase() * (void) TMap::importMapFromDatabase() * (QVector3D) TMap::span * (int) TMap::mViewArea * (QMap<QString, int>) TMap::pixNameTable * (QMap<int, QPixmap>) TMap::pixTable * (bool) TMap::isToDisplayAuditErrorsToConsole Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * ImplimentationFixes: activate a valid optimisation & remove redundant code Adding a true as a non-default 3rd argument to TRoomDB::addRoom(...) call in XMLimport::readRoom(...) enables a significant optimisation (skips a computationally expensive step when ADDING a room to new map) which dramatically reduces the time to parse an XML map file. It also pointed to the fact that the TRoomDB::entranceMap was already correctly being handled and didn't need to be regenerated in XMLimport::readRoom(...) so the code that was added in a previous commit was redundant and could be removed. A code error in TMap::slot_setDownloadProgress(...) that caused an issue that a reviewer found on test has been fixed - the total download filesize that was being sent by the Qt system signal that is connected to this slot was a -1 value (as IS DOCUMENTED) when the Qt system does NOT know the size of a QNetworkReply in advance of reaching the end of the download was incorrectly handled in a previous commit in this change set. Also found during testing that there is no need for an error message for the QNetworkReply::OperationCanceledError case in TMap::slot_replayFinished(...) as it is already handled in the TMap::slot_downloadCancel() slot. Changed the text put up onto the progress widget during the XML room parsing to be a room count - which is likely more useful and to only do it for every hundredth room - which reduces any delay "wasted" in writing to the display - combined, the effects seem satisfactory IMHO. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: provide error messages for TLuaInterpreter::loadMap(...) Errors for the XML map file importing process as initiated from the Lua command should be returned to that command rather than plastered onto the main profile console - this commit attempts to perform that effect. In testing found that there was no error handling for failure to find or open the nominated file so messages for that have been added as well. Due to the previous program logic the action of creating a mapper widget using the main toolbar button automatically loaded the "default" (the newest Mudlet Map file format file from the currently active profile's map sub-directory). Under some previous situations it looked as though a map might be loaded twice as mudlet::slot_mapper() was called both directly and via signal/slot action. These were resolved by turning that slot into a wrapper that now calls the body of code formerly within to a new method mudlet::createMapper( bool isToLoadDefaultMapFile = true ) with a the default value as an argument. This allows other usages of the body of code to be called directly with a suitable argument, which for the TConsole::loadMap() & TConsole::importMap() and the dlgProfilePreferences::downloadMap() cases is false as they are all do not want the "default" map! Also: * spotted a word "area" missing from an advisory text in TRoom::auditRooms(...). Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: fix minor bug, correct a spelling, undo a few capitalisations Under certain, unanticipated (error with no error message) conditions TLuaInterpreter::loadMap(...) would push both a nil and then a false value onto the stack for return {wrong} but only indicate one value {correct}. The textual matters were found during peer review. off-by: Stephen Lyons <slysven@virginmedia.com>
2016-10-13 09:18:48 +01:00
// Not used:
//void TMap::exportMapToDatabase()
//{
// QString dbName = QFileDialog::getSaveFileName( 0, "Chose db file name." );
// QString script = QString("exportMapToDatabse([[%1]])").arg(dbName);
// mpHost->mLuaInterpreter.compileAndExecuteScript( script );
//}
//void TMap::importMapFromDatabase()
//{
// QString dbName = QFileDialog::getOpenFileName( 0, "Chose db file name." );
// QString script = QString("importMapFromDatabase([[%1]])").arg(dbName);
// mpHost->mLuaInterpreter.compileAndExecuteScript( script );
//}
2011-06-16 09:49:34 +02:00
bool TMap::setRoomArea(int id, int area, bool isToDeferAreaRelatedRecalculations)
2011-06-16 09:49:34 +02:00
{
TRoom* pR = mpRoomDB->getRoom(id);
if (!pR) {
QString msg = tr("RoomID=%1 does not exist, can not set AreaID=%2 for non-existing room!").arg(id).arg(area);
logError(msg);
BugFix: Treat and prevent further duplicate or empty map area names Some steps had previously been taken to enforce no duplicate area names when importing an XML map or when adding a new name but other mechanisms were left unchecked, specifically this was when renaming an existing area. This commit adds a number of validation steps to many of the lua functions that manipulate areas and their names. This includes taking steps when creating a new TArea instance to ensure a suitable area name is created and added to the areaNamesMap which may be overwritten if a valid (non-empty, non-duplicate) name is provided at the time or later. This avoids problems with the Area selection widget on the 2 or 3D Map Display and the lua getAreaTable() function, neither of which will handle duplicate area names and for the former, does not handle nameless areas well either. The deleteArea() function could take either an area Id or a name as the target of its action so the area that is to be deleted is now not subject to any ambiguity if supplied as a name! Should a map file be loaded where empty or duplicated area names are found these will be "fixed" and warning messages inserted onto the main profile to explain what has happened. The user will only get this once per map file as there should now be no way to modified the map file to have either of these issues. The code that builds the area selection widget is revised to handle the corner cases of two areas that have the same letters in their name but the cases vary (the widget is sorted by name in a case insensitive manner) which previously was not handled (same as duplicate names were not). As a side effect of revising the TLuaInterpreter Class, area names containing non-ASCII characters can now be handled - they will be passed through the lua subsystem using the UTF-8 encoding. *** This commit is a reworking of one that produced a QMessageBox to alert and advised the user what was happening - that was deemed to be too intrusive so this version instead displays the information in the console - as such the detail of the renaming has to be shown now whereas the dialog solution had the option of providing it as "Show Details..." to display it only if requested at the time. *** Additionally, the lua setAreaName(areaId, newAreaName) has been extended to allow the existing area to be specified as a name (string) as well as an Id as we can now uniquely identify it by that means. This now matches the behaviour of deleteArea which already acts in that manner. It also means a user script can use "setAreaNAme(oldName, newName)" to rename an area without concern about determining the area Id. Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-01-09 03:51:50 +00:00
return false;
}
TArea* pA = mpRoomDB->getArea(area);
if (!pA) {
// Uh oh, the area doesn't seem to exist as a TArea instance, lets check
// to see if it exists as a name only:
if (!mpRoomDB->getAreaNamesMap().contains(area)) {
// Ah, no it doesn't so moan:
QString msg = tr("AreaID=%2 does not exist, can not set RoomID=%1 to non-existing area!").arg(id).arg(area);
logError(msg);
return false;
}
// If got to this point then there is NOT a TArea instance for the given
// area Id but there is a Name - and the pR->setArea(...) call WILL
// instantiate the required TArea structure - this seems a bit twisty
// and convoluted, but it was how previous code was wired up and we need
// to retain the API for the lua subsystem...
}
2011-06-16 09:49:34 +02:00
bool result = pR->setArea(area, isToDeferAreaRelatedRecalculations);
if (result) {
Revise: massage Area Exit data to required format and ensure it is correct Rename: (void)TArea::fast_ausgaengeBestimmen(int) ==> TArea::determineAreaExitsOfRoom (void)TArea::ausgaengeBestimmen(int) ==> TArea::determineAreaExits (const)(QList<int>)TArea::getAreaExits() const ==> TArea::getAreaExitRoomIds() Add new method to return area exit data in new, wanted format: (const)(QMultiMap<int, QPair<QString, int> >) getAreaExitRoomData() const In preparation to revising internal storage representation of area exit data moved the: (QMultiMap<int, QPair<int, int> >)(TArea *)->exits member from public to private area of class. To permit save and load the following have had to be made friends of the TArea class: (bool)TMap::serialize( QDataStream & ) and (bool)TMap::restore( QString ) Revise (void)TMap::init(Host *) to run (TArea *)->determineAreaExits() on current and all previous map file format versions, will not be needed on future version as the code to manage the areaExits data is now functional. Previous code would have done this only for versions prior to 14 files (current is 16) or if the lua function auditAreas() was manually run. In passing also modified code that "fixed-up" "old style" map labels so that it is no longer run on current version files and pushes any messages that that creates into the main profile console instead of using standard C++ cout calls which we deprecate now. All code blocks that have been touched by this series of commits have been re-formatted to current styles. Update copyrights on all files touched that have not already been marked as having been edited by myself. Revised TLuaInterpreter::getAreaExits(...) to take a second optional Boolean that if present and true cause it to return data about the area exit directions and the destination rooms, if false or omitted, returns only the rooms in the area that have exits out of it, reproducing the previous implementation. In either case the result is a table if there are area exits (or a nil for an isolate area without exits); two additional values are returned an informative, translatable, text message and an integer status code that reflects the same information. When moving a series of rooms to a different area via the 2D mapper's GUI the recalculations for the area extremes {by TArea::calcSpan()} and the out of area exits {by TArea::determineAreaExits()} can now be deferred until the last room has been moved by passing a third true (boolean) argument to TMap::setRoomArea(...) which defaults to false for other single room at a time usages. Though that method keeps a local copy of the areas that have been modified and thus need updating, should the last room NOT be processed (null TRooo pointer for room Id) a publicly accessible "mIsDirty" flag is also used so that recovery code can identify and clean up those affected areas otherwise. It is possible that this flag may be useful in other situations, such as when moving or adding multiple rooms WITHIN an area. *** This commit has been rebased so it's history might not be the same as someone else's copy of it *** Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-01-05 01:20:15 +00:00
mMapGraphNeedsUpdate = true;
}
return result;
2011-01-11 08:44:38 +01:00
}
bool TMap::addRoom(int id)
2010-09-07 20:35:32 +02:00
{
bool ret = mpRoomDB->addRoom(id);
if (ret) {
mMapGraphNeedsUpdate = true;
}
2013-03-22 12:47:58 +01:00
return ret;
2010-09-07 20:35:32 +02:00
}
bool TMap::setRoomCoordinates(int id, int x, int y, int z)
2010-09-07 20:35:32 +02:00
{
TRoom* pR = mpRoomDB->getRoom(id);
if (!pR) {
return false;
}
2010-09-07 20:35:32 +02:00
2013-03-22 12:47:58 +01:00
pR->x = x;
pR->y = y;
pR->z = z;
2010-12-28 23:31:03 +01:00
2010-09-07 20:35:32 +02:00
return true;
}
int compSign(int a, int b)
{
return (a < 0) == (b < 0);
}
2013-03-22 12:47:58 +01:00
void TMap::connectExitStub(int roomId, int dirType)
{
TRoom* pR = mpRoomDB->getRoom(roomId);
if (!pR) {
Enhance: 2D Map Room Selection, better big map performance + other mods In situations when we check whether a room in an area both for internal purposes and when rooms on a mapper is selected, using QSet instead of a QList is faster in performance for large numbers of entries in set. As it reworks the mapper code it also fixes issue where the multi-room selection widget overwrites map info display - the latter is re-sized and re-positioned (and regains a semi-transparent background which helped to show this working during debugging!) The former is now: dynamically resized to only take up enough vertical space to show the selected rooms; also displays the associate room names if there are any, expanding the widget as required; sorts the display either by room name or number and in either direction. The mouse wheel handler is modified so that using the scroll wheel ONLY scrolls the list within the widget - previously (by default) once the end in either direction was hit the related events would be passed up the widget chain where it would otherwise invoke the 2D mapper's zoom in/out code. In modifying the zoom in/out code I have replaced the (obsoleted in Qt5.x) QWheelEvent::delta() method to use the QWheelEvent::angleDelta() method, using only the Y-component the latter provides. If the Control modifier is active the zoom value is modified by an extra x10 factor which is useful when working with large maps as otherwise the zooming rate is "slow" at high values - ideally the control should be logarithmic or exponential or some other "non-linear" algorithm to work more uniformly over the range of practical use cases. The code to paint the map info text has been revised also to use the mMapInfoRect which was being defined but NOT used. The info text now reports whether the room name is for the player room {set via the Lua command centerview(roomId)} or is one that is selected by mouse dragging - and if more than one room is selected by that indicates the count of rooms in the selection. In the case of multiple rooms being selected the room that single room context menu operations will act upon is highlighted by the same style of yellow target used to show the custom exit line destination but is drawn in a different point in the code so that it is drawn over the rooms. Because of the change to the way that multiple rooms are selected routines that use that information had to be revised - in doing so it was possible to improve the usability/operation of: T2DMap::slot_movePosition() T2DMap::slot_setCharacter() T2DMap::slot_spread() T2DMap::slot_shrink() T2DMap::slot_lockRoom(): T2DMap::slot_unlockRoom(): This method, also resurrected here to the 2D mapper context menu, as it is also affected by the changes: T2DMap::slot_setPlayerLocation() There was a slot_setPlayerLocation code that set a global lua variable mRoomSet and moved the player to that room Id (introduced in commit-c25faf4e 2012-05-04 07:44:36 by Heiko) but the corresponding 2D Mapper context menu item that called it was commented out and thus removed from the menu in commit-93f65962 2012-12-29 01:16:28 also by Heiko without any explaination. Since that has not been used since then I have replaced it with a new Event: sysManualLocationSetEvent with a single numeric value which is the new (valid) room Id number - user scripts can capture this event if they want to know that the user has manually re-positioned the current player room in the 2D mapper. In passing: * Fixed Text font changing between docked and un-docked forms of the built-in map widget (when not incorporated into a console) - as it was not previously explicitly set it assumed the Application one whilst docked but the Qt System one when a free floating widget - and the two do not have to be the same. This fixes: https://bugs.launchpad.net/mudlet/+bug/1432841 . * Starts to fix https://bugs.launchpad.net/mudlet/+bug/1376511 by changing from use of obsolete QWheelEvent::delta() to QWheelEvent::angleDelta() in T2DMap::wheelEvent(...); will need duplicating in TTextEdit::wheelEvent(...) and GLWidget::wheelEvent(...) . * Adds the profile name to the Mapper dockable widget so that it's parentage can be determined when multiple profiles are active. Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2016-03-08 08:35:07 +00:00
return;
}
2013-03-22 12:47:58 +01:00
int area = pR->getArea();
int minDistance = 999999;
int minDistanceRoom = 0, meanSquareDistance = 0;
if (!unitVectors.contains(dirType)) {
return;
}
QVector3D unitVector = unitVectors[dirType];
int ux = unitVector.x(), uy = unitVector.y(), uz = unitVector.z();
2013-03-22 12:47:58 +01:00
int rx = pR->x, ry = pR->y, rz = pR->z;
int dx = 0, dy = 0, dz = 0;
TArea* pA = mpRoomDB->getArea(area);
if (!pA) {
Enhance: 2D Map Room Selection, better big map performance + other mods In situations when we check whether a room in an area both for internal purposes and when rooms on a mapper is selected, using QSet instead of a QList is faster in performance for large numbers of entries in set. As it reworks the mapper code it also fixes issue where the multi-room selection widget overwrites map info display - the latter is re-sized and re-positioned (and regains a semi-transparent background which helped to show this working during debugging!) The former is now: dynamically resized to only take up enough vertical space to show the selected rooms; also displays the associate room names if there are any, expanding the widget as required; sorts the display either by room name or number and in either direction. The mouse wheel handler is modified so that using the scroll wheel ONLY scrolls the list within the widget - previously (by default) once the end in either direction was hit the related events would be passed up the widget chain where it would otherwise invoke the 2D mapper's zoom in/out code. In modifying the zoom in/out code I have replaced the (obsoleted in Qt5.x) QWheelEvent::delta() method to use the QWheelEvent::angleDelta() method, using only the Y-component the latter provides. If the Control modifier is active the zoom value is modified by an extra x10 factor which is useful when working with large maps as otherwise the zooming rate is "slow" at high values - ideally the control should be logarithmic or exponential or some other "non-linear" algorithm to work more uniformly over the range of practical use cases. The code to paint the map info text has been revised also to use the mMapInfoRect which was being defined but NOT used. The info text now reports whether the room name is for the player room {set via the Lua command centerview(roomId)} or is one that is selected by mouse dragging - and if more than one room is selected by that indicates the count of rooms in the selection. In the case of multiple rooms being selected the room that single room context menu operations will act upon is highlighted by the same style of yellow target used to show the custom exit line destination but is drawn in a different point in the code so that it is drawn over the rooms. Because of the change to the way that multiple rooms are selected routines that use that information had to be revised - in doing so it was possible to improve the usability/operation of: T2DMap::slot_movePosition() T2DMap::slot_setCharacter() T2DMap::slot_spread() T2DMap::slot_shrink() T2DMap::slot_lockRoom(): T2DMap::slot_unlockRoom(): This method, also resurrected here to the 2D mapper context menu, as it is also affected by the changes: T2DMap::slot_setPlayerLocation() There was a slot_setPlayerLocation code that set a global lua variable mRoomSet and moved the player to that room Id (introduced in commit-c25faf4e 2012-05-04 07:44:36 by Heiko) but the corresponding 2D Mapper context menu item that called it was commented out and thus removed from the menu in commit-93f65962 2012-12-29 01:16:28 also by Heiko without any explaination. Since that has not been used since then I have replaced it with a new Event: sysManualLocationSetEvent with a single numeric value which is the new (valid) room Id number - user scripts can capture this event if they want to know that the user has manually re-positioned the current player room in the 2D mapper. In passing: * Fixed Text font changing between docked and un-docked forms of the built-in map widget (when not incorporated into a console) - as it was not previously explicitly set it assumed the Application one whilst docked but the Qt System one when a free floating widget - and the two do not have to be the same. This fixes: https://bugs.launchpad.net/mudlet/+bug/1432841 . * Starts to fix https://bugs.launchpad.net/mudlet/+bug/1376511 by changing from use of obsolete QWheelEvent::delta() to QWheelEvent::angleDelta() in T2DMap::wheelEvent(...); will need duplicating in TTextEdit::wheelEvent(...) and GLWidget::wheelEvent(...) . * Adds the profile name to the Mapper dockable widget so that it's parentage can be determined when multiple profiles are active. Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2016-03-08 08:35:07 +00:00
return;
}
QSetIterator<int> itRoom(pA->getAreaRooms());
while (itRoom.hasNext()) {
pR = mpRoomDB->getRoom(itRoom.next());
if (!pR) {
Enhance: 2D Map Room Selection, better big map performance + other mods In situations when we check whether a room in an area both for internal purposes and when rooms on a mapper is selected, using QSet instead of a QList is faster in performance for large numbers of entries in set. As it reworks the mapper code it also fixes issue where the multi-room selection widget overwrites map info display - the latter is re-sized and re-positioned (and regains a semi-transparent background which helped to show this working during debugging!) The former is now: dynamically resized to only take up enough vertical space to show the selected rooms; also displays the associate room names if there are any, expanding the widget as required; sorts the display either by room name or number and in either direction. The mouse wheel handler is modified so that using the scroll wheel ONLY scrolls the list within the widget - previously (by default) once the end in either direction was hit the related events would be passed up the widget chain where it would otherwise invoke the 2D mapper's zoom in/out code. In modifying the zoom in/out code I have replaced the (obsoleted in Qt5.x) QWheelEvent::delta() method to use the QWheelEvent::angleDelta() method, using only the Y-component the latter provides. If the Control modifier is active the zoom value is modified by an extra x10 factor which is useful when working with large maps as otherwise the zooming rate is "slow" at high values - ideally the control should be logarithmic or exponential or some other "non-linear" algorithm to work more uniformly over the range of practical use cases. The code to paint the map info text has been revised also to use the mMapInfoRect which was being defined but NOT used. The info text now reports whether the room name is for the player room {set via the Lua command centerview(roomId)} or is one that is selected by mouse dragging - and if more than one room is selected by that indicates the count of rooms in the selection. In the case of multiple rooms being selected the room that single room context menu operations will act upon is highlighted by the same style of yellow target used to show the custom exit line destination but is drawn in a different point in the code so that it is drawn over the rooms. Because of the change to the way that multiple rooms are selected routines that use that information had to be revised - in doing so it was possible to improve the usability/operation of: T2DMap::slot_movePosition() T2DMap::slot_setCharacter() T2DMap::slot_spread() T2DMap::slot_shrink() T2DMap::slot_lockRoom(): T2DMap::slot_unlockRoom(): This method, also resurrected here to the 2D mapper context menu, as it is also affected by the changes: T2DMap::slot_setPlayerLocation() There was a slot_setPlayerLocation code that set a global lua variable mRoomSet and moved the player to that room Id (introduced in commit-c25faf4e 2012-05-04 07:44:36 by Heiko) but the corresponding 2D Mapper context menu item that called it was commented out and thus removed from the menu in commit-93f65962 2012-12-29 01:16:28 also by Heiko without any explaination. Since that has not been used since then I have replaced it with a new Event: sysManualLocationSetEvent with a single numeric value which is the new (valid) room Id number - user scripts can capture this event if they want to know that the user has manually re-positioned the current player room in the 2D mapper. In passing: * Fixed Text font changing between docked and un-docked forms of the built-in map widget (when not incorporated into a console) - as it was not previously explicitly set it assumed the Application one whilst docked but the Qt System one when a free floating widget - and the two do not have to be the same. This fixes: https://bugs.launchpad.net/mudlet/+bug/1432841 . * Starts to fix https://bugs.launchpad.net/mudlet/+bug/1376511 by changing from use of obsolete QWheelEvent::delta() to QWheelEvent::angleDelta() in T2DMap::wheelEvent(...); will need duplicating in TTextEdit::wheelEvent(...) and GLWidget::wheelEvent(...) . * Adds the profile name to the Mapper dockable widget so that it's parentage can be determined when multiple profiles are active. Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2016-03-08 08:35:07 +00:00
continue;
}
if (pR->getId() == roomId) {
Enhance: 2D Map Room Selection, better big map performance + other mods In situations when we check whether a room in an area both for internal purposes and when rooms on a mapper is selected, using QSet instead of a QList is faster in performance for large numbers of entries in set. As it reworks the mapper code it also fixes issue where the multi-room selection widget overwrites map info display - the latter is re-sized and re-positioned (and regains a semi-transparent background which helped to show this working during debugging!) The former is now: dynamically resized to only take up enough vertical space to show the selected rooms; also displays the associate room names if there are any, expanding the widget as required; sorts the display either by room name or number and in either direction. The mouse wheel handler is modified so that using the scroll wheel ONLY scrolls the list within the widget - previously (by default) once the end in either direction was hit the related events would be passed up the widget chain where it would otherwise invoke the 2D mapper's zoom in/out code. In modifying the zoom in/out code I have replaced the (obsoleted in Qt5.x) QWheelEvent::delta() method to use the QWheelEvent::angleDelta() method, using only the Y-component the latter provides. If the Control modifier is active the zoom value is modified by an extra x10 factor which is useful when working with large maps as otherwise the zooming rate is "slow" at high values - ideally the control should be logarithmic or exponential or some other "non-linear" algorithm to work more uniformly over the range of practical use cases. The code to paint the map info text has been revised also to use the mMapInfoRect which was being defined but NOT used. The info text now reports whether the room name is for the player room {set via the Lua command centerview(roomId)} or is one that is selected by mouse dragging - and if more than one room is selected by that indicates the count of rooms in the selection. In the case of multiple rooms being selected the room that single room context menu operations will act upon is highlighted by the same style of yellow target used to show the custom exit line destination but is drawn in a different point in the code so that it is drawn over the rooms. Because of the change to the way that multiple rooms are selected routines that use that information had to be revised - in doing so it was possible to improve the usability/operation of: T2DMap::slot_movePosition() T2DMap::slot_setCharacter() T2DMap::slot_spread() T2DMap::slot_shrink() T2DMap::slot_lockRoom(): T2DMap::slot_unlockRoom(): This method, also resurrected here to the 2D mapper context menu, as it is also affected by the changes: T2DMap::slot_setPlayerLocation() There was a slot_setPlayerLocation code that set a global lua variable mRoomSet and moved the player to that room Id (introduced in commit-c25faf4e 2012-05-04 07:44:36 by Heiko) but the corresponding 2D Mapper context menu item that called it was commented out and thus removed from the menu in commit-93f65962 2012-12-29 01:16:28 also by Heiko without any explaination. Since that has not been used since then I have replaced it with a new Event: sysManualLocationSetEvent with a single numeric value which is the new (valid) room Id number - user scripts can capture this event if they want to know that the user has manually re-positioned the current player room in the 2D mapper. In passing: * Fixed Text font changing between docked and un-docked forms of the built-in map widget (when not incorporated into a console) - as it was not previously explicitly set it assumed the Application one whilst docked but the Qt System one when a free floating widget - and the two do not have to be the same. This fixes: https://bugs.launchpad.net/mudlet/+bug/1432841 . * Starts to fix https://bugs.launchpad.net/mudlet/+bug/1376511 by changing from use of obsolete QWheelEvent::delta() to QWheelEvent::angleDelta() in T2DMap::wheelEvent(...); will need duplicating in TTextEdit::wheelEvent(...) and GLWidget::wheelEvent(...) . * Adds the profile name to the Mapper dockable widget so that it's parentage can be determined when multiple profiles are active. Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2016-03-08 08:35:07 +00:00
continue;
}
if (uz) {
dz = pR->z - rz;
if (!compSign(dz, uz) || !dz) {
Enhance: 2D Map Room Selection, better big map performance + other mods In situations when we check whether a room in an area both for internal purposes and when rooms on a mapper is selected, using QSet instead of a QList is faster in performance for large numbers of entries in set. As it reworks the mapper code it also fixes issue where the multi-room selection widget overwrites map info display - the latter is re-sized and re-positioned (and regains a semi-transparent background which helped to show this working during debugging!) The former is now: dynamically resized to only take up enough vertical space to show the selected rooms; also displays the associate room names if there are any, expanding the widget as required; sorts the display either by room name or number and in either direction. The mouse wheel handler is modified so that using the scroll wheel ONLY scrolls the list within the widget - previously (by default) once the end in either direction was hit the related events would be passed up the widget chain where it would otherwise invoke the 2D mapper's zoom in/out code. In modifying the zoom in/out code I have replaced the (obsoleted in Qt5.x) QWheelEvent::delta() method to use the QWheelEvent::angleDelta() method, using only the Y-component the latter provides. If the Control modifier is active the zoom value is modified by an extra x10 factor which is useful when working with large maps as otherwise the zooming rate is "slow" at high values - ideally the control should be logarithmic or exponential or some other "non-linear" algorithm to work more uniformly over the range of practical use cases. The code to paint the map info text has been revised also to use the mMapInfoRect which was being defined but NOT used. The info text now reports whether the room name is for the player room {set via the Lua command centerview(roomId)} or is one that is selected by mouse dragging - and if more than one room is selected by that indicates the count of rooms in the selection. In the case of multiple rooms being selected the room that single room context menu operations will act upon is highlighted by the same style of yellow target used to show the custom exit line destination but is drawn in a different point in the code so that it is drawn over the rooms. Because of the change to the way that multiple rooms are selected routines that use that information had to be revised - in doing so it was possible to improve the usability/operation of: T2DMap::slot_movePosition() T2DMap::slot_setCharacter() T2DMap::slot_spread() T2DMap::slot_shrink() T2DMap::slot_lockRoom(): T2DMap::slot_unlockRoom(): This method, also resurrected here to the 2D mapper context menu, as it is also affected by the changes: T2DMap::slot_setPlayerLocation() There was a slot_setPlayerLocation code that set a global lua variable mRoomSet and moved the player to that room Id (introduced in commit-c25faf4e 2012-05-04 07:44:36 by Heiko) but the corresponding 2D Mapper context menu item that called it was commented out and thus removed from the menu in commit-93f65962 2012-12-29 01:16:28 also by Heiko without any explaination. Since that has not been used since then I have replaced it with a new Event: sysManualLocationSetEvent with a single numeric value which is the new (valid) room Id number - user scripts can capture this event if they want to know that the user has manually re-positioned the current player room in the 2D mapper. In passing: * Fixed Text font changing between docked and un-docked forms of the built-in map widget (when not incorporated into a console) - as it was not previously explicitly set it assumed the Application one whilst docked but the Qt System one when a free floating widget - and the two do not have to be the same. This fixes: https://bugs.launchpad.net/mudlet/+bug/1432841 . * Starts to fix https://bugs.launchpad.net/mudlet/+bug/1376511 by changing from use of obsolete QWheelEvent::delta() to QWheelEvent::angleDelta() in T2DMap::wheelEvent(...); will need duplicating in TTextEdit::wheelEvent(...) and GLWidget::wheelEvent(...) . * Adds the profile name to the Mapper dockable widget so that it's parentage can be determined when multiple profiles are active. Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2016-03-08 08:35:07 +00:00
continue;
}
} else {
//to avoid lower/upper floors from stealing stubs
if (pR->z != rz) {
Enhance: 2D Map Room Selection, better big map performance + other mods In situations when we check whether a room in an area both for internal purposes and when rooms on a mapper is selected, using QSet instead of a QList is faster in performance for large numbers of entries in set. As it reworks the mapper code it also fixes issue where the multi-room selection widget overwrites map info display - the latter is re-sized and re-positioned (and regains a semi-transparent background which helped to show this working during debugging!) The former is now: dynamically resized to only take up enough vertical space to show the selected rooms; also displays the associate room names if there are any, expanding the widget as required; sorts the display either by room name or number and in either direction. The mouse wheel handler is modified so that using the scroll wheel ONLY scrolls the list within the widget - previously (by default) once the end in either direction was hit the related events would be passed up the widget chain where it would otherwise invoke the 2D mapper's zoom in/out code. In modifying the zoom in/out code I have replaced the (obsoleted in Qt5.x) QWheelEvent::delta() method to use the QWheelEvent::angleDelta() method, using only the Y-component the latter provides. If the Control modifier is active the zoom value is modified by an extra x10 factor which is useful when working with large maps as otherwise the zooming rate is "slow" at high values - ideally the control should be logarithmic or exponential or some other "non-linear" algorithm to work more uniformly over the range of practical use cases. The code to paint the map info text has been revised also to use the mMapInfoRect which was being defined but NOT used. The info text now reports whether the room name is for the player room {set via the Lua command centerview(roomId)} or is one that is selected by mouse dragging - and if more than one room is selected by that indicates the count of rooms in the selection. In the case of multiple rooms being selected the room that single room context menu operations will act upon is highlighted by the same style of yellow target used to show the custom exit line destination but is drawn in a different point in the code so that it is drawn over the rooms. Because of the change to the way that multiple rooms are selected routines that use that information had to be revised - in doing so it was possible to improve the usability/operation of: T2DMap::slot_movePosition() T2DMap::slot_setCharacter() T2DMap::slot_spread() T2DMap::slot_shrink() T2DMap::slot_lockRoom(): T2DMap::slot_unlockRoom(): This method, also resurrected here to the 2D mapper context menu, as it is also affected by the changes: T2DMap::slot_setPlayerLocation() There was a slot_setPlayerLocation code that set a global lua variable mRoomSet and moved the player to that room Id (introduced in commit-c25faf4e 2012-05-04 07:44:36 by Heiko) but the corresponding 2D Mapper context menu item that called it was commented out and thus removed from the menu in commit-93f65962 2012-12-29 01:16:28 also by Heiko without any explaination. Since that has not been used since then I have replaced it with a new Event: sysManualLocationSetEvent with a single numeric value which is the new (valid) room Id number - user scripts can capture this event if they want to know that the user has manually re-positioned the current player room in the 2D mapper. In passing: * Fixed Text font changing between docked and un-docked forms of the built-in map widget (when not incorporated into a console) - as it was not previously explicitly set it assumed the Application one whilst docked but the Qt System one when a free floating widget - and the two do not have to be the same. This fixes: https://bugs.launchpad.net/mudlet/+bug/1432841 . * Starts to fix https://bugs.launchpad.net/mudlet/+bug/1376511 by changing from use of obsolete QWheelEvent::delta() to QWheelEvent::angleDelta() in T2DMap::wheelEvent(...); will need duplicating in TTextEdit::wheelEvent(...) and GLWidget::wheelEvent(...) . * Adds the profile name to the Mapper dockable widget so that it's parentage can be determined when multiple profiles are active. Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2016-03-08 08:35:07 +00:00
continue;
}
}
if (ux) {
dx = pR->x - rx;
if (!compSign(dx, ux) || !dx) //we do !dx to make sure we have a component in the desired direction
Enhance: 2D Map Room Selection, better big map performance + other mods In situations when we check whether a room in an area both for internal purposes and when rooms on a mapper is selected, using QSet instead of a QList is faster in performance for large numbers of entries in set. As it reworks the mapper code it also fixes issue where the multi-room selection widget overwrites map info display - the latter is re-sized and re-positioned (and regains a semi-transparent background which helped to show this working during debugging!) The former is now: dynamically resized to only take up enough vertical space to show the selected rooms; also displays the associate room names if there are any, expanding the widget as required; sorts the display either by room name or number and in either direction. The mouse wheel handler is modified so that using the scroll wheel ONLY scrolls the list within the widget - previously (by default) once the end in either direction was hit the related events would be passed up the widget chain where it would otherwise invoke the 2D mapper's zoom in/out code. In modifying the zoom in/out code I have replaced the (obsoleted in Qt5.x) QWheelEvent::delta() method to use the QWheelEvent::angleDelta() method, using only the Y-component the latter provides. If the Control modifier is active the zoom value is modified by an extra x10 factor which is useful when working with large maps as otherwise the zooming rate is "slow" at high values - ideally the control should be logarithmic or exponential or some other "non-linear" algorithm to work more uniformly over the range of practical use cases. The code to paint the map info text has been revised also to use the mMapInfoRect which was being defined but NOT used. The info text now reports whether the room name is for the player room {set via the Lua command centerview(roomId)} or is one that is selected by mouse dragging - and if more than one room is selected by that indicates the count of rooms in the selection. In the case of multiple rooms being selected the room that single room context menu operations will act upon is highlighted by the same style of yellow target used to show the custom exit line destination but is drawn in a different point in the code so that it is drawn over the rooms. Because of the change to the way that multiple rooms are selected routines that use that information had to be revised - in doing so it was possible to improve the usability/operation of: T2DMap::slot_movePosition() T2DMap::slot_setCharacter() T2DMap::slot_spread() T2DMap::slot_shrink() T2DMap::slot_lockRoom(): T2DMap::slot_unlockRoom(): This method, also resurrected here to the 2D mapper context menu, as it is also affected by the changes: T2DMap::slot_setPlayerLocation() There was a slot_setPlayerLocation code that set a global lua variable mRoomSet and moved the player to that room Id (introduced in commit-c25faf4e 2012-05-04 07:44:36 by Heiko) but the corresponding 2D Mapper context menu item that called it was commented out and thus removed from the menu in commit-93f65962 2012-12-29 01:16:28 also by Heiko without any explaination. Since that has not been used since then I have replaced it with a new Event: sysManualLocationSetEvent with a single numeric value which is the new (valid) room Id number - user scripts can capture this event if they want to know that the user has manually re-positioned the current player room in the 2D mapper. In passing: * Fixed Text font changing between docked and un-docked forms of the built-in map widget (when not incorporated into a console) - as it was not previously explicitly set it assumed the Application one whilst docked but the Qt System one when a free floating widget - and the two do not have to be the same. This fixes: https://bugs.launchpad.net/mudlet/+bug/1432841 . * Starts to fix https://bugs.launchpad.net/mudlet/+bug/1376511 by changing from use of obsolete QWheelEvent::delta() to QWheelEvent::angleDelta() in T2DMap::wheelEvent(...); will need duplicating in TTextEdit::wheelEvent(...) and GLWidget::wheelEvent(...) . * Adds the profile name to the Mapper dockable widget so that it's parentage can be determined when multiple profiles are active. Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2016-03-08 08:35:07 +00:00
{
continue;
Enhance: 2D Map Room Selection, better big map performance + other mods In situations when we check whether a room in an area both for internal purposes and when rooms on a mapper is selected, using QSet instead of a QList is faster in performance for large numbers of entries in set. As it reworks the mapper code it also fixes issue where the multi-room selection widget overwrites map info display - the latter is re-sized and re-positioned (and regains a semi-transparent background which helped to show this working during debugging!) The former is now: dynamically resized to only take up enough vertical space to show the selected rooms; also displays the associate room names if there are any, expanding the widget as required; sorts the display either by room name or number and in either direction. The mouse wheel handler is modified so that using the scroll wheel ONLY scrolls the list within the widget - previously (by default) once the end in either direction was hit the related events would be passed up the widget chain where it would otherwise invoke the 2D mapper's zoom in/out code. In modifying the zoom in/out code I have replaced the (obsoleted in Qt5.x) QWheelEvent::delta() method to use the QWheelEvent::angleDelta() method, using only the Y-component the latter provides. If the Control modifier is active the zoom value is modified by an extra x10 factor which is useful when working with large maps as otherwise the zooming rate is "slow" at high values - ideally the control should be logarithmic or exponential or some other "non-linear" algorithm to work more uniformly over the range of practical use cases. The code to paint the map info text has been revised also to use the mMapInfoRect which was being defined but NOT used. The info text now reports whether the room name is for the player room {set via the Lua command centerview(roomId)} or is one that is selected by mouse dragging - and if more than one room is selected by that indicates the count of rooms in the selection. In the case of multiple rooms being selected the room that single room context menu operations will act upon is highlighted by the same style of yellow target used to show the custom exit line destination but is drawn in a different point in the code so that it is drawn over the rooms. Because of the change to the way that multiple rooms are selected routines that use that information had to be revised - in doing so it was possible to improve the usability/operation of: T2DMap::slot_movePosition() T2DMap::slot_setCharacter() T2DMap::slot_spread() T2DMap::slot_shrink() T2DMap::slot_lockRoom(): T2DMap::slot_unlockRoom(): This method, also resurrected here to the 2D mapper context menu, as it is also affected by the changes: T2DMap::slot_setPlayerLocation() There was a slot_setPlayerLocation code that set a global lua variable mRoomSet and moved the player to that room Id (introduced in commit-c25faf4e 2012-05-04 07:44:36 by Heiko) but the corresponding 2D Mapper context menu item that called it was commented out and thus removed from the menu in commit-93f65962 2012-12-29 01:16:28 also by Heiko without any explaination. Since that has not been used since then I have replaced it with a new Event: sysManualLocationSetEvent with a single numeric value which is the new (valid) room Id number - user scripts can capture this event if they want to know that the user has manually re-positioned the current player room in the 2D mapper. In passing: * Fixed Text font changing between docked and un-docked forms of the built-in map widget (when not incorporated into a console) - as it was not previously explicitly set it assumed the Application one whilst docked but the Qt System one when a free floating widget - and the two do not have to be the same. This fixes: https://bugs.launchpad.net/mudlet/+bug/1432841 . * Starts to fix https://bugs.launchpad.net/mudlet/+bug/1376511 by changing from use of obsolete QWheelEvent::delta() to QWheelEvent::angleDelta() in T2DMap::wheelEvent(...); will need duplicating in TTextEdit::wheelEvent(...) and GLWidget::wheelEvent(...) . * Adds the profile name to the Mapper dockable widget so that it's parentage can be determined when multiple profiles are active. Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2016-03-08 08:35:07 +00:00
}
} else {
//to avoid rooms on same plane from stealing stubs
if ((int)pR->x != rx) {
Enhance: 2D Map Room Selection, better big map performance + other mods In situations when we check whether a room in an area both for internal purposes and when rooms on a mapper is selected, using QSet instead of a QList is faster in performance for large numbers of entries in set. As it reworks the mapper code it also fixes issue where the multi-room selection widget overwrites map info display - the latter is re-sized and re-positioned (and regains a semi-transparent background which helped to show this working during debugging!) The former is now: dynamically resized to only take up enough vertical space to show the selected rooms; also displays the associate room names if there are any, expanding the widget as required; sorts the display either by room name or number and in either direction. The mouse wheel handler is modified so that using the scroll wheel ONLY scrolls the list within the widget - previously (by default) once the end in either direction was hit the related events would be passed up the widget chain where it would otherwise invoke the 2D mapper's zoom in/out code. In modifying the zoom in/out code I have replaced the (obsoleted in Qt5.x) QWheelEvent::delta() method to use the QWheelEvent::angleDelta() method, using only the Y-component the latter provides. If the Control modifier is active the zoom value is modified by an extra x10 factor which is useful when working with large maps as otherwise the zooming rate is "slow" at high values - ideally the control should be logarithmic or exponential or some other "non-linear" algorithm to work more uniformly over the range of practical use cases. The code to paint the map info text has been revised also to use the mMapInfoRect which was being defined but NOT used. The info text now reports whether the room name is for the player room {set via the Lua command centerview(roomId)} or is one that is selected by mouse dragging - and if more than one room is selected by that indicates the count of rooms in the selection. In the case of multiple rooms being selected the room that single room context menu operations will act upon is highlighted by the same style of yellow target used to show the custom exit line destination but is drawn in a different point in the code so that it is drawn over the rooms. Because of the change to the way that multiple rooms are selected routines that use that information had to be revised - in doing so it was possible to improve the usability/operation of: T2DMap::slot_movePosition() T2DMap::slot_setCharacter() T2DMap::slot_spread() T2DMap::slot_shrink() T2DMap::slot_lockRoom(): T2DMap::slot_unlockRoom(): This method, also resurrected here to the 2D mapper context menu, as it is also affected by the changes: T2DMap::slot_setPlayerLocation() There was a slot_setPlayerLocation code that set a global lua variable mRoomSet and moved the player to that room Id (introduced in commit-c25faf4e 2012-05-04 07:44:36 by Heiko) but the corresponding 2D Mapper context menu item that called it was commented out and thus removed from the menu in commit-93f65962 2012-12-29 01:16:28 also by Heiko without any explaination. Since that has not been used since then I have replaced it with a new Event: sysManualLocationSetEvent with a single numeric value which is the new (valid) room Id number - user scripts can capture this event if they want to know that the user has manually re-positioned the current player room in the 2D mapper. In passing: * Fixed Text font changing between docked and un-docked forms of the built-in map widget (when not incorporated into a console) - as it was not previously explicitly set it assumed the Application one whilst docked but the Qt System one when a free floating widget - and the two do not have to be the same. This fixes: https://bugs.launchpad.net/mudlet/+bug/1432841 . * Starts to fix https://bugs.launchpad.net/mudlet/+bug/1376511 by changing from use of obsolete QWheelEvent::delta() to QWheelEvent::angleDelta() in T2DMap::wheelEvent(...); will need duplicating in TTextEdit::wheelEvent(...) and GLWidget::wheelEvent(...) . * Adds the profile name to the Mapper dockable widget so that it's parentage can be determined when multiple profiles are active. Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2016-03-08 08:35:07 +00:00
continue;
}
}
if (uy) {
dy = pR->y - ry;
//if the sign is the SAME here we keep it b/c we flip our y coordinate.
if (compSign(dy, uy) || !dy) {
continue;
Enhance: 2D Map Room Selection, better big map performance + other mods In situations when we check whether a room in an area both for internal purposes and when rooms on a mapper is selected, using QSet instead of a QList is faster in performance for large numbers of entries in set. As it reworks the mapper code it also fixes issue where the multi-room selection widget overwrites map info display - the latter is re-sized and re-positioned (and regains a semi-transparent background which helped to show this working during debugging!) The former is now: dynamically resized to only take up enough vertical space to show the selected rooms; also displays the associate room names if there are any, expanding the widget as required; sorts the display either by room name or number and in either direction. The mouse wheel handler is modified so that using the scroll wheel ONLY scrolls the list within the widget - previously (by default) once the end in either direction was hit the related events would be passed up the widget chain where it would otherwise invoke the 2D mapper's zoom in/out code. In modifying the zoom in/out code I have replaced the (obsoleted in Qt5.x) QWheelEvent::delta() method to use the QWheelEvent::angleDelta() method, using only the Y-component the latter provides. If the Control modifier is active the zoom value is modified by an extra x10 factor which is useful when working with large maps as otherwise the zooming rate is "slow" at high values - ideally the control should be logarithmic or exponential or some other "non-linear" algorithm to work more uniformly over the range of practical use cases. The code to paint the map info text has been revised also to use the mMapInfoRect which was being defined but NOT used. The info text now reports whether the room name is for the player room {set via the Lua command centerview(roomId)} or is one that is selected by mouse dragging - and if more than one room is selected by that indicates the count of rooms in the selection. In the case of multiple rooms being selected the room that single room context menu operations will act upon is highlighted by the same style of yellow target used to show the custom exit line destination but is drawn in a different point in the code so that it is drawn over the rooms. Because of the change to the way that multiple rooms are selected routines that use that information had to be revised - in doing so it was possible to improve the usability/operation of: T2DMap::slot_movePosition() T2DMap::slot_setCharacter() T2DMap::slot_spread() T2DMap::slot_shrink() T2DMap::slot_lockRoom(): T2DMap::slot_unlockRoom(): This method, also resurrected here to the 2D mapper context menu, as it is also affected by the changes: T2DMap::slot_setPlayerLocation() There was a slot_setPlayerLocation code that set a global lua variable mRoomSet and moved the player to that room Id (introduced in commit-c25faf4e 2012-05-04 07:44:36 by Heiko) but the corresponding 2D Mapper context menu item that called it was commented out and thus removed from the menu in commit-93f65962 2012-12-29 01:16:28 also by Heiko without any explaination. Since that has not been used since then I have replaced it with a new Event: sysManualLocationSetEvent with a single numeric value which is the new (valid) room Id number - user scripts can capture this event if they want to know that the user has manually re-positioned the current player room in the 2D mapper. In passing: * Fixed Text font changing between docked and un-docked forms of the built-in map widget (when not incorporated into a console) - as it was not previously explicitly set it assumed the Application one whilst docked but the Qt System one when a free floating widget - and the two do not have to be the same. This fixes: https://bugs.launchpad.net/mudlet/+bug/1432841 . * Starts to fix https://bugs.launchpad.net/mudlet/+bug/1376511 by changing from use of obsolete QWheelEvent::delta() to QWheelEvent::angleDelta() in T2DMap::wheelEvent(...); will need duplicating in TTextEdit::wheelEvent(...) and GLWidget::wheelEvent(...) . * Adds the profile name to the Mapper dockable widget so that it's parentage can be determined when multiple profiles are active. Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2016-03-08 08:35:07 +00:00
}
} else {
//to avoid rooms on same plane from stealing stubs
if (pR->y != ry) {
Enhance: 2D Map Room Selection, better big map performance + other mods In situations when we check whether a room in an area both for internal purposes and when rooms on a mapper is selected, using QSet instead of a QList is faster in performance for large numbers of entries in set. As it reworks the mapper code it also fixes issue where the multi-room selection widget overwrites map info display - the latter is re-sized and re-positioned (and regains a semi-transparent background which helped to show this working during debugging!) The former is now: dynamically resized to only take up enough vertical space to show the selected rooms; also displays the associate room names if there are any, expanding the widget as required; sorts the display either by room name or number and in either direction. The mouse wheel handler is modified so that using the scroll wheel ONLY scrolls the list within the widget - previously (by default) once the end in either direction was hit the related events would be passed up the widget chain where it would otherwise invoke the 2D mapper's zoom in/out code. In modifying the zoom in/out code I have replaced the (obsoleted in Qt5.x) QWheelEvent::delta() method to use the QWheelEvent::angleDelta() method, using only the Y-component the latter provides. If the Control modifier is active the zoom value is modified by an extra x10 factor which is useful when working with large maps as otherwise the zooming rate is "slow" at high values - ideally the control should be logarithmic or exponential or some other "non-linear" algorithm to work more uniformly over the range of practical use cases. The code to paint the map info text has been revised also to use the mMapInfoRect which was being defined but NOT used. The info text now reports whether the room name is for the player room {set via the Lua command centerview(roomId)} or is one that is selected by mouse dragging - and if more than one room is selected by that indicates the count of rooms in the selection. In the case of multiple rooms being selected the room that single room context menu operations will act upon is highlighted by the same style of yellow target used to show the custom exit line destination but is drawn in a different point in the code so that it is drawn over the rooms. Because of the change to the way that multiple rooms are selected routines that use that information had to be revised - in doing so it was possible to improve the usability/operation of: T2DMap::slot_movePosition() T2DMap::slot_setCharacter() T2DMap::slot_spread() T2DMap::slot_shrink() T2DMap::slot_lockRoom(): T2DMap::slot_unlockRoom(): This method, also resurrected here to the 2D mapper context menu, as it is also affected by the changes: T2DMap::slot_setPlayerLocation() There was a slot_setPlayerLocation code that set a global lua variable mRoomSet and moved the player to that room Id (introduced in commit-c25faf4e 2012-05-04 07:44:36 by Heiko) but the corresponding 2D Mapper context menu item that called it was commented out and thus removed from the menu in commit-93f65962 2012-12-29 01:16:28 also by Heiko without any explaination. Since that has not been used since then I have replaced it with a new Event: sysManualLocationSetEvent with a single numeric value which is the new (valid) room Id number - user scripts can capture this event if they want to know that the user has manually re-positioned the current player room in the 2D mapper. In passing: * Fixed Text font changing between docked and un-docked forms of the built-in map widget (when not incorporated into a console) - as it was not previously explicitly set it assumed the Application one whilst docked but the Qt System one when a free floating widget - and the two do not have to be the same. This fixes: https://bugs.launchpad.net/mudlet/+bug/1432841 . * Starts to fix https://bugs.launchpad.net/mudlet/+bug/1376511 by changing from use of obsolete QWheelEvent::delta() to QWheelEvent::angleDelta() in T2DMap::wheelEvent(...); will need duplicating in TTextEdit::wheelEvent(...) and GLWidget::wheelEvent(...) . * Adds the profile name to the Mapper dockable widget so that it's parentage can be determined when multiple profiles are active. Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2016-03-08 08:35:07 +00:00
continue;
}
}
meanSquareDistance = dx * dx + dy * dy + dz * dz;
if (meanSquareDistance < minDistance) {
minDistanceRoom = pR->getId();
minDistance = meanSquareDistance;
}
}
if (minDistanceRoom) {
2013-03-22 12:47:58 +01:00
pR = mpRoomDB->getRoom(minDistanceRoom);
if (!pR) {
Enhance: 2D Map Room Selection, better big map performance + other mods In situations when we check whether a room in an area both for internal purposes and when rooms on a mapper is selected, using QSet instead of a QList is faster in performance for large numbers of entries in set. As it reworks the mapper code it also fixes issue where the multi-room selection widget overwrites map info display - the latter is re-sized and re-positioned (and regains a semi-transparent background which helped to show this working during debugging!) The former is now: dynamically resized to only take up enough vertical space to show the selected rooms; also displays the associate room names if there are any, expanding the widget as required; sorts the display either by room name or number and in either direction. The mouse wheel handler is modified so that using the scroll wheel ONLY scrolls the list within the widget - previously (by default) once the end in either direction was hit the related events would be passed up the widget chain where it would otherwise invoke the 2D mapper's zoom in/out code. In modifying the zoom in/out code I have replaced the (obsoleted in Qt5.x) QWheelEvent::delta() method to use the QWheelEvent::angleDelta() method, using only the Y-component the latter provides. If the Control modifier is active the zoom value is modified by an extra x10 factor which is useful when working with large maps as otherwise the zooming rate is "slow" at high values - ideally the control should be logarithmic or exponential or some other "non-linear" algorithm to work more uniformly over the range of practical use cases. The code to paint the map info text has been revised also to use the mMapInfoRect which was being defined but NOT used. The info text now reports whether the room name is for the player room {set via the Lua command centerview(roomId)} or is one that is selected by mouse dragging - and if more than one room is selected by that indicates the count of rooms in the selection. In the case of multiple rooms being selected the room that single room context menu operations will act upon is highlighted by the same style of yellow target used to show the custom exit line destination but is drawn in a different point in the code so that it is drawn over the rooms. Because of the change to the way that multiple rooms are selected routines that use that information had to be revised - in doing so it was possible to improve the usability/operation of: T2DMap::slot_movePosition() T2DMap::slot_setCharacter() T2DMap::slot_spread() T2DMap::slot_shrink() T2DMap::slot_lockRoom(): T2DMap::slot_unlockRoom(): This method, also resurrected here to the 2D mapper context menu, as it is also affected by the changes: T2DMap::slot_setPlayerLocation() There was a slot_setPlayerLocation code that set a global lua variable mRoomSet and moved the player to that room Id (introduced in commit-c25faf4e 2012-05-04 07:44:36 by Heiko) but the corresponding 2D Mapper context menu item that called it was commented out and thus removed from the menu in commit-93f65962 2012-12-29 01:16:28 also by Heiko without any explaination. Since that has not been used since then I have replaced it with a new Event: sysManualLocationSetEvent with a single numeric value which is the new (valid) room Id number - user scripts can capture this event if they want to know that the user has manually re-positioned the current player room in the 2D mapper. In passing: * Fixed Text font changing between docked and un-docked forms of the built-in map widget (when not incorporated into a console) - as it was not previously explicitly set it assumed the Application one whilst docked but the Qt System one when a free floating widget - and the two do not have to be the same. This fixes: https://bugs.launchpad.net/mudlet/+bug/1432841 . * Starts to fix https://bugs.launchpad.net/mudlet/+bug/1376511 by changing from use of obsolete QWheelEvent::delta() to QWheelEvent::angleDelta() in T2DMap::wheelEvent(...); will need duplicating in TTextEdit::wheelEvent(...) and GLWidget::wheelEvent(...) . * Adds the profile name to the Mapper dockable widget so that it's parentage can be determined when multiple profiles are active. Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2016-03-08 08:35:07 +00:00
return;
}
if (pR->exitStubs.contains(reverseDirections[dirType])) {
setExit(roomId, minDistanceRoom, dirType);
setExit(minDistanceRoom, roomId, reverseDirections[dirType]);
}
}
}
int TMap::createNewRoomID(int minimumId)
2010-09-07 20:35:32 +02:00
{
int _id = 0;
if (minimumId > 0) {
_id = minimumId - 1;
2010-09-07 20:35:32 +02:00
}
do {
; // Empty loop as increment done in test
} while (mpRoomDB->getRoom(++_id));
return _id;
2010-09-07 20:35:32 +02:00
}
bool TMap::setExit(int from, int to, int dir)
2010-09-07 20:35:32 +02:00
{
Backport: merge ten commits room "entrance" code from "release_30" to "development" branches, Commit 01 of 10 originally entitled: "fix for keeping reverse area exit map in sync with exit creation, adding, and deletion" Conflicts resolved in: src/TRoom.h Commit 02 of 10 originally entitled: "bug fix for entranceMap having reversed key and value" Conflicts resolved in: src/TRoomDB.cpp Commit 03 of 10 originally entitled: "removal of entranceMap cleanup" Conflicts resolved in: src/TRoomDB.cpp Commit 04 of 10 originally entitled: "BugFix: prevent crash in dlgRoomExits::initExits() on missing exit" Code deficiencies that remove rooms without properly updating connected rooms were causing segmentation faults because this method - perhaps foolishly - expected a room to exist when another room had an exit Id to the room given. This commit corrects any faulty normal exits now by resetting them to the no exit -1 value. Commit 05 of 10 originally entitled: "Fixup: prevent unneeded TRoom::setExit() calls from dlgRoomExits class" Each individual call to TRoom::setExit((int)exitRoomId,(int)directionCode) from dlgRoomExit::save() creates additional entries in TRoom::entranceMap even for non-exit directions. To reduce (but unfortunately not eliminate) the number of duplicates change the save() code to only use setExit() when a difference between the current and saved exit room numbers is found. Commit 06 of 10 originally entitled: "Fixup: clear TRoomDB::entranceMap on map clearance" Obvious but was missing. Commit 07 of 10 originally entitled: "Fixup: add getAllRoomEntrances() to Lua command set" Though suitable for release code this was added to help with debugging. This was what enabled me to spot the problems that the previous pair of commits ameliorates. This currently only reports the rooms that have exit(s) that lead to the given room Id. It is anticipated that there will be a future revision to report the particular direction(s) from the given room(s) are the one(s) that lead to the room, using a second argument that will be a boolean true to trigger that behavior (the absence of, or a false, second argument would then cause the result that this code produces.) Conflicts resolved in: src/TLuaInterpreter.cpp src/TLuaInterpreter.h Commit 08 of 10 originally entitled: "Fixup: add debugging output to TRoomDB::updateEntranceMap(TRoom *)" Set a break point in the method and change the static bool showDebug to dis-/en-able output... Conflicts resolved in: src/TRoomDB.cpp Commit 09 of 10 originally entitled: "FixEnhance: fix entranceMap maintenance, bulk room deletion & map loading" Previously we were not removing entries from the entranceMap involving the value (a room that the room Id that was a key had an entrance FROM) when a route was changed. There is a performance cost in ensuring the data is kept correctly - there may be a modest gain by storing the entrance data within each TRoom class instance rather than a central database in TRoomDB... Deletion of multiple rooms and map loading can be done more efficiently if we skip some redundant steps. Also added/revised some timing code to measure things. Conflicts resolved in: src/TRoomDB.cpp src/TRoomDB.h Commit 10 of 10 originally entitled: "BugFix: Some previous coding errors" * T2DMap::slot_setArea(): used a uint where I should have used an int as a method I called can return a -1 in some cases. * TArea::getAreaExitRoomData(): a qWarning() in a debugging line I had used the wrong type (%1,%2,...) of format string argument characters when I should of used (%i or %s)... * (bool)TArea::mIsDirty: was put in wrong block of lines in header Conflicts resolved in: src/TArea.h Further conflicts resolved which were brought about by later re-basing before posting code out to world: src/dlgRoomExits.cpp Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-08-15 22:15:39 +01:00
// FIXME: This along with TRoom->setExit need to be unified to a controller.
TRoom* pR = mpRoomDB->getRoom(from);
TRoom* pR_to = mpRoomDB->getRoom(to);
2013-03-22 12:47:58 +01:00
if (!pR) {
Revise: massage Area Exit data to required format and ensure it is correct Rename: (void)TArea::fast_ausgaengeBestimmen(int) ==> TArea::determineAreaExitsOfRoom (void)TArea::ausgaengeBestimmen(int) ==> TArea::determineAreaExits (const)(QList<int>)TArea::getAreaExits() const ==> TArea::getAreaExitRoomIds() Add new method to return area exit data in new, wanted format: (const)(QMultiMap<int, QPair<QString, int> >) getAreaExitRoomData() const In preparation to revising internal storage representation of area exit data moved the: (QMultiMap<int, QPair<int, int> >)(TArea *)->exits member from public to private area of class. To permit save and load the following have had to be made friends of the TArea class: (bool)TMap::serialize( QDataStream & ) and (bool)TMap::restore( QString ) Revise (void)TMap::init(Host *) to run (TArea *)->determineAreaExits() on current and all previous map file format versions, will not be needed on future version as the code to manage the areaExits data is now functional. Previous code would have done this only for versions prior to 14 files (current is 16) or if the lua function auditAreas() was manually run. In passing also modified code that "fixed-up" "old style" map labels so that it is no longer run on current version files and pushes any messages that that creates into the main profile console instead of using standard C++ cout calls which we deprecate now. All code blocks that have been touched by this series of commits have been re-formatted to current styles. Update copyrights on all files touched that have not already been marked as having been edited by myself. Revised TLuaInterpreter::getAreaExits(...) to take a second optional Boolean that if present and true cause it to return data about the area exit directions and the destination rooms, if false or omitted, returns only the rooms in the area that have exits out of it, reproducing the previous implementation. In either case the result is a table if there are area exits (or a nil for an isolate area without exits); two additional values are returned an informative, translatable, text message and an integer status code that reflects the same information. When moving a series of rooms to a different area via the 2D mapper's GUI the recalculations for the area extremes {by TArea::calcSpan()} and the out of area exits {by TArea::determineAreaExits()} can now be deferred until the last room has been moved by passing a third true (boolean) argument to TMap::setRoomArea(...) which defaults to false for other single room at a time usages. Though that method keeps a local copy of the areas that have been modified and thus need updating, should the last room NOT be processed (null TRooo pointer for room Id) a publicly accessible "mIsDirty" flag is also used so that recovery code can identify and clean up those affected areas otherwise. It is possible that this flag may be useful in other situations, such as when moving or adding multiple rooms WITHIN an area. *** This commit has been rebased so it's history might not be the same as someone else's copy of it *** Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-01-05 01:20:15 +00:00
return false;
}
if (!pR_to && to > 0) {
Revise: massage Area Exit data to required format and ensure it is correct Rename: (void)TArea::fast_ausgaengeBestimmen(int) ==> TArea::determineAreaExitsOfRoom (void)TArea::ausgaengeBestimmen(int) ==> TArea::determineAreaExits (const)(QList<int>)TArea::getAreaExits() const ==> TArea::getAreaExitRoomIds() Add new method to return area exit data in new, wanted format: (const)(QMultiMap<int, QPair<QString, int> >) getAreaExitRoomData() const In preparation to revising internal storage representation of area exit data moved the: (QMultiMap<int, QPair<int, int> >)(TArea *)->exits member from public to private area of class. To permit save and load the following have had to be made friends of the TArea class: (bool)TMap::serialize( QDataStream & ) and (bool)TMap::restore( QString ) Revise (void)TMap::init(Host *) to run (TArea *)->determineAreaExits() on current and all previous map file format versions, will not be needed on future version as the code to manage the areaExits data is now functional. Previous code would have done this only for versions prior to 14 files (current is 16) or if the lua function auditAreas() was manually run. In passing also modified code that "fixed-up" "old style" map labels so that it is no longer run on current version files and pushes any messages that that creates into the main profile console instead of using standard C++ cout calls which we deprecate now. All code blocks that have been touched by this series of commits have been re-formatted to current styles. Update copyrights on all files touched that have not already been marked as having been edited by myself. Revised TLuaInterpreter::getAreaExits(...) to take a second optional Boolean that if present and true cause it to return data about the area exit directions and the destination rooms, if false or omitted, returns only the rooms in the area that have exits out of it, reproducing the previous implementation. In either case the result is a table if there are area exits (or a nil for an isolate area without exits); two additional values are returned an informative, translatable, text message and an integer status code that reflects the same information. When moving a series of rooms to a different area via the 2D mapper's GUI the recalculations for the area extremes {by TArea::calcSpan()} and the out of area exits {by TArea::determineAreaExits()} can now be deferred until the last room has been moved by passing a third true (boolean) argument to TMap::setRoomArea(...) which defaults to false for other single room at a time usages. Though that method keeps a local copy of the areas that have been modified and thus need updating, should the last room NOT be processed (null TRooo pointer for room Id) a publicly accessible "mIsDirty" flag is also used so that recovery code can identify and clean up those affected areas otherwise. It is possible that this flag may be useful in other situations, such as when moving or adding multiple rooms WITHIN an area. *** This commit has been rebased so it's history might not be the same as someone else's copy of it *** Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-01-05 01:20:15 +00:00
return false;
}
if (to < 1) {
Revise: massage Area Exit data to required format and ensure it is correct Rename: (void)TArea::fast_ausgaengeBestimmen(int) ==> TArea::determineAreaExitsOfRoom (void)TArea::ausgaengeBestimmen(int) ==> TArea::determineAreaExits (const)(QList<int>)TArea::getAreaExits() const ==> TArea::getAreaExitRoomIds() Add new method to return area exit data in new, wanted format: (const)(QMultiMap<int, QPair<QString, int> >) getAreaExitRoomData() const In preparation to revising internal storage representation of area exit data moved the: (QMultiMap<int, QPair<int, int> >)(TArea *)->exits member from public to private area of class. To permit save and load the following have had to be made friends of the TArea class: (bool)TMap::serialize( QDataStream & ) and (bool)TMap::restore( QString ) Revise (void)TMap::init(Host *) to run (TArea *)->determineAreaExits() on current and all previous map file format versions, will not be needed on future version as the code to manage the areaExits data is now functional. Previous code would have done this only for versions prior to 14 files (current is 16) or if the lua function auditAreas() was manually run. In passing also modified code that "fixed-up" "old style" map labels so that it is no longer run on current version files and pushes any messages that that creates into the main profile console instead of using standard C++ cout calls which we deprecate now. All code blocks that have been touched by this series of commits have been re-formatted to current styles. Update copyrights on all files touched that have not already been marked as having been edited by myself. Revised TLuaInterpreter::getAreaExits(...) to take a second optional Boolean that if present and true cause it to return data about the area exit directions and the destination rooms, if false or omitted, returns only the rooms in the area that have exits out of it, reproducing the previous implementation. In either case the result is a table if there are area exits (or a nil for an isolate area without exits); two additional values are returned an informative, translatable, text message and an integer status code that reflects the same information. When moving a series of rooms to a different area via the 2D mapper's GUI the recalculations for the area extremes {by TArea::calcSpan()} and the out of area exits {by TArea::determineAreaExits()} can now be deferred until the last room has been moved by passing a third true (boolean) argument to TMap::setRoomArea(...) which defaults to false for other single room at a time usages. Though that method keeps a local copy of the areas that have been modified and thus need updating, should the last room NOT be processed (null TRooo pointer for room Id) a publicly accessible "mIsDirty" flag is also used so that recovery code can identify and clean up those affected areas otherwise. It is possible that this flag may be useful in other situations, such as when moving or adding multiple rooms WITHIN an area. *** This commit has been rebased so it's history might not be the same as someone else's copy of it *** Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-01-05 01:20:15 +00:00
to = -1;
}
2010-12-28 23:31:03 +01:00
2013-05-26 11:47:15 +02:00
bool ret = true;
2010-09-07 20:35:32 +02:00
switch (dir) {
case DIR_NORTH:
pR->setNorth(to);
break;
case DIR_NORTHEAST:
pR->setNortheast(to);
break;
case DIR_NORTHWEST:
pR->setNorthwest(to);
break;
case DIR_EAST:
pR->setEast(to);
break;
case DIR_WEST:
pR->setWest(to);
break;
case DIR_SOUTH:
pR->setSouth(to);
break;
case DIR_SOUTHEAST:
pR->setSoutheast(to);
break;
case DIR_SOUTHWEST:
pR->setSouthwest(to);
break;
case DIR_UP:
pR->setUp(to);
break;
case DIR_DOWN:
pR->setDown(to);
break;
case DIR_IN:
pR->setIn(to);
break;
case DIR_OUT:
pR->setOut(to);
break;
default:
ret = false;
2010-09-07 20:35:32 +02:00
}
Enhancement: Improved/extended exits GUI for 2D mapper The GUI formed by dlgRoomExits.{cpp|h} and room_exits.ui combined now provide full control and aim to enforce relational consistency between the data items that provide all the exits from a particular room. All controls should have tool-tips - some context sensitive and provide support for some aspects that are not yet implemented in other parts of the code e.g. door markers for the mapper on exits not in the XY-Plane. As the controls for each normal exit are duplicated, labels are not given for the individual components to save space, instead an expanded disabled dummy with labels is provided as a Key. Unfortunately even after this the dialogue is still a little large and it has been suggested to replace the four radio buttons that provide control over the door item with a combo-box with the four fixed values... Following support methods have been changed/added: bool TRoom::hasExitStub(int) - modified, to provide a Boolean type result consistent with functionality. void TRoom::setExitStub(int, bool) - modified, remove ALL existing stub entries for the given direction code if the second argument is false, only adds a new entry if a corresponding one was not present - this is required for the data storage type (QList) for stubs which could otherwise take multiple entries for the same key (exit). Changed second argument to Boolean type to reflect its functionality. bool TRoom::hasExitWeight(QString) - new, needed for the GUI to determine source of weight data for exit. Normally that detail is hidden from consumers of this data. void TRoom::setExitWeight(QString, int) - modified, to permit it to remove data item for an exit. Uses zero or negative weight value which additionally aides route-finding code that consumes this data but requires only positive weight data. Removal of specific exit weight data permits reversion to use of overall weight value set in ROOM's weight. void TRoom::setDoor(QString, int) - new, implemented previously declared but not defined code. First argument as lower case initials for normal exits in XY-plane and "up", "down", "in", "out" for other normal exits. Supports special exits though no support at this point in 2D mapper for these or non-XY-plane exits. Second argument is door type (0=none, 1=open, 2=closed, 3=locked) and value of 0 will remove instance data of any of the other type. int TRoom::getDoor(QString) - new, companion to setDoor, uses same first argument to determine exit to return door code of. Returns zero for any exit specified which does not have a door explicitly set. Note: Parts of code-base still access door data directly at this point, further work required before that data could be made private to TRoom class. void TRoom::setArea(int) - modified, warning for room not having valid previous area enabled. bool TRoom::hasExit(int) - modified, method not being in use, re-purposed to use to test for an actual exit in given normal exit direction. Test used is simple, fast and may produce false positives (checks only for exit to room Id NOT being -1). A more thorough check would be to check that mpRoomDB->getRoom( exitId ) != 0 where exitId is value already determined not to be -1. bool TRoom::setExit(int, int) - new, uses a direction code as a first argument to set the exit to the exitId given as second. Intended to replace individual setNorth()...setOut() series of methods in cases requiring iteration through all normal exits. int TRoom::getExit(int) - new, companion to the new setExit(). bool TRoom::setSpecialExitLock(QString, bool) - new, substitute for other version which does not need to have the destination room supplied. Unlike the void method it supplants, it provides a bool return, true on success. void TRoom::setSpecialExit(int, QString) - replacement for addSpecialExit() renamed because now capable of removing a special exit if the first argument, the exit to room Id is less than one. Lua command removeSpecialExit( fromRoomId, cmd ) with no normal return value added for users' use, eliminating the need to remove all exits and re-adding all others in order to remove or change just one. Corresponding addSpecialExit( fromRoomId, toRoomId, cmd ) now able to change the toRoomId for an existing exit "cmd" from given fromRoomId room. void TRoom::removeAllSpecialExitsToRoom(int) - modified, now ensures the corresponding TArea::exits is updated upon removal of all the special exits from a room. void TRoom::auditExits() - modified, missing checks added for up and down normal exits, and reporting for all normal exits. Code restructured to avoid use of two "goto" commands and consequent restarts in checking of special exits if they were to be executed. int TRoomDB::getArea(TArea *) - commented out prior to removal, it is mis-named as it returned an integer area Id not a TArea value, pointer or reference. Also it's given functionality is already provided by int TRoomDB::getAreaID(TArea *) and the implied action by TArea * TRoomDB::getArea(int). Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2014-03-15 05:16:30 +00:00
pR->setExitStub(dir, false);
mMapGraphNeedsUpdate = true;
TArea* pA = mpRoomDB->getArea(pR->getArea());
if (!pA) {
return false;
Revise: massage Area Exit data to required format and ensure it is correct Rename: (void)TArea::fast_ausgaengeBestimmen(int) ==> TArea::determineAreaExitsOfRoom (void)TArea::ausgaengeBestimmen(int) ==> TArea::determineAreaExits (const)(QList<int>)TArea::getAreaExits() const ==> TArea::getAreaExitRoomIds() Add new method to return area exit data in new, wanted format: (const)(QMultiMap<int, QPair<QString, int> >) getAreaExitRoomData() const In preparation to revising internal storage representation of area exit data moved the: (QMultiMap<int, QPair<int, int> >)(TArea *)->exits member from public to private area of class. To permit save and load the following have had to be made friends of the TArea class: (bool)TMap::serialize( QDataStream & ) and (bool)TMap::restore( QString ) Revise (void)TMap::init(Host *) to run (TArea *)->determineAreaExits() on current and all previous map file format versions, will not be needed on future version as the code to manage the areaExits data is now functional. Previous code would have done this only for versions prior to 14 files (current is 16) or if the lua function auditAreas() was manually run. In passing also modified code that "fixed-up" "old style" map labels so that it is no longer run on current version files and pushes any messages that that creates into the main profile console instead of using standard C++ cout calls which we deprecate now. All code blocks that have been touched by this series of commits have been re-formatted to current styles. Update copyrights on all files touched that have not already been marked as having been edited by myself. Revised TLuaInterpreter::getAreaExits(...) to take a second optional Boolean that if present and true cause it to return data about the area exit directions and the destination rooms, if false or omitted, returns only the rooms in the area that have exits out of it, reproducing the previous implementation. In either case the result is a table if there are area exits (or a nil for an isolate area without exits); two additional values are returned an informative, translatable, text message and an integer status code that reflects the same information. When moving a series of rooms to a different area via the 2D mapper's GUI the recalculations for the area extremes {by TArea::calcSpan()} and the out of area exits {by TArea::determineAreaExits()} can now be deferred until the last room has been moved by passing a third true (boolean) argument to TMap::setRoomArea(...) which defaults to false for other single room at a time usages. Though that method keeps a local copy of the areas that have been modified and thus need updating, should the last room NOT be processed (null TRooo pointer for room Id) a publicly accessible "mIsDirty" flag is also used so that recovery code can identify and clean up those affected areas otherwise. It is possible that this flag may be useful in other situations, such as when moving or adding multiple rooms WITHIN an area. *** This commit has been rebased so it's history might not be the same as someone else's copy of it *** Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-01-05 01:20:15 +00:00
}
pA->determineAreaExitsOfRoom(pR->getId());
Backport: merge ten commits room "entrance" code from "release_30" to "development" branches, Commit 01 of 10 originally entitled: "fix for keeping reverse area exit map in sync with exit creation, adding, and deletion" Conflicts resolved in: src/TRoom.h Commit 02 of 10 originally entitled: "bug fix for entranceMap having reversed key and value" Conflicts resolved in: src/TRoomDB.cpp Commit 03 of 10 originally entitled: "removal of entranceMap cleanup" Conflicts resolved in: src/TRoomDB.cpp Commit 04 of 10 originally entitled: "BugFix: prevent crash in dlgRoomExits::initExits() on missing exit" Code deficiencies that remove rooms without properly updating connected rooms were causing segmentation faults because this method - perhaps foolishly - expected a room to exist when another room had an exit Id to the room given. This commit corrects any faulty normal exits now by resetting them to the no exit -1 value. Commit 05 of 10 originally entitled: "Fixup: prevent unneeded TRoom::setExit() calls from dlgRoomExits class" Each individual call to TRoom::setExit((int)exitRoomId,(int)directionCode) from dlgRoomExit::save() creates additional entries in TRoom::entranceMap even for non-exit directions. To reduce (but unfortunately not eliminate) the number of duplicates change the save() code to only use setExit() when a difference between the current and saved exit room numbers is found. Commit 06 of 10 originally entitled: "Fixup: clear TRoomDB::entranceMap on map clearance" Obvious but was missing. Commit 07 of 10 originally entitled: "Fixup: add getAllRoomEntrances() to Lua command set" Though suitable for release code this was added to help with debugging. This was what enabled me to spot the problems that the previous pair of commits ameliorates. This currently only reports the rooms that have exit(s) that lead to the given room Id. It is anticipated that there will be a future revision to report the particular direction(s) from the given room(s) are the one(s) that lead to the room, using a second argument that will be a boolean true to trigger that behavior (the absence of, or a false, second argument would then cause the result that this code produces.) Conflicts resolved in: src/TLuaInterpreter.cpp src/TLuaInterpreter.h Commit 08 of 10 originally entitled: "Fixup: add debugging output to TRoomDB::updateEntranceMap(TRoom *)" Set a break point in the method and change the static bool showDebug to dis-/en-able output... Conflicts resolved in: src/TRoomDB.cpp Commit 09 of 10 originally entitled: "FixEnhance: fix entranceMap maintenance, bulk room deletion & map loading" Previously we were not removing entries from the entranceMap involving the value (a room that the room Id that was a key had an entrance FROM) when a route was changed. There is a performance cost in ensuring the data is kept correctly - there may be a modest gain by storing the entrance data within each TRoom class instance rather than a central database in TRoomDB... Deletion of multiple rooms and map loading can be done more efficiently if we skip some redundant steps. Also added/revised some timing code to measure things. Conflicts resolved in: src/TRoomDB.cpp src/TRoomDB.h Commit 10 of 10 originally entitled: "BugFix: Some previous coding errors" * T2DMap::slot_setArea(): used a uint where I should have used an int as a method I called can return a -1 in some cases. * TArea::getAreaExitRoomData(): a qWarning() in a debugging line I had used the wrong type (%1,%2,...) of format string argument characters when I should of used (%i or %s)... * (bool)TArea::mIsDirty: was put in wrong block of lines in header Conflicts resolved in: src/TArea.h Further conflicts resolved which were brought about by later re-basing before posting code out to world: src/dlgRoomExits.cpp Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-08-15 22:15:39 +01:00
mpRoomDB->updateEntranceMap(pR);
2013-05-26 11:47:15 +02:00
return ret;
2010-09-07 20:35:32 +02:00
}
void TMap::audit()
2010-08-25 00:41:43 +02:00
{
// init areas
Backport: merge ten commits room "entrance" code from "release_30" to "development" branches, Commit 01 of 10 originally entitled: "fix for keeping reverse area exit map in sync with exit creation, adding, and deletion" Conflicts resolved in: src/TRoom.h Commit 02 of 10 originally entitled: "bug fix for entranceMap having reversed key and value" Conflicts resolved in: src/TRoomDB.cpp Commit 03 of 10 originally entitled: "removal of entranceMap cleanup" Conflicts resolved in: src/TRoomDB.cpp Commit 04 of 10 originally entitled: "BugFix: prevent crash in dlgRoomExits::initExits() on missing exit" Code deficiencies that remove rooms without properly updating connected rooms were causing segmentation faults because this method - perhaps foolishly - expected a room to exist when another room had an exit Id to the room given. This commit corrects any faulty normal exits now by resetting them to the no exit -1 value. Commit 05 of 10 originally entitled: "Fixup: prevent unneeded TRoom::setExit() calls from dlgRoomExits class" Each individual call to TRoom::setExit((int)exitRoomId,(int)directionCode) from dlgRoomExit::save() creates additional entries in TRoom::entranceMap even for non-exit directions. To reduce (but unfortunately not eliminate) the number of duplicates change the save() code to only use setExit() when a difference between the current and saved exit room numbers is found. Commit 06 of 10 originally entitled: "Fixup: clear TRoomDB::entranceMap on map clearance" Obvious but was missing. Commit 07 of 10 originally entitled: "Fixup: add getAllRoomEntrances() to Lua command set" Though suitable for release code this was added to help with debugging. This was what enabled me to spot the problems that the previous pair of commits ameliorates. This currently only reports the rooms that have exit(s) that lead to the given room Id. It is anticipated that there will be a future revision to report the particular direction(s) from the given room(s) are the one(s) that lead to the room, using a second argument that will be a boolean true to trigger that behavior (the absence of, or a false, second argument would then cause the result that this code produces.) Conflicts resolved in: src/TLuaInterpreter.cpp src/TLuaInterpreter.h Commit 08 of 10 originally entitled: "Fixup: add debugging output to TRoomDB::updateEntranceMap(TRoom *)" Set a break point in the method and change the static bool showDebug to dis-/en-able output... Conflicts resolved in: src/TRoomDB.cpp Commit 09 of 10 originally entitled: "FixEnhance: fix entranceMap maintenance, bulk room deletion & map loading" Previously we were not removing entries from the entranceMap involving the value (a room that the room Id that was a key had an entrance FROM) when a route was changed. There is a performance cost in ensuring the data is kept correctly - there may be a modest gain by storing the entrance data within each TRoom class instance rather than a central database in TRoomDB... Deletion of multiple rooms and map loading can be done more efficiently if we skip some redundant steps. Also added/revised some timing code to measure things. Conflicts resolved in: src/TRoomDB.cpp src/TRoomDB.h Commit 10 of 10 originally entitled: "BugFix: Some previous coding errors" * T2DMap::slot_setArea(): used a uint where I should have used an int as a method I called can return a -1 in some cases. * TArea::getAreaExitRoomData(): a qWarning() in a debugging line I had used the wrong type (%1,%2,...) of format string argument characters when I should of used (%i or %s)... * (bool)TArea::mIsDirty: was put in wrong block of lines in header Conflicts resolved in: src/TArea.h Further conflicts resolved which were brought about by later re-basing before posting code out to world: src/dlgRoomExits.cpp Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-08-15 22:15:39 +01:00
QElapsedTimer _time;
Revise: massage Area Exit data to required format and ensure it is correct Rename: (void)TArea::fast_ausgaengeBestimmen(int) ==> TArea::determineAreaExitsOfRoom (void)TArea::ausgaengeBestimmen(int) ==> TArea::determineAreaExits (const)(QList<int>)TArea::getAreaExits() const ==> TArea::getAreaExitRoomIds() Add new method to return area exit data in new, wanted format: (const)(QMultiMap<int, QPair<QString, int> >) getAreaExitRoomData() const In preparation to revising internal storage representation of area exit data moved the: (QMultiMap<int, QPair<int, int> >)(TArea *)->exits member from public to private area of class. To permit save and load the following have had to be made friends of the TArea class: (bool)TMap::serialize( QDataStream & ) and (bool)TMap::restore( QString ) Revise (void)TMap::init(Host *) to run (TArea *)->determineAreaExits() on current and all previous map file format versions, will not be needed on future version as the code to manage the areaExits data is now functional. Previous code would have done this only for versions prior to 14 files (current is 16) or if the lua function auditAreas() was manually run. In passing also modified code that "fixed-up" "old style" map labels so that it is no longer run on current version files and pushes any messages that that creates into the main profile console instead of using standard C++ cout calls which we deprecate now. All code blocks that have been touched by this series of commits have been re-formatted to current styles. Update copyrights on all files touched that have not already been marked as having been edited by myself. Revised TLuaInterpreter::getAreaExits(...) to take a second optional Boolean that if present and true cause it to return data about the area exit directions and the destination rooms, if false or omitted, returns only the rooms in the area that have exits out of it, reproducing the previous implementation. In either case the result is a table if there are area exits (or a nil for an isolate area without exits); two additional values are returned an informative, translatable, text message and an integer status code that reflects the same information. When moving a series of rooms to a different area via the 2D mapper's GUI the recalculations for the area extremes {by TArea::calcSpan()} and the out of area exits {by TArea::determineAreaExits()} can now be deferred until the last room has been moved by passing a third true (boolean) argument to TMap::setRoomArea(...) which defaults to false for other single room at a time usages. Though that method keeps a local copy of the areas that have been modified and thus need updating, should the last room NOT be processed (null TRooo pointer for room Id) a publicly accessible "mIsDirty" flag is also used so that recovery code can identify and clean up those affected areas otherwise. It is possible that this flag may be useful in other situations, such as when moving or adding multiple rooms WITHIN an area. *** This commit has been rebased so it's history might not be the same as someone else's copy of it *** Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-01-05 01:20:15 +00:00
_time.start();
{ // Blocked - just to limit the scope of infoMsg...!
QString infoMsg = tr("[ INFO ] - Auditing of a loaded/imported/downloaded map starting...");
postMessage(infoMsg);
Revise: massage Area Exit data to required format and ensure it is correct Rename: (void)TArea::fast_ausgaengeBestimmen(int) ==> TArea::determineAreaExitsOfRoom (void)TArea::ausgaengeBestimmen(int) ==> TArea::determineAreaExits (const)(QList<int>)TArea::getAreaExits() const ==> TArea::getAreaExitRoomIds() Add new method to return area exit data in new, wanted format: (const)(QMultiMap<int, QPair<QString, int> >) getAreaExitRoomData() const In preparation to revising internal storage representation of area exit data moved the: (QMultiMap<int, QPair<int, int> >)(TArea *)->exits member from public to private area of class. To permit save and load the following have had to be made friends of the TArea class: (bool)TMap::serialize( QDataStream & ) and (bool)TMap::restore( QString ) Revise (void)TMap::init(Host *) to run (TArea *)->determineAreaExits() on current and all previous map file format versions, will not be needed on future version as the code to manage the areaExits data is now functional. Previous code would have done this only for versions prior to 14 files (current is 16) or if the lua function auditAreas() was manually run. In passing also modified code that "fixed-up" "old style" map labels so that it is no longer run on current version files and pushes any messages that that creates into the main profile console instead of using standard C++ cout calls which we deprecate now. All code blocks that have been touched by this series of commits have been re-formatted to current styles. Update copyrights on all files touched that have not already been marked as having been edited by myself. Revised TLuaInterpreter::getAreaExits(...) to take a second optional Boolean that if present and true cause it to return data about the area exit directions and the destination rooms, if false or omitted, returns only the rooms in the area that have exits out of it, reproducing the previous implementation. In either case the result is a table if there are area exits (or a nil for an isolate area without exits); two additional values are returned an informative, translatable, text message and an integer status code that reflects the same information. When moving a series of rooms to a different area via the 2D mapper's GUI the recalculations for the area extremes {by TArea::calcSpan()} and the out of area exits {by TArea::determineAreaExits()} can now be deferred until the last room has been moved by passing a third true (boolean) argument to TMap::setRoomArea(...) which defaults to false for other single room at a time usages. Though that method keeps a local copy of the areas that have been modified and thus need updating, should the last room NOT be processed (null TRooo pointer for room Id) a publicly accessible "mIsDirty" flag is also used so that recovery code can identify and clean up those affected areas otherwise. It is possible that this flag may be useful in other situations, such as when moving or adding multiple rooms WITHIN an area. *** This commit has been rebased so it's history might not be the same as someone else's copy of it *** Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-01-05 01:20:15 +00:00
}
// The old mpRoomDB->initAreasForOldMaps() was a subset of these checks
QHash<int, int> roomRemapping; // These are populated by the auditRooms(...)
Revision: route most of map auditing messages to errors.txt file As the amount of messages produced by the new/improve map auditing/clean-up code can be large for old map files this commit causes them to be sent to a profile specific file that is already opened by the Host class but has not been used for some time. An option (a check-box) on the "map" tab of the "profile preferences" dialog controls whether the equivalent information is also shown on the profile's main console as in the past. If the option (a global one) which is saved between sessions/runs is NOT enabled then an advisory is sent to the console advising the user to review the file contents if a "significant" issue was detected. If it is enabled a similar message advising that the information has also been saved. In either case, as the file is appended to, and not rewritten each time, the message includes details of the first line of the report so that it can be located in the file. One difference between the on-screen and the file versions of the information is that the former puts up the issues as they are detected whereas the latter groups the information by subject, first the general overall issues, then the area ones, in order of the areas' id numbers and then the room ones, in room order. Following earlier discussions in these Pull Request I have attempted to edit all uses of the word "Id" in user visible places to be "id" instead. This threw up some other messages with issues in several files that I have tweaked here as well! Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2016-05-03 04:58:31 +01:00
QHash<int, int> areaRemapping; // call and contain "Keys" of old ids and
// "Values" of new ids to use in their stead
Revise: massage Area Exit data to required format and ensure it is correct Rename: (void)TArea::fast_ausgaengeBestimmen(int) ==> TArea::determineAreaExitsOfRoom (void)TArea::ausgaengeBestimmen(int) ==> TArea::determineAreaExits (const)(QList<int>)TArea::getAreaExits() const ==> TArea::getAreaExitRoomIds() Add new method to return area exit data in new, wanted format: (const)(QMultiMap<int, QPair<QString, int> >) getAreaExitRoomData() const In preparation to revising internal storage representation of area exit data moved the: (QMultiMap<int, QPair<int, int> >)(TArea *)->exits member from public to private area of class. To permit save and load the following have had to be made friends of the TArea class: (bool)TMap::serialize( QDataStream & ) and (bool)TMap::restore( QString ) Revise (void)TMap::init(Host *) to run (TArea *)->determineAreaExits() on current and all previous map file format versions, will not be needed on future version as the code to manage the areaExits data is now functional. Previous code would have done this only for versions prior to 14 files (current is 16) or if the lua function auditAreas() was manually run. In passing also modified code that "fixed-up" "old style" map labels so that it is no longer run on current version files and pushes any messages that that creates into the main profile console instead of using standard C++ cout calls which we deprecate now. All code blocks that have been touched by this series of commits have been re-formatted to current styles. Update copyrights on all files touched that have not already been marked as having been edited by myself. Revised TLuaInterpreter::getAreaExits(...) to take a second optional Boolean that if present and true cause it to return data about the area exit directions and the destination rooms, if false or omitted, returns only the rooms in the area that have exits out of it, reproducing the previous implementation. In either case the result is a table if there are area exits (or a nil for an isolate area without exits); two additional values are returned an informative, translatable, text message and an integer status code that reflects the same information. When moving a series of rooms to a different area via the 2D mapper's GUI the recalculations for the area extremes {by TArea::calcSpan()} and the out of area exits {by TArea::determineAreaExits()} can now be deferred until the last room has been moved by passing a third true (boolean) argument to TMap::setRoomArea(...) which defaults to false for other single room at a time usages. Though that method keeps a local copy of the areas that have been modified and thus need updating, should the last room NOT be processed (null TRooo pointer for room Id) a publicly accessible "mIsDirty" flag is also used so that recovery code can identify and clean up those affected areas otherwise. It is possible that this flag may be useful in other situations, such as when moving or adding multiple rooms WITHIN an area. *** This commit has been rebased so it's history might not be the same as someone else's copy of it *** Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-01-05 01:20:15 +00:00
if (mVersion < 16) {
Revise: massage Area Exit data to required format and ensure it is correct Rename: (void)TArea::fast_ausgaengeBestimmen(int) ==> TArea::determineAreaExitsOfRoom (void)TArea::ausgaengeBestimmen(int) ==> TArea::determineAreaExits (const)(QList<int>)TArea::getAreaExits() const ==> TArea::getAreaExitRoomIds() Add new method to return area exit data in new, wanted format: (const)(QMultiMap<int, QPair<QString, int> >) getAreaExitRoomData() const In preparation to revising internal storage representation of area exit data moved the: (QMultiMap<int, QPair<int, int> >)(TArea *)->exits member from public to private area of class. To permit save and load the following have had to be made friends of the TArea class: (bool)TMap::serialize( QDataStream & ) and (bool)TMap::restore( QString ) Revise (void)TMap::init(Host *) to run (TArea *)->determineAreaExits() on current and all previous map file format versions, will not be needed on future version as the code to manage the areaExits data is now functional. Previous code would have done this only for versions prior to 14 files (current is 16) or if the lua function auditAreas() was manually run. In passing also modified code that "fixed-up" "old style" map labels so that it is no longer run on current version files and pushes any messages that that creates into the main profile console instead of using standard C++ cout calls which we deprecate now. All code blocks that have been touched by this series of commits have been re-formatted to current styles. Update copyrights on all files touched that have not already been marked as having been edited by myself. Revised TLuaInterpreter::getAreaExits(...) to take a second optional Boolean that if present and true cause it to return data about the area exit directions and the destination rooms, if false or omitted, returns only the rooms in the area that have exits out of it, reproducing the previous implementation. In either case the result is a table if there are area exits (or a nil for an isolate area without exits); two additional values are returned an informative, translatable, text message and an integer status code that reflects the same information. When moving a series of rooms to a different area via the 2D mapper's GUI the recalculations for the area extremes {by TArea::calcSpan()} and the out of area exits {by TArea::determineAreaExits()} can now be deferred until the last room has been moved by passing a third true (boolean) argument to TMap::setRoomArea(...) which defaults to false for other single room at a time usages. Though that method keeps a local copy of the areas that have been modified and thus need updating, should the last room NOT be processed (null TRooo pointer for room Id) a publicly accessible "mIsDirty" flag is also used so that recovery code can identify and clean up those affected areas otherwise. It is possible that this flag may be useful in other situations, such as when moving or adding multiple rooms WITHIN an area. *** This commit has been rebased so it's history might not be the same as someone else's copy of it *** Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-01-05 01:20:15 +00:00
// convert old style labels, wasn't made version conditional in past but
// not likely to be an issue in recent map file format versions (say 16+)
QMapIterator<int, TArea*> itArea(mpRoomDB->getAreaMap());
while (itArea.hasNext()) {
Revise: massage Area Exit data to required format and ensure it is correct Rename: (void)TArea::fast_ausgaengeBestimmen(int) ==> TArea::determineAreaExitsOfRoom (void)TArea::ausgaengeBestimmen(int) ==> TArea::determineAreaExits (const)(QList<int>)TArea::getAreaExits() const ==> TArea::getAreaExitRoomIds() Add new method to return area exit data in new, wanted format: (const)(QMultiMap<int, QPair<QString, int> >) getAreaExitRoomData() const In preparation to revising internal storage representation of area exit data moved the: (QMultiMap<int, QPair<int, int> >)(TArea *)->exits member from public to private area of class. To permit save and load the following have had to be made friends of the TArea class: (bool)TMap::serialize( QDataStream & ) and (bool)TMap::restore( QString ) Revise (void)TMap::init(Host *) to run (TArea *)->determineAreaExits() on current and all previous map file format versions, will not be needed on future version as the code to manage the areaExits data is now functional. Previous code would have done this only for versions prior to 14 files (current is 16) or if the lua function auditAreas() was manually run. In passing also modified code that "fixed-up" "old style" map labels so that it is no longer run on current version files and pushes any messages that that creates into the main profile console instead of using standard C++ cout calls which we deprecate now. All code blocks that have been touched by this series of commits have been re-formatted to current styles. Update copyrights on all files touched that have not already been marked as having been edited by myself. Revised TLuaInterpreter::getAreaExits(...) to take a second optional Boolean that if present and true cause it to return data about the area exit directions and the destination rooms, if false or omitted, returns only the rooms in the area that have exits out of it, reproducing the previous implementation. In either case the result is a table if there are area exits (or a nil for an isolate area without exits); two additional values are returned an informative, translatable, text message and an integer status code that reflects the same information. When moving a series of rooms to a different area via the 2D mapper's GUI the recalculations for the area extremes {by TArea::calcSpan()} and the out of area exits {by TArea::determineAreaExits()} can now be deferred until the last room has been moved by passing a third true (boolean) argument to TMap::setRoomArea(...) which defaults to false for other single room at a time usages. Though that method keeps a local copy of the areas that have been modified and thus need updating, should the last room NOT be processed (null TRooo pointer for room Id) a publicly accessible "mIsDirty" flag is also used so that recovery code can identify and clean up those affected areas otherwise. It is possible that this flag may be useful in other situations, such as when moving or adding multiple rooms WITHIN an area. *** This commit has been rebased so it's history might not be the same as someone else's copy of it *** Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-01-05 01:20:15 +00:00
itArea.next();
int areaID = itArea.key();
if (mapLabels.contains(areaID)) {
Revise: massage Area Exit data to required format and ensure it is correct Rename: (void)TArea::fast_ausgaengeBestimmen(int) ==> TArea::determineAreaExitsOfRoom (void)TArea::ausgaengeBestimmen(int) ==> TArea::determineAreaExits (const)(QList<int>)TArea::getAreaExits() const ==> TArea::getAreaExitRoomIds() Add new method to return area exit data in new, wanted format: (const)(QMultiMap<int, QPair<QString, int> >) getAreaExitRoomData() const In preparation to revising internal storage representation of area exit data moved the: (QMultiMap<int, QPair<int, int> >)(TArea *)->exits member from public to private area of class. To permit save and load the following have had to be made friends of the TArea class: (bool)TMap::serialize( QDataStream & ) and (bool)TMap::restore( QString ) Revise (void)TMap::init(Host *) to run (TArea *)->determineAreaExits() on current and all previous map file format versions, will not be needed on future version as the code to manage the areaExits data is now functional. Previous code would have done this only for versions prior to 14 files (current is 16) or if the lua function auditAreas() was manually run. In passing also modified code that "fixed-up" "old style" map labels so that it is no longer run on current version files and pushes any messages that that creates into the main profile console instead of using standard C++ cout calls which we deprecate now. All code blocks that have been touched by this series of commits have been re-formatted to current styles. Update copyrights on all files touched that have not already been marked as having been edited by myself. Revised TLuaInterpreter::getAreaExits(...) to take a second optional Boolean that if present and true cause it to return data about the area exit directions and the destination rooms, if false or omitted, returns only the rooms in the area that have exits out of it, reproducing the previous implementation. In either case the result is a table if there are area exits (or a nil for an isolate area without exits); two additional values are returned an informative, translatable, text message and an integer status code that reflects the same information. When moving a series of rooms to a different area via the 2D mapper's GUI the recalculations for the area extremes {by TArea::calcSpan()} and the out of area exits {by TArea::determineAreaExits()} can now be deferred until the last room has been moved by passing a third true (boolean) argument to TMap::setRoomArea(...) which defaults to false for other single room at a time usages. Though that method keeps a local copy of the areas that have been modified and thus need updating, should the last room NOT be processed (null TRooo pointer for room Id) a publicly accessible "mIsDirty" flag is also used so that recovery code can identify and clean up those affected areas otherwise. It is possible that this flag may be useful in other situations, such as when moving or adding multiple rooms WITHIN an area. *** This commit has been rebased so it's history might not be the same as someone else's copy of it *** Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-01-05 01:20:15 +00:00
QList<int> labelIDList = mapLabels.value(areaID).keys();
for (int& i : labelIDList) {
TMapLabel l = mapLabels.value(areaID).value(i);
if (l.pix.isNull()) {
int newID = createMapLabel(areaID, l.text, l.pos.x(), l.pos.y(), l.pos.z(), l.fgColor, l.bgColor, true, false, 40.0, 50);
if (newID > -1) {
if (mudlet::self()->showMapAuditErrors()) {
QString msg = tr("[ INFO ] - CONVERTING: old style label, areaID:%1 labelID:%2.").arg(areaID).arg(i);
Revision: route most of map auditing messages to errors.txt file As the amount of messages produced by the new/improve map auditing/clean-up code can be large for old map files this commit causes them to be sent to a profile specific file that is already opened by the Host class but has not been used for some time. An option (a check-box) on the "map" tab of the "profile preferences" dialog controls whether the equivalent information is also shown on the profile's main console as in the past. If the option (a global one) which is saved between sessions/runs is NOT enabled then an advisory is sent to the console advising the user to review the file contents if a "significant" issue was detected. If it is enabled a similar message advising that the information has also been saved. In either case, as the file is appended to, and not rewritten each time, the message includes details of the first line of the report so that it can be located in the file. One difference between the on-screen and the file versions of the information is that the former puts up the issues as they are detected whereas the latter groups the information by subject, first the general overall issues, then the area ones, in order of the areas' id numbers and then the room ones, in room order. Following earlier discussions in these Pull Request I have attempted to edit all uses of the word "Id" in user visible places to be "id" instead. This threw up some other messages with issues in several files that I have tweaked here as well! Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2016-05-03 04:58:31 +01:00
postMessage(msg);
}
appendAreaErrorMsg(areaID, tr("[ INFO ] - Converting old style label id: %1.").arg(i));
mapLabels[areaID][i] = mapLabels[areaID][newID];
deleteMapLabel(areaID, newID);
} else {
if (mudlet::self()->showMapAuditErrors()) {
QString msg = tr("[ WARN ] - CONVERTING: cannot convert old style label in area with id: %1, label id is: %2.").arg(areaID).arg(i);
Revision: route most of map auditing messages to errors.txt file As the amount of messages produced by the new/improve map auditing/clean-up code can be large for old map files this commit causes them to be sent to a profile specific file that is already opened by the Host class but has not been used for some time. An option (a check-box) on the "map" tab of the "profile preferences" dialog controls whether the equivalent information is also shown on the profile's main console as in the past. If the option (a global one) which is saved between sessions/runs is NOT enabled then an advisory is sent to the console advising the user to review the file contents if a "significant" issue was detected. If it is enabled a similar message advising that the information has also been saved. In either case, as the file is appended to, and not rewritten each time, the message includes details of the first line of the report so that it can be located in the file. One difference between the on-screen and the file versions of the information is that the former puts up the issues as they are detected whereas the latter groups the information by subject, first the general overall issues, then the area ones, in order of the areas' id numbers and then the room ones, in room order. Following earlier discussions in these Pull Request I have attempted to edit all uses of the word "Id" in user visible places to be "id" instead. This threw up some other messages with issues in several files that I have tweaked here as well! Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2016-05-03 04:58:31 +01:00
postMessage(msg);
}
appendAreaErrorMsg(areaID, tr("[ WARN ] - CONVERTING: cannot convert old style label with id: %1.").arg(i));
Revise: massage Area Exit data to required format and ensure it is correct Rename: (void)TArea::fast_ausgaengeBestimmen(int) ==> TArea::determineAreaExitsOfRoom (void)TArea::ausgaengeBestimmen(int) ==> TArea::determineAreaExits (const)(QList<int>)TArea::getAreaExits() const ==> TArea::getAreaExitRoomIds() Add new method to return area exit data in new, wanted format: (const)(QMultiMap<int, QPair<QString, int> >) getAreaExitRoomData() const In preparation to revising internal storage representation of area exit data moved the: (QMultiMap<int, QPair<int, int> >)(TArea *)->exits member from public to private area of class. To permit save and load the following have had to be made friends of the TArea class: (bool)TMap::serialize( QDataStream & ) and (bool)TMap::restore( QString ) Revise (void)TMap::init(Host *) to run (TArea *)->determineAreaExits() on current and all previous map file format versions, will not be needed on future version as the code to manage the areaExits data is now functional. Previous code would have done this only for versions prior to 14 files (current is 16) or if the lua function auditAreas() was manually run. In passing also modified code that "fixed-up" "old style" map labels so that it is no longer run on current version files and pushes any messages that that creates into the main profile console instead of using standard C++ cout calls which we deprecate now. All code blocks that have been touched by this series of commits have been re-formatted to current styles. Update copyrights on all files touched that have not already been marked as having been edited by myself. Revised TLuaInterpreter::getAreaExits(...) to take a second optional Boolean that if present and true cause it to return data about the area exit directions and the destination rooms, if false or omitted, returns only the rooms in the area that have exits out of it, reproducing the previous implementation. In either case the result is a table if there are area exits (or a nil for an isolate area without exits); two additional values are returned an informative, translatable, text message and an integer status code that reflects the same information. When moving a series of rooms to a different area via the 2D mapper's GUI the recalculations for the area extremes {by TArea::calcSpan()} and the out of area exits {by TArea::determineAreaExits()} can now be deferred until the last room has been moved by passing a third true (boolean) argument to TMap::setRoomArea(...) which defaults to false for other single room at a time usages. Though that method keeps a local copy of the areas that have been modified and thus need updating, should the last room NOT be processed (null TRooo pointer for room Id) a publicly accessible "mIsDirty" flag is also used so that recovery code can identify and clean up those affected areas otherwise. It is possible that this flag may be useful in other situations, such as when moving or adding multiple rooms WITHIN an area. *** This commit has been rebased so it's history might not be the same as someone else's copy of it *** Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-01-05 01:20:15 +00:00
}
}
if ((l.size.width() > std::numeric_limits<qreal>::max()) || (l.size.width() < -std::numeric_limits<qreal>::max())) {
mapLabels[areaID][i].size.setWidth(l.pix.width());
Revise: massage Area Exit data to required format and ensure it is correct Rename: (void)TArea::fast_ausgaengeBestimmen(int) ==> TArea::determineAreaExitsOfRoom (void)TArea::ausgaengeBestimmen(int) ==> TArea::determineAreaExits (const)(QList<int>)TArea::getAreaExits() const ==> TArea::getAreaExitRoomIds() Add new method to return area exit data in new, wanted format: (const)(QMultiMap<int, QPair<QString, int> >) getAreaExitRoomData() const In preparation to revising internal storage representation of area exit data moved the: (QMultiMap<int, QPair<int, int> >)(TArea *)->exits member from public to private area of class. To permit save and load the following have had to be made friends of the TArea class: (bool)TMap::serialize( QDataStream & ) and (bool)TMap::restore( QString ) Revise (void)TMap::init(Host *) to run (TArea *)->determineAreaExits() on current and all previous map file format versions, will not be needed on future version as the code to manage the areaExits data is now functional. Previous code would have done this only for versions prior to 14 files (current is 16) or if the lua function auditAreas() was manually run. In passing also modified code that "fixed-up" "old style" map labels so that it is no longer run on current version files and pushes any messages that that creates into the main profile console instead of using standard C++ cout calls which we deprecate now. All code blocks that have been touched by this series of commits have been re-formatted to current styles. Update copyrights on all files touched that have not already been marked as having been edited by myself. Revised TLuaInterpreter::getAreaExits(...) to take a second optional Boolean that if present and true cause it to return data about the area exit directions and the destination rooms, if false or omitted, returns only the rooms in the area that have exits out of it, reproducing the previous implementation. In either case the result is a table if there are area exits (or a nil for an isolate area without exits); two additional values are returned an informative, translatable, text message and an integer status code that reflects the same information. When moving a series of rooms to a different area via the 2D mapper's GUI the recalculations for the area extremes {by TArea::calcSpan()} and the out of area exits {by TArea::determineAreaExits()} can now be deferred until the last room has been moved by passing a third true (boolean) argument to TMap::setRoomArea(...) which defaults to false for other single room at a time usages. Though that method keeps a local copy of the areas that have been modified and thus need updating, should the last room NOT be processed (null TRooo pointer for room Id) a publicly accessible "mIsDirty" flag is also used so that recovery code can identify and clean up those affected areas otherwise. It is possible that this flag may be useful in other situations, such as when moving or adding multiple rooms WITHIN an area. *** This commit has been rebased so it's history might not be the same as someone else's copy of it *** Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-01-05 01:20:15 +00:00
}
if ((l.size.height() > std::numeric_limits<qreal>::max()) || (l.size.height() < -std::numeric_limits<qreal>::max())) {
mapLabels[areaID][i].size.setHeight(l.pix.height());
2012-12-29 02:16:28 +01:00
}
}
2012-12-29 02:16:28 +01:00
}
}
}
mpRoomDB->auditRooms(roomRemapping, areaRemapping);
// The second half of old mpRoomDB->initAreasForOldMaps() - needed to fixup
// all the (TArea *)->areaExits() that were built wrongly previously,
// calcSpan() may not be required to be done here and now but it is in my
// sights as a target for revision in the future. Slysven
QMapIterator<int, TArea*> itArea(mpRoomDB->getAreaMap());
while (itArea.hasNext()) {
itArea.next();
itArea.value()->determineAreaExits();
itArea.value()->calcSpan();
itArea.value()->mIsDirty = false;
}
{ // Blocked - just to limit the scope of infoMsg...!
QString infoMsg = tr("[ OK ] - Auditing of map completed (%1s). Enjoy your game...").arg(_time.nsecsElapsed() * 1.0e-9, 0, 'f', 2);
postMessage(infoMsg);
appendErrorMsg(infoMsg);
}
auto loadTime = mpHost->getLuaInterpreter()->condenseMapLoad();
if (loadTime != -1.0) {
QString msg = tr("[ OK ] - Map loaded successfully (%1s).").arg(loadTime);
postMessage(msg);
}
2010-08-25 00:41:43 +02:00
}
2011-07-04 11:50:19 +02:00
void TMap::setView(float x, float y, float z, float zoom)
2010-08-25 00:41:43 +02:00
{
}
void TMap::tidyMap(int areaID)
2010-12-28 23:31:03 +01:00
{
}
void TMap::solveRoomCollision(int id, int creationDirection, bool PCheck)
2010-12-28 23:31:03 +01:00
{
}
QList<int> TMap::detectRoomCollisions(int id)
2010-12-28 23:31:03 +01:00
{
Enhance: 2D Map Room Selection, better big map performance + other mods In situations when we check whether a room in an area both for internal purposes and when rooms on a mapper is selected, using QSet instead of a QList is faster in performance for large numbers of entries in set. As it reworks the mapper code it also fixes issue where the multi-room selection widget overwrites map info display - the latter is re-sized and re-positioned (and regains a semi-transparent background which helped to show this working during debugging!) The former is now: dynamically resized to only take up enough vertical space to show the selected rooms; also displays the associate room names if there are any, expanding the widget as required; sorts the display either by room name or number and in either direction. The mouse wheel handler is modified so that using the scroll wheel ONLY scrolls the list within the widget - previously (by default) once the end in either direction was hit the related events would be passed up the widget chain where it would otherwise invoke the 2D mapper's zoom in/out code. In modifying the zoom in/out code I have replaced the (obsoleted in Qt5.x) QWheelEvent::delta() method to use the QWheelEvent::angleDelta() method, using only the Y-component the latter provides. If the Control modifier is active the zoom value is modified by an extra x10 factor which is useful when working with large maps as otherwise the zooming rate is "slow" at high values - ideally the control should be logarithmic or exponential or some other "non-linear" algorithm to work more uniformly over the range of practical use cases. The code to paint the map info text has been revised also to use the mMapInfoRect which was being defined but NOT used. The info text now reports whether the room name is for the player room {set via the Lua command centerview(roomId)} or is one that is selected by mouse dragging - and if more than one room is selected by that indicates the count of rooms in the selection. In the case of multiple rooms being selected the room that single room context menu operations will act upon is highlighted by the same style of yellow target used to show the custom exit line destination but is drawn in a different point in the code so that it is drawn over the rooms. Because of the change to the way that multiple rooms are selected routines that use that information had to be revised - in doing so it was possible to improve the usability/operation of: T2DMap::slot_movePosition() T2DMap::slot_setCharacter() T2DMap::slot_spread() T2DMap::slot_shrink() T2DMap::slot_lockRoom(): T2DMap::slot_unlockRoom(): This method, also resurrected here to the 2D mapper context menu, as it is also affected by the changes: T2DMap::slot_setPlayerLocation() There was a slot_setPlayerLocation code that set a global lua variable mRoomSet and moved the player to that room Id (introduced in commit-c25faf4e 2012-05-04 07:44:36 by Heiko) but the corresponding 2D Mapper context menu item that called it was commented out and thus removed from the menu in commit-93f65962 2012-12-29 01:16:28 also by Heiko without any explaination. Since that has not been used since then I have replaced it with a new Event: sysManualLocationSetEvent with a single numeric value which is the new (valid) room Id number - user scripts can capture this event if they want to know that the user has manually re-positioned the current player room in the 2D mapper. In passing: * Fixed Text font changing between docked and un-docked forms of the built-in map widget (when not incorporated into a console) - as it was not previously explicitly set it assumed the Application one whilst docked but the Qt System one when a free floating widget - and the two do not have to be the same. This fixes: https://bugs.launchpad.net/mudlet/+bug/1432841 . * Starts to fix https://bugs.launchpad.net/mudlet/+bug/1376511 by changing from use of obsolete QWheelEvent::delta() to QWheelEvent::angleDelta() in T2DMap::wheelEvent(...); will need duplicating in TTextEdit::wheelEvent(...) and GLWidget::wheelEvent(...) . * Adds the profile name to the Mapper dockable widget so that it's parentage can be determined when multiple profiles are active. Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2016-03-08 08:35:07 +00:00
QList<int> collList;
TRoom* pR = mpRoomDB->getRoom(id);
if (!pR) {
Enhance: 2D Map Room Selection, better big map performance + other mods In situations when we check whether a room in an area both for internal purposes and when rooms on a mapper is selected, using QSet instead of a QList is faster in performance for large numbers of entries in set. As it reworks the mapper code it also fixes issue where the multi-room selection widget overwrites map info display - the latter is re-sized and re-positioned (and regains a semi-transparent background which helped to show this working during debugging!) The former is now: dynamically resized to only take up enough vertical space to show the selected rooms; also displays the associate room names if there are any, expanding the widget as required; sorts the display either by room name or number and in either direction. The mouse wheel handler is modified so that using the scroll wheel ONLY scrolls the list within the widget - previously (by default) once the end in either direction was hit the related events would be passed up the widget chain where it would otherwise invoke the 2D mapper's zoom in/out code. In modifying the zoom in/out code I have replaced the (obsoleted in Qt5.x) QWheelEvent::delta() method to use the QWheelEvent::angleDelta() method, using only the Y-component the latter provides. If the Control modifier is active the zoom value is modified by an extra x10 factor which is useful when working with large maps as otherwise the zooming rate is "slow" at high values - ideally the control should be logarithmic or exponential or some other "non-linear" algorithm to work more uniformly over the range of practical use cases. The code to paint the map info text has been revised also to use the mMapInfoRect which was being defined but NOT used. The info text now reports whether the room name is for the player room {set via the Lua command centerview(roomId)} or is one that is selected by mouse dragging - and if more than one room is selected by that indicates the count of rooms in the selection. In the case of multiple rooms being selected the room that single room context menu operations will act upon is highlighted by the same style of yellow target used to show the custom exit line destination but is drawn in a different point in the code so that it is drawn over the rooms. Because of the change to the way that multiple rooms are selected routines that use that information had to be revised - in doing so it was possible to improve the usability/operation of: T2DMap::slot_movePosition() T2DMap::slot_setCharacter() T2DMap::slot_spread() T2DMap::slot_shrink() T2DMap::slot_lockRoom(): T2DMap::slot_unlockRoom(): This method, also resurrected here to the 2D mapper context menu, as it is also affected by the changes: T2DMap::slot_setPlayerLocation() There was a slot_setPlayerLocation code that set a global lua variable mRoomSet and moved the player to that room Id (introduced in commit-c25faf4e 2012-05-04 07:44:36 by Heiko) but the corresponding 2D Mapper context menu item that called it was commented out and thus removed from the menu in commit-93f65962 2012-12-29 01:16:28 also by Heiko without any explaination. Since that has not been used since then I have replaced it with a new Event: sysManualLocationSetEvent with a single numeric value which is the new (valid) room Id number - user scripts can capture this event if they want to know that the user has manually re-positioned the current player room in the 2D mapper. In passing: * Fixed Text font changing between docked and un-docked forms of the built-in map widget (when not incorporated into a console) - as it was not previously explicitly set it assumed the Application one whilst docked but the Qt System one when a free floating widget - and the two do not have to be the same. This fixes: https://bugs.launchpad.net/mudlet/+bug/1432841 . * Starts to fix https://bugs.launchpad.net/mudlet/+bug/1376511 by changing from use of obsolete QWheelEvent::delta() to QWheelEvent::angleDelta() in T2DMap::wheelEvent(...); will need duplicating in TTextEdit::wheelEvent(...) and GLWidget::wheelEvent(...) . * Adds the profile name to the Mapper dockable widget so that it's parentage can be determined when multiple profiles are active. Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2016-03-08 08:35:07 +00:00
return collList;
2010-12-28 23:31:03 +01:00
}
2013-03-22 12:47:58 +01:00
int area = pR->getArea();
int x = pR->x;
int y = pR->y;
int z = pR->z;
TArea* pA = mpRoomDB->getArea(area);
if (!pA) {
Enhance: 2D Map Room Selection, better big map performance + other mods In situations when we check whether a room in an area both for internal purposes and when rooms on a mapper is selected, using QSet instead of a QList is faster in performance for large numbers of entries in set. As it reworks the mapper code it also fixes issue where the multi-room selection widget overwrites map info display - the latter is re-sized and re-positioned (and regains a semi-transparent background which helped to show this working during debugging!) The former is now: dynamically resized to only take up enough vertical space to show the selected rooms; also displays the associate room names if there are any, expanding the widget as required; sorts the display either by room name or number and in either direction. The mouse wheel handler is modified so that using the scroll wheel ONLY scrolls the list within the widget - previously (by default) once the end in either direction was hit the related events would be passed up the widget chain where it would otherwise invoke the 2D mapper's zoom in/out code. In modifying the zoom in/out code I have replaced the (obsoleted in Qt5.x) QWheelEvent::delta() method to use the QWheelEvent::angleDelta() method, using only the Y-component the latter provides. If the Control modifier is active the zoom value is modified by an extra x10 factor which is useful when working with large maps as otherwise the zooming rate is "slow" at high values - ideally the control should be logarithmic or exponential or some other "non-linear" algorithm to work more uniformly over the range of practical use cases. The code to paint the map info text has been revised also to use the mMapInfoRect which was being defined but NOT used. The info text now reports whether the room name is for the player room {set via the Lua command centerview(roomId)} or is one that is selected by mouse dragging - and if more than one room is selected by that indicates the count of rooms in the selection. In the case of multiple rooms being selected the room that single room context menu operations will act upon is highlighted by the same style of yellow target used to show the custom exit line destination but is drawn in a different point in the code so that it is drawn over the rooms. Because of the change to the way that multiple rooms are selected routines that use that information had to be revised - in doing so it was possible to improve the usability/operation of: T2DMap::slot_movePosition() T2DMap::slot_setCharacter() T2DMap::slot_spread() T2DMap::slot_shrink() T2DMap::slot_lockRoom(): T2DMap::slot_unlockRoom(): This method, also resurrected here to the 2D mapper context menu, as it is also affected by the changes: T2DMap::slot_setPlayerLocation() There was a slot_setPlayerLocation code that set a global lua variable mRoomSet and moved the player to that room Id (introduced in commit-c25faf4e 2012-05-04 07:44:36 by Heiko) but the corresponding 2D Mapper context menu item that called it was commented out and thus removed from the menu in commit-93f65962 2012-12-29 01:16:28 also by Heiko without any explaination. Since that has not been used since then I have replaced it with a new Event: sysManualLocationSetEvent with a single numeric value which is the new (valid) room Id number - user scripts can capture this event if they want to know that the user has manually re-positioned the current player room in the 2D mapper. In passing: * Fixed Text font changing between docked and un-docked forms of the built-in map widget (when not incorporated into a console) - as it was not previously explicitly set it assumed the Application one whilst docked but the Qt System one when a free floating widget - and the two do not have to be the same. This fixes: https://bugs.launchpad.net/mudlet/+bug/1432841 . * Starts to fix https://bugs.launchpad.net/mudlet/+bug/1376511 by changing from use of obsolete QWheelEvent::delta() to QWheelEvent::angleDelta() in T2DMap::wheelEvent(...); will need duplicating in TTextEdit::wheelEvent(...) and GLWidget::wheelEvent(...) . * Adds the profile name to the Mapper dockable widget so that it's parentage can be determined when multiple profiles are active. Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2016-03-08 08:35:07 +00:00
return collList;
2010-12-28 23:31:03 +01:00
}
Enhance: 2D Map Room Selection, better big map performance + other mods In situations when we check whether a room in an area both for internal purposes and when rooms on a mapper is selected, using QSet instead of a QList is faster in performance for large numbers of entries in set. As it reworks the mapper code it also fixes issue where the multi-room selection widget overwrites map info display - the latter is re-sized and re-positioned (and regains a semi-transparent background which helped to show this working during debugging!) The former is now: dynamically resized to only take up enough vertical space to show the selected rooms; also displays the associate room names if there are any, expanding the widget as required; sorts the display either by room name or number and in either direction. The mouse wheel handler is modified so that using the scroll wheel ONLY scrolls the list within the widget - previously (by default) once the end in either direction was hit the related events would be passed up the widget chain where it would otherwise invoke the 2D mapper's zoom in/out code. In modifying the zoom in/out code I have replaced the (obsoleted in Qt5.x) QWheelEvent::delta() method to use the QWheelEvent::angleDelta() method, using only the Y-component the latter provides. If the Control modifier is active the zoom value is modified by an extra x10 factor which is useful when working with large maps as otherwise the zooming rate is "slow" at high values - ideally the control should be logarithmic or exponential or some other "non-linear" algorithm to work more uniformly over the range of practical use cases. The code to paint the map info text has been revised also to use the mMapInfoRect which was being defined but NOT used. The info text now reports whether the room name is for the player room {set via the Lua command centerview(roomId)} or is one that is selected by mouse dragging - and if more than one room is selected by that indicates the count of rooms in the selection. In the case of multiple rooms being selected the room that single room context menu operations will act upon is highlighted by the same style of yellow target used to show the custom exit line destination but is drawn in a different point in the code so that it is drawn over the rooms. Because of the change to the way that multiple rooms are selected routines that use that information had to be revised - in doing so it was possible to improve the usability/operation of: T2DMap::slot_movePosition() T2DMap::slot_setCharacter() T2DMap::slot_spread() T2DMap::slot_shrink() T2DMap::slot_lockRoom(): T2DMap::slot_unlockRoom(): This method, also resurrected here to the 2D mapper context menu, as it is also affected by the changes: T2DMap::slot_setPlayerLocation() There was a slot_setPlayerLocation code that set a global lua variable mRoomSet and moved the player to that room Id (introduced in commit-c25faf4e 2012-05-04 07:44:36 by Heiko) but the corresponding 2D Mapper context menu item that called it was commented out and thus removed from the menu in commit-93f65962 2012-12-29 01:16:28 also by Heiko without any explaination. Since that has not been used since then I have replaced it with a new Event: sysManualLocationSetEvent with a single numeric value which is the new (valid) room Id number - user scripts can capture this event if they want to know that the user has manually re-positioned the current player room in the 2D mapper. In passing: * Fixed Text font changing between docked and un-docked forms of the built-in map widget (when not incorporated into a console) - as it was not previously explicitly set it assumed the Application one whilst docked but the Qt System one when a free floating widget - and the two do not have to be the same. This fixes: https://bugs.launchpad.net/mudlet/+bug/1432841 . * Starts to fix https://bugs.launchpad.net/mudlet/+bug/1376511 by changing from use of obsolete QWheelEvent::delta() to QWheelEvent::angleDelta() in T2DMap::wheelEvent(...); will need duplicating in TTextEdit::wheelEvent(...) and GLWidget::wheelEvent(...) . * Adds the profile name to the Mapper dockable widget so that it's parentage can be determined when multiple profiles are active. Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2016-03-08 08:35:07 +00:00
QSetIterator<int> itRoom(pA->getAreaRooms());
while (itRoom.hasNext()) {
Enhance: 2D Map Room Selection, better big map performance + other mods In situations when we check whether a room in an area both for internal purposes and when rooms on a mapper is selected, using QSet instead of a QList is faster in performance for large numbers of entries in set. As it reworks the mapper code it also fixes issue where the multi-room selection widget overwrites map info display - the latter is re-sized and re-positioned (and regains a semi-transparent background which helped to show this working during debugging!) The former is now: dynamically resized to only take up enough vertical space to show the selected rooms; also displays the associate room names if there are any, expanding the widget as required; sorts the display either by room name or number and in either direction. The mouse wheel handler is modified so that using the scroll wheel ONLY scrolls the list within the widget - previously (by default) once the end in either direction was hit the related events would be passed up the widget chain where it would otherwise invoke the 2D mapper's zoom in/out code. In modifying the zoom in/out code I have replaced the (obsoleted in Qt5.x) QWheelEvent::delta() method to use the QWheelEvent::angleDelta() method, using only the Y-component the latter provides. If the Control modifier is active the zoom value is modified by an extra x10 factor which is useful when working with large maps as otherwise the zooming rate is "slow" at high values - ideally the control should be logarithmic or exponential or some other "non-linear" algorithm to work more uniformly over the range of practical use cases. The code to paint the map info text has been revised also to use the mMapInfoRect which was being defined but NOT used. The info text now reports whether the room name is for the player room {set via the Lua command centerview(roomId)} or is one that is selected by mouse dragging - and if more than one room is selected by that indicates the count of rooms in the selection. In the case of multiple rooms being selected the room that single room context menu operations will act upon is highlighted by the same style of yellow target used to show the custom exit line destination but is drawn in a different point in the code so that it is drawn over the rooms. Because of the change to the way that multiple rooms are selected routines that use that information had to be revised - in doing so it was possible to improve the usability/operation of: T2DMap::slot_movePosition() T2DMap::slot_setCharacter() T2DMap::slot_spread() T2DMap::slot_shrink() T2DMap::slot_lockRoom(): T2DMap::slot_unlockRoom(): This method, also resurrected here to the 2D mapper context menu, as it is also affected by the changes: T2DMap::slot_setPlayerLocation() There was a slot_setPlayerLocation code that set a global lua variable mRoomSet and moved the player to that room Id (introduced in commit-c25faf4e 2012-05-04 07:44:36 by Heiko) but the corresponding 2D Mapper context menu item that called it was commented out and thus removed from the menu in commit-93f65962 2012-12-29 01:16:28 also by Heiko without any explaination. Since that has not been used since then I have replaced it with a new Event: sysManualLocationSetEvent with a single numeric value which is the new (valid) room Id number - user scripts can capture this event if they want to know that the user has manually re-positioned the current player room in the 2D mapper. In passing: * Fixed Text font changing between docked and un-docked forms of the built-in map widget (when not incorporated into a console) - as it was not previously explicitly set it assumed the Application one whilst docked but the Qt System one when a free floating widget - and the two do not have to be the same. This fixes: https://bugs.launchpad.net/mudlet/+bug/1432841 . * Starts to fix https://bugs.launchpad.net/mudlet/+bug/1376511 by changing from use of obsolete QWheelEvent::delta() to QWheelEvent::angleDelta() in T2DMap::wheelEvent(...); will need duplicating in TTextEdit::wheelEvent(...) and GLWidget::wheelEvent(...) . * Adds the profile name to the Mapper dockable widget so that it's parentage can be determined when multiple profiles are active. Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2016-03-08 08:35:07 +00:00
int checkRoomId = itRoom.next();
pR = mpRoomDB->getRoom(checkRoomId);
if (!pR) {
Enhance: 2D Map Room Selection, better big map performance + other mods In situations when we check whether a room in an area both for internal purposes and when rooms on a mapper is selected, using QSet instead of a QList is faster in performance for large numbers of entries in set. As it reworks the mapper code it also fixes issue where the multi-room selection widget overwrites map info display - the latter is re-sized and re-positioned (and regains a semi-transparent background which helped to show this working during debugging!) The former is now: dynamically resized to only take up enough vertical space to show the selected rooms; also displays the associate room names if there are any, expanding the widget as required; sorts the display either by room name or number and in either direction. The mouse wheel handler is modified so that using the scroll wheel ONLY scrolls the list within the widget - previously (by default) once the end in either direction was hit the related events would be passed up the widget chain where it would otherwise invoke the 2D mapper's zoom in/out code. In modifying the zoom in/out code I have replaced the (obsoleted in Qt5.x) QWheelEvent::delta() method to use the QWheelEvent::angleDelta() method, using only the Y-component the latter provides. If the Control modifier is active the zoom value is modified by an extra x10 factor which is useful when working with large maps as otherwise the zooming rate is "slow" at high values - ideally the control should be logarithmic or exponential or some other "non-linear" algorithm to work more uniformly over the range of practical use cases. The code to paint the map info text has been revised also to use the mMapInfoRect which was being defined but NOT used. The info text now reports whether the room name is for the player room {set via the Lua command centerview(roomId)} or is one that is selected by mouse dragging - and if more than one room is selected by that indicates the count of rooms in the selection. In the case of multiple rooms being selected the room that single room context menu operations will act upon is highlighted by the same style of yellow target used to show the custom exit line destination but is drawn in a different point in the code so that it is drawn over the rooms. Because of the change to the way that multiple rooms are selected routines that use that information had to be revised - in doing so it was possible to improve the usability/operation of: T2DMap::slot_movePosition() T2DMap::slot_setCharacter() T2DMap::slot_spread() T2DMap::slot_shrink() T2DMap::slot_lockRoom(): T2DMap::slot_unlockRoom(): This method, also resurrected here to the 2D mapper context menu, as it is also affected by the changes: T2DMap::slot_setPlayerLocation() There was a slot_setPlayerLocation code that set a global lua variable mRoomSet and moved the player to that room Id (introduced in commit-c25faf4e 2012-05-04 07:44:36 by Heiko) but the corresponding 2D Mapper context menu item that called it was commented out and thus removed from the menu in commit-93f65962 2012-12-29 01:16:28 also by Heiko without any explaination. Since that has not been used since then I have replaced it with a new Event: sysManualLocationSetEvent with a single numeric value which is the new (valid) room Id number - user scripts can capture this event if they want to know that the user has manually re-positioned the current player room in the 2D mapper. In passing: * Fixed Text font changing between docked and un-docked forms of the built-in map widget (when not incorporated into a console) - as it was not previously explicitly set it assumed the Application one whilst docked but the Qt System one when a free floating widget - and the two do not have to be the same. This fixes: https://bugs.launchpad.net/mudlet/+bug/1432841 . * Starts to fix https://bugs.launchpad.net/mudlet/+bug/1376511 by changing from use of obsolete QWheelEvent::delta() to QWheelEvent::angleDelta() in T2DMap::wheelEvent(...); will need duplicating in TTextEdit::wheelEvent(...) and GLWidget::wheelEvent(...) . * Adds the profile name to the Mapper dockable widget so that it's parentage can be determined when multiple profiles are active. Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2016-03-08 08:35:07 +00:00
continue;
}
if (pR->x == x && pR->y == y && pR->z == z) {
collList.push_back(checkRoomId);
2010-12-28 23:31:03 +01:00
}
}
return collList;
}
Enhance: fix map downloading code, add manual XML map importing (#326) * Enhance: fix map downloading code, add manual XML map importing A recent move by I.R.E. to using SSL for their public MUD map URLs broke the ability for Mudlet to download those XML format files. This commit addresses this issue (as mentioned in, but not the original problem referred to in https://bugs.launchpad.net/mudlet/+bug/1427364) the revision to the code does now use "https://www.<MUD URL>/maps/map.xml" as a default name for the I.R.E. MUDS - however the method that initiates the download which was moved to TMap class from the dlgMapper one (see below) is now: (bool) TMap::downloadMap( const QString * remoteUrl = Q_NULLPTR, const QString * localFileName = Q_NULLPTR ) which if not supplied with any arguments behaves as before. However the remoteUrl argument may be given as a full QString including the scheme (the bit of the URL at the beginning before the ':') to override that and a second argument may be used to provide a different name to use for the local file name which if is a RELATIVE pathFileName will be resolved in relation to the profile directory. At present no use is made of this additional functionality but it may be useful for use with other MUDs if they should choose to provide XML map files with other remote locations and scripts using a different local filename. As a long-standing thing that needed doing I have finally provided a means to import a map XML file that - for instance - has already been download. It had been noted that there was no way to read those I.R.E. map files even if they had been obtained from a web browser able to correctly handle https: URLs - now both the TLuaInterpreter::loadMap() and the dlgProfilePreference "loadMap" button {NOT the IRE only "map download" one} will both handle files ending in ".xml" (not case sensitive so it'll work MacOS platforms as well!} For the loadMap case it will be necessary to change the filetype filter on the File Selection dialog to select "xml" files. During testing it became clear to me that it was possible to try and read one or more XML files via several mechanisms simultaneously with "unhelpful" consequences. As well as hitting the dlgProfilePreferences IRE "map download" multiple times, the TLuaInterpreter::loadMap() does NOT block until the map has been loaded and as the import time {running of XMLinport::readPackage(...)} is of significant duration for a large map (a debug, without optimisation, build on my 1.8GHz Quad-core took over two minutes to process the current Achaea map file) it is very possible to get conditions where the same profile will try to run XMLinport::readPackage(...) asynchronously - given that a profile only supports ONE map at a time it was necessary to fit a QMutex to prevent the part of the XMLinport class relating to XML Map files being called from different places in the map related code. This means that if a map download is started further downloads and any local map imports will fail until that first download has completed or aborted. Similarly a local import will prevent a download being started. As a side effect this cures: https://bugs.launchpad.net/mudlet/+bug/852861 - "Map download button starts another download thread if one is already going" The previous XML import code was not adding the rooms that it parsed to the relevant TArea::rooms member - although this would be picked-up and fixed by TMap::audit() later on, this would be accompanied by an error message about every single room. The code now builds up this information while parsing the rooms' details and inserts it so that this does not cause report-able problems during the TMap::audit() execution - the data gathered also allows missing areas to be spotted so that if a room claimed to belong to an area that was not included in the preceding areas' data an unnamed area is created for it. As a consequence of the long time to actually parse an XML map file I have enhanced the progress dialog that was originally used to track the map file download. It is now retained until the file is completely imported and shows more information about the process - importantly it shows during the XMLimport::readRoom(...) the room id being processed - and THAT method is the time/cpu hog so seeing something happening during the time that Mudlet otherwise appears to hang is useful feedback even if it adds a few seconds to the overall duration (may be more than a minute). This dialog is now also used during the other routes that involve reading an XML file and there is now a bit of consistence with the on-screen messages. Whilst inspecting XMLimport class I found there was some uncertain initialisation which I have tidied up. In summary: Added: * (bool) TConsole::importMap(const QString & location) * (void) TRoomDB::setAreaRooms(const int areaId, const QSet<int> & roomIds) * image file mudlet_map_download.png used as icon for download/import progress dialog * (bool) TMap::importMap(QFile & file) * (bool) TMap::readXmlMapFile(QFile & file) * (void) TMap::slot_downloadError(QNetworkReply::NetworkError error) * (void) TMap::reportStringToProgressDialog(const QString text) * (void) TMap::reportProgressToProgressDialog(const int current, const int maximum) Revised: * (int)TLuaInterpreter::loadMap( lua_State * ) * Moved XML map download code from dlgMapper class to the TMap one: + (void) dlgMapper::downloadMap() ==> (bool) TMap::downloadMap(const QString * remoteUrl, const QString * localFileName) + (void) dlgMapper::setDownloadProgress(qint64, qint64) ==> (void) TMap::slot_setDownloadProgress(qint64,qint64) + (void) dlgMapper::cancel() ==> (void) TMap::slot_downloadCancel() + (void) dlgMapper::replyFinished(QNetworkReply *) ==> (void) TMap::slot_replyFinished(QNetworkReply *) * Enhanced download progress indication to also include parsing which can take even more time than download! * Provide means to import local XML map file * Prevent trying to import/download more than one map at a time Renamed: * (void) XMLimport::readAreaNames() ==> XMLimport::readArea() - for consistency with related functions Commented out unused: * (void) XMLimport::readUnknownRoomElement() Note the movement of the map file download code to the TMap class does require making the latter a class with the Q_OBJECT macro (which removes the need for Q_DECLARE_TR_FUNCTIONS as a side-effect!) - though as another side-effect the TMap header needed a boost name specifier added to one identifier as that identifier ("property") exists in both boost and QObject classes!!! YOU MAY NEED TO RUN QMAKE ON THE PROJECT IF THE BUILD SYSTEM DOES NOT PICK UP THE ADDITION OF "Q_OBJECT" TO TMAP CLASS. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: Include missing #include, remove unused return value The absence of this was causing build errors on the Travis C.I. platform! Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: move TMap.h to mudlet_MOC_HDRS to fix CMake build issue As we have made TMap inherit from QOject - to have signal/slot functionality that class needs to be run through Qt's MOC - and to do that with the CMake project/build system it needs to be included in the files included in the projects *_MOC_HDRS {and removed from the *_HDRS} variable. Also spotted a trivial error in that specifying a const return value from method is ineffective and pointless - so removed it from: TMap::retrieveMapFileStats(QString,QString *,int *,int *,int *,int *) Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: clean up TMap initialisation/clearing actions Now restores the customEnvColors set up on initialisation but that was cleared when the map replaced with another one that is loaded {which subsequently replaces that element anyway} or imported {which merely writes over it, replacing any matching keys}. Initialises elements that when inspected on the entry to the constructor proper previously were not being set to a consistent value {booleans/ints/floats}. NOTE: This will now clear the map user data member when the map is cleared if the date is required to be saved when one map is loaded OR IMPORTED over an existing one then the data will need to be saved outside of the map - as is already need for areas and rooms user data! Also comment out or remove unused members/methods: * (void) TMap::getConnectedNodesGreaterThanX(int, int) * (void) TMap::getConnectedNodesSmallerThanX(int, int) * (void) TMap::getConnectedNodesGreaterThanY(int, int) * (void) TMap::getConnectedNodesSmallerThanY(int, int) * (void) TMap::astBreitenAnpassung(int, int) * (void) TMap::astHoehenAnpassung(int, int) * (void) TMap::exportMapToDatabase() * (void) TMap::importMapFromDatabase() * (QVector3D) TMap::span * (int) TMap::mViewArea * (QMap<QString, int>) TMap::pixNameTable * (QMap<int, QPixmap>) TMap::pixTable * (bool) TMap::isToDisplayAuditErrorsToConsole Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * ImplimentationFixes: activate a valid optimisation & remove redundant code Adding a true as a non-default 3rd argument to TRoomDB::addRoom(...) call in XMLimport::readRoom(...) enables a significant optimisation (skips a computationally expensive step when ADDING a room to new map) which dramatically reduces the time to parse an XML map file. It also pointed to the fact that the TRoomDB::entranceMap was already correctly being handled and didn't need to be regenerated in XMLimport::readRoom(...) so the code that was added in a previous commit was redundant and could be removed. A code error in TMap::slot_setDownloadProgress(...) that caused an issue that a reviewer found on test has been fixed - the total download filesize that was being sent by the Qt system signal that is connected to this slot was a -1 value (as IS DOCUMENTED) when the Qt system does NOT know the size of a QNetworkReply in advance of reaching the end of the download was incorrectly handled in a previous commit in this change set. Also found during testing that there is no need for an error message for the QNetworkReply::OperationCanceledError case in TMap::slot_replayFinished(...) as it is already handled in the TMap::slot_downloadCancel() slot. Changed the text put up onto the progress widget during the XML room parsing to be a room count - which is likely more useful and to only do it for every hundredth room - which reduces any delay "wasted" in writing to the display - combined, the effects seem satisfactory IMHO. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: provide error messages for TLuaInterpreter::loadMap(...) Errors for the XML map file importing process as initiated from the Lua command should be returned to that command rather than plastered onto the main profile console - this commit attempts to perform that effect. In testing found that there was no error handling for failure to find or open the nominated file so messages for that have been added as well. Due to the previous program logic the action of creating a mapper widget using the main toolbar button automatically loaded the "default" (the newest Mudlet Map file format file from the currently active profile's map sub-directory). Under some previous situations it looked as though a map might be loaded twice as mudlet::slot_mapper() was called both directly and via signal/slot action. These were resolved by turning that slot into a wrapper that now calls the body of code formerly within to a new method mudlet::createMapper( bool isToLoadDefaultMapFile = true ) with a the default value as an argument. This allows other usages of the body of code to be called directly with a suitable argument, which for the TConsole::loadMap() & TConsole::importMap() and the dlgProfilePreferences::downloadMap() cases is false as they are all do not want the "default" map! Also: * spotted a word "area" missing from an advisory text in TRoom::auditRooms(...). Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: fix minor bug, correct a spelling, undo a few capitalisations Under certain, unanticipated (error with no error message) conditions TLuaInterpreter::loadMap(...) would push both a nil and then a false value onto the stack for return {wrong} but only indicate one value {correct}. The textual matters were found during peer review. off-by: Stephen Lyons <slysven@virginmedia.com>
2016-10-13 09:18:48 +01:00
// Not used:
//void TMap::astBreitenAnpassung( int id, int id2 )
//{
//}
2010-12-28 23:31:03 +01:00
Enhance: fix map downloading code, add manual XML map importing (#326) * Enhance: fix map downloading code, add manual XML map importing A recent move by I.R.E. to using SSL for their public MUD map URLs broke the ability for Mudlet to download those XML format files. This commit addresses this issue (as mentioned in, but not the original problem referred to in https://bugs.launchpad.net/mudlet/+bug/1427364) the revision to the code does now use "https://www.<MUD URL>/maps/map.xml" as a default name for the I.R.E. MUDS - however the method that initiates the download which was moved to TMap class from the dlgMapper one (see below) is now: (bool) TMap::downloadMap( const QString * remoteUrl = Q_NULLPTR, const QString * localFileName = Q_NULLPTR ) which if not supplied with any arguments behaves as before. However the remoteUrl argument may be given as a full QString including the scheme (the bit of the URL at the beginning before the ':') to override that and a second argument may be used to provide a different name to use for the local file name which if is a RELATIVE pathFileName will be resolved in relation to the profile directory. At present no use is made of this additional functionality but it may be useful for use with other MUDs if they should choose to provide XML map files with other remote locations and scripts using a different local filename. As a long-standing thing that needed doing I have finally provided a means to import a map XML file that - for instance - has already been download. It had been noted that there was no way to read those I.R.E. map files even if they had been obtained from a web browser able to correctly handle https: URLs - now both the TLuaInterpreter::loadMap() and the dlgProfilePreference "loadMap" button {NOT the IRE only "map download" one} will both handle files ending in ".xml" (not case sensitive so it'll work MacOS platforms as well!} For the loadMap case it will be necessary to change the filetype filter on the File Selection dialog to select "xml" files. During testing it became clear to me that it was possible to try and read one or more XML files via several mechanisms simultaneously with "unhelpful" consequences. As well as hitting the dlgProfilePreferences IRE "map download" multiple times, the TLuaInterpreter::loadMap() does NOT block until the map has been loaded and as the import time {running of XMLinport::readPackage(...)} is of significant duration for a large map (a debug, without optimisation, build on my 1.8GHz Quad-core took over two minutes to process the current Achaea map file) it is very possible to get conditions where the same profile will try to run XMLinport::readPackage(...) asynchronously - given that a profile only supports ONE map at a time it was necessary to fit a QMutex to prevent the part of the XMLinport class relating to XML Map files being called from different places in the map related code. This means that if a map download is started further downloads and any local map imports will fail until that first download has completed or aborted. Similarly a local import will prevent a download being started. As a side effect this cures: https://bugs.launchpad.net/mudlet/+bug/852861 - "Map download button starts another download thread if one is already going" The previous XML import code was not adding the rooms that it parsed to the relevant TArea::rooms member - although this would be picked-up and fixed by TMap::audit() later on, this would be accompanied by an error message about every single room. The code now builds up this information while parsing the rooms' details and inserts it so that this does not cause report-able problems during the TMap::audit() execution - the data gathered also allows missing areas to be spotted so that if a room claimed to belong to an area that was not included in the preceding areas' data an unnamed area is created for it. As a consequence of the long time to actually parse an XML map file I have enhanced the progress dialog that was originally used to track the map file download. It is now retained until the file is completely imported and shows more information about the process - importantly it shows during the XMLimport::readRoom(...) the room id being processed - and THAT method is the time/cpu hog so seeing something happening during the time that Mudlet otherwise appears to hang is useful feedback even if it adds a few seconds to the overall duration (may be more than a minute). This dialog is now also used during the other routes that involve reading an XML file and there is now a bit of consistence with the on-screen messages. Whilst inspecting XMLimport class I found there was some uncertain initialisation which I have tidied up. In summary: Added: * (bool) TConsole::importMap(const QString & location) * (void) TRoomDB::setAreaRooms(const int areaId, const QSet<int> & roomIds) * image file mudlet_map_download.png used as icon for download/import progress dialog * (bool) TMap::importMap(QFile & file) * (bool) TMap::readXmlMapFile(QFile & file) * (void) TMap::slot_downloadError(QNetworkReply::NetworkError error) * (void) TMap::reportStringToProgressDialog(const QString text) * (void) TMap::reportProgressToProgressDialog(const int current, const int maximum) Revised: * (int)TLuaInterpreter::loadMap( lua_State * ) * Moved XML map download code from dlgMapper class to the TMap one: + (void) dlgMapper::downloadMap() ==> (bool) TMap::downloadMap(const QString * remoteUrl, const QString * localFileName) + (void) dlgMapper::setDownloadProgress(qint64, qint64) ==> (void) TMap::slot_setDownloadProgress(qint64,qint64) + (void) dlgMapper::cancel() ==> (void) TMap::slot_downloadCancel() + (void) dlgMapper::replyFinished(QNetworkReply *) ==> (void) TMap::slot_replyFinished(QNetworkReply *) * Enhanced download progress indication to also include parsing which can take even more time than download! * Provide means to import local XML map file * Prevent trying to import/download more than one map at a time Renamed: * (void) XMLimport::readAreaNames() ==> XMLimport::readArea() - for consistency with related functions Commented out unused: * (void) XMLimport::readUnknownRoomElement() Note the movement of the map file download code to the TMap class does require making the latter a class with the Q_OBJECT macro (which removes the need for Q_DECLARE_TR_FUNCTIONS as a side-effect!) - though as another side-effect the TMap header needed a boost name specifier added to one identifier as that identifier ("property") exists in both boost and QObject classes!!! YOU MAY NEED TO RUN QMAKE ON THE PROJECT IF THE BUILD SYSTEM DOES NOT PICK UP THE ADDITION OF "Q_OBJECT" TO TMAP CLASS. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: Include missing #include, remove unused return value The absence of this was causing build errors on the Travis C.I. platform! Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: move TMap.h to mudlet_MOC_HDRS to fix CMake build issue As we have made TMap inherit from QOject - to have signal/slot functionality that class needs to be run through Qt's MOC - and to do that with the CMake project/build system it needs to be included in the files included in the projects *_MOC_HDRS {and removed from the *_HDRS} variable. Also spotted a trivial error in that specifying a const return value from method is ineffective and pointless - so removed it from: TMap::retrieveMapFileStats(QString,QString *,int *,int *,int *,int *) Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: clean up TMap initialisation/clearing actions Now restores the customEnvColors set up on initialisation but that was cleared when the map replaced with another one that is loaded {which subsequently replaces that element anyway} or imported {which merely writes over it, replacing any matching keys}. Initialises elements that when inspected on the entry to the constructor proper previously were not being set to a consistent value {booleans/ints/floats}. NOTE: This will now clear the map user data member when the map is cleared if the date is required to be saved when one map is loaded OR IMPORTED over an existing one then the data will need to be saved outside of the map - as is already need for areas and rooms user data! Also comment out or remove unused members/methods: * (void) TMap::getConnectedNodesGreaterThanX(int, int) * (void) TMap::getConnectedNodesSmallerThanX(int, int) * (void) TMap::getConnectedNodesGreaterThanY(int, int) * (void) TMap::getConnectedNodesSmallerThanY(int, int) * (void) TMap::astBreitenAnpassung(int, int) * (void) TMap::astHoehenAnpassung(int, int) * (void) TMap::exportMapToDatabase() * (void) TMap::importMapFromDatabase() * (QVector3D) TMap::span * (int) TMap::mViewArea * (QMap<QString, int>) TMap::pixNameTable * (QMap<int, QPixmap>) TMap::pixTable * (bool) TMap::isToDisplayAuditErrorsToConsole Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * ImplimentationFixes: activate a valid optimisation & remove redundant code Adding a true as a non-default 3rd argument to TRoomDB::addRoom(...) call in XMLimport::readRoom(...) enables a significant optimisation (skips a computationally expensive step when ADDING a room to new map) which dramatically reduces the time to parse an XML map file. It also pointed to the fact that the TRoomDB::entranceMap was already correctly being handled and didn't need to be regenerated in XMLimport::readRoom(...) so the code that was added in a previous commit was redundant and could be removed. A code error in TMap::slot_setDownloadProgress(...) that caused an issue that a reviewer found on test has been fixed - the total download filesize that was being sent by the Qt system signal that is connected to this slot was a -1 value (as IS DOCUMENTED) when the Qt system does NOT know the size of a QNetworkReply in advance of reaching the end of the download was incorrectly handled in a previous commit in this change set. Also found during testing that there is no need for an error message for the QNetworkReply::OperationCanceledError case in TMap::slot_replayFinished(...) as it is already handled in the TMap::slot_downloadCancel() slot. Changed the text put up onto the progress widget during the XML room parsing to be a room count - which is likely more useful and to only do it for every hundredth room - which reduces any delay "wasted" in writing to the display - combined, the effects seem satisfactory IMHO. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: provide error messages for TLuaInterpreter::loadMap(...) Errors for the XML map file importing process as initiated from the Lua command should be returned to that command rather than plastered onto the main profile console - this commit attempts to perform that effect. In testing found that there was no error handling for failure to find or open the nominated file so messages for that have been added as well. Due to the previous program logic the action of creating a mapper widget using the main toolbar button automatically loaded the "default" (the newest Mudlet Map file format file from the currently active profile's map sub-directory). Under some previous situations it looked as though a map might be loaded twice as mudlet::slot_mapper() was called both directly and via signal/slot action. These were resolved by turning that slot into a wrapper that now calls the body of code formerly within to a new method mudlet::createMapper( bool isToLoadDefaultMapFile = true ) with a the default value as an argument. This allows other usages of the body of code to be called directly with a suitable argument, which for the TConsole::loadMap() & TConsole::importMap() and the dlgProfilePreferences::downloadMap() cases is false as they are all do not want the "default" map! Also: * spotted a word "area" missing from an advisory text in TRoom::auditRooms(...). Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: fix minor bug, correct a spelling, undo a few capitalisations Under certain, unanticipated (error with no error message) conditions TLuaInterpreter::loadMap(...) would push both a nil and then a false value onto the stack for return {wrong} but only indicate one value {correct}. The textual matters were found during peer review. off-by: Stephen Lyons <slysven@virginmedia.com>
2016-10-13 09:18:48 +01:00
//void TMap::astHoehenAnpassung( int id, int id2 )
//{
//}
2010-12-28 23:31:03 +01:00
Enhance: fix map downloading code, add manual XML map importing (#326) * Enhance: fix map downloading code, add manual XML map importing A recent move by I.R.E. to using SSL for their public MUD map URLs broke the ability for Mudlet to download those XML format files. This commit addresses this issue (as mentioned in, but not the original problem referred to in https://bugs.launchpad.net/mudlet/+bug/1427364) the revision to the code does now use "https://www.<MUD URL>/maps/map.xml" as a default name for the I.R.E. MUDS - however the method that initiates the download which was moved to TMap class from the dlgMapper one (see below) is now: (bool) TMap::downloadMap( const QString * remoteUrl = Q_NULLPTR, const QString * localFileName = Q_NULLPTR ) which if not supplied with any arguments behaves as before. However the remoteUrl argument may be given as a full QString including the scheme (the bit of the URL at the beginning before the ':') to override that and a second argument may be used to provide a different name to use for the local file name which if is a RELATIVE pathFileName will be resolved in relation to the profile directory. At present no use is made of this additional functionality but it may be useful for use with other MUDs if they should choose to provide XML map files with other remote locations and scripts using a different local filename. As a long-standing thing that needed doing I have finally provided a means to import a map XML file that - for instance - has already been download. It had been noted that there was no way to read those I.R.E. map files even if they had been obtained from a web browser able to correctly handle https: URLs - now both the TLuaInterpreter::loadMap() and the dlgProfilePreference "loadMap" button {NOT the IRE only "map download" one} will both handle files ending in ".xml" (not case sensitive so it'll work MacOS platforms as well!} For the loadMap case it will be necessary to change the filetype filter on the File Selection dialog to select "xml" files. During testing it became clear to me that it was possible to try and read one or more XML files via several mechanisms simultaneously with "unhelpful" consequences. As well as hitting the dlgProfilePreferences IRE "map download" multiple times, the TLuaInterpreter::loadMap() does NOT block until the map has been loaded and as the import time {running of XMLinport::readPackage(...)} is of significant duration for a large map (a debug, without optimisation, build on my 1.8GHz Quad-core took over two minutes to process the current Achaea map file) it is very possible to get conditions where the same profile will try to run XMLinport::readPackage(...) asynchronously - given that a profile only supports ONE map at a time it was necessary to fit a QMutex to prevent the part of the XMLinport class relating to XML Map files being called from different places in the map related code. This means that if a map download is started further downloads and any local map imports will fail until that first download has completed or aborted. Similarly a local import will prevent a download being started. As a side effect this cures: https://bugs.launchpad.net/mudlet/+bug/852861 - "Map download button starts another download thread if one is already going" The previous XML import code was not adding the rooms that it parsed to the relevant TArea::rooms member - although this would be picked-up and fixed by TMap::audit() later on, this would be accompanied by an error message about every single room. The code now builds up this information while parsing the rooms' details and inserts it so that this does not cause report-able problems during the TMap::audit() execution - the data gathered also allows missing areas to be spotted so that if a room claimed to belong to an area that was not included in the preceding areas' data an unnamed area is created for it. As a consequence of the long time to actually parse an XML map file I have enhanced the progress dialog that was originally used to track the map file download. It is now retained until the file is completely imported and shows more information about the process - importantly it shows during the XMLimport::readRoom(...) the room id being processed - and THAT method is the time/cpu hog so seeing something happening during the time that Mudlet otherwise appears to hang is useful feedback even if it adds a few seconds to the overall duration (may be more than a minute). This dialog is now also used during the other routes that involve reading an XML file and there is now a bit of consistence with the on-screen messages. Whilst inspecting XMLimport class I found there was some uncertain initialisation which I have tidied up. In summary: Added: * (bool) TConsole::importMap(const QString & location) * (void) TRoomDB::setAreaRooms(const int areaId, const QSet<int> & roomIds) * image file mudlet_map_download.png used as icon for download/import progress dialog * (bool) TMap::importMap(QFile & file) * (bool) TMap::readXmlMapFile(QFile & file) * (void) TMap::slot_downloadError(QNetworkReply::NetworkError error) * (void) TMap::reportStringToProgressDialog(const QString text) * (void) TMap::reportProgressToProgressDialog(const int current, const int maximum) Revised: * (int)TLuaInterpreter::loadMap( lua_State * ) * Moved XML map download code from dlgMapper class to the TMap one: + (void) dlgMapper::downloadMap() ==> (bool) TMap::downloadMap(const QString * remoteUrl, const QString * localFileName) + (void) dlgMapper::setDownloadProgress(qint64, qint64) ==> (void) TMap::slot_setDownloadProgress(qint64,qint64) + (void) dlgMapper::cancel() ==> (void) TMap::slot_downloadCancel() + (void) dlgMapper::replyFinished(QNetworkReply *) ==> (void) TMap::slot_replyFinished(QNetworkReply *) * Enhanced download progress indication to also include parsing which can take even more time than download! * Provide means to import local XML map file * Prevent trying to import/download more than one map at a time Renamed: * (void) XMLimport::readAreaNames() ==> XMLimport::readArea() - for consistency with related functions Commented out unused: * (void) XMLimport::readUnknownRoomElement() Note the movement of the map file download code to the TMap class does require making the latter a class with the Q_OBJECT macro (which removes the need for Q_DECLARE_TR_FUNCTIONS as a side-effect!) - though as another side-effect the TMap header needed a boost name specifier added to one identifier as that identifier ("property") exists in both boost and QObject classes!!! YOU MAY NEED TO RUN QMAKE ON THE PROJECT IF THE BUILD SYSTEM DOES NOT PICK UP THE ADDITION OF "Q_OBJECT" TO TMAP CLASS. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: Include missing #include, remove unused return value The absence of this was causing build errors on the Travis C.I. platform! Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: move TMap.h to mudlet_MOC_HDRS to fix CMake build issue As we have made TMap inherit from QOject - to have signal/slot functionality that class needs to be run through Qt's MOC - and to do that with the CMake project/build system it needs to be included in the files included in the projects *_MOC_HDRS {and removed from the *_HDRS} variable. Also spotted a trivial error in that specifying a const return value from method is ineffective and pointless - so removed it from: TMap::retrieveMapFileStats(QString,QString *,int *,int *,int *,int *) Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: clean up TMap initialisation/clearing actions Now restores the customEnvColors set up on initialisation but that was cleared when the map replaced with another one that is loaded {which subsequently replaces that element anyway} or imported {which merely writes over it, replacing any matching keys}. Initialises elements that when inspected on the entry to the constructor proper previously were not being set to a consistent value {booleans/ints/floats}. NOTE: This will now clear the map user data member when the map is cleared if the date is required to be saved when one map is loaded OR IMPORTED over an existing one then the data will need to be saved outside of the map - as is already need for areas and rooms user data! Also comment out or remove unused members/methods: * (void) TMap::getConnectedNodesGreaterThanX(int, int) * (void) TMap::getConnectedNodesSmallerThanX(int, int) * (void) TMap::getConnectedNodesGreaterThanY(int, int) * (void) TMap::getConnectedNodesSmallerThanY(int, int) * (void) TMap::astBreitenAnpassung(int, int) * (void) TMap::astHoehenAnpassung(int, int) * (void) TMap::exportMapToDatabase() * (void) TMap::importMapFromDatabase() * (QVector3D) TMap::span * (int) TMap::mViewArea * (QMap<QString, int>) TMap::pixNameTable * (QMap<int, QPixmap>) TMap::pixTable * (bool) TMap::isToDisplayAuditErrorsToConsole Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * ImplimentationFixes: activate a valid optimisation & remove redundant code Adding a true as a non-default 3rd argument to TRoomDB::addRoom(...) call in XMLimport::readRoom(...) enables a significant optimisation (skips a computationally expensive step when ADDING a room to new map) which dramatically reduces the time to parse an XML map file. It also pointed to the fact that the TRoomDB::entranceMap was already correctly being handled and didn't need to be regenerated in XMLimport::readRoom(...) so the code that was added in a previous commit was redundant and could be removed. A code error in TMap::slot_setDownloadProgress(...) that caused an issue that a reviewer found on test has been fixed - the total download filesize that was being sent by the Qt system signal that is connected to this slot was a -1 value (as IS DOCUMENTED) when the Qt system does NOT know the size of a QNetworkReply in advance of reaching the end of the download was incorrectly handled in a previous commit in this change set. Also found during testing that there is no need for an error message for the QNetworkReply::OperationCanceledError case in TMap::slot_replayFinished(...) as it is already handled in the TMap::slot_downloadCancel() slot. Changed the text put up onto the progress widget during the XML room parsing to be a room count - which is likely more useful and to only do it for every hundredth room - which reduces any delay "wasted" in writing to the display - combined, the effects seem satisfactory IMHO. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: provide error messages for TLuaInterpreter::loadMap(...) Errors for the XML map file importing process as initiated from the Lua command should be returned to that command rather than plastered onto the main profile console - this commit attempts to perform that effect. In testing found that there was no error handling for failure to find or open the nominated file so messages for that have been added as well. Due to the previous program logic the action of creating a mapper widget using the main toolbar button automatically loaded the "default" (the newest Mudlet Map file format file from the currently active profile's map sub-directory). Under some previous situations it looked as though a map might be loaded twice as mudlet::slot_mapper() was called both directly and via signal/slot action. These were resolved by turning that slot into a wrapper that now calls the body of code formerly within to a new method mudlet::createMapper( bool isToLoadDefaultMapFile = true ) with a the default value as an argument. This allows other usages of the body of code to be called directly with a suitable argument, which for the TConsole::loadMap() & TConsole::importMap() and the dlgProfilePreferences::downloadMap() cases is false as they are all do not want the "default" map! Also: * spotted a word "area" missing from an advisory text in TRoom::auditRooms(...). Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: fix minor bug, correct a spelling, undo a few capitalisations Under certain, unanticipated (error with no error message) conditions TLuaInterpreter::loadMap(...) would push both a nil and then a false value onto the stack for return {wrong} but only indicate one value {correct}. The textual matters were found during peer review. off-by: Stephen Lyons <slysven@virginmedia.com>
2016-10-13 09:18:48 +01:00
//void TMap::getConnectedNodesGreaterThanX( int id, int min )
//{
//}
2010-12-28 23:31:03 +01:00
Enhance: fix map downloading code, add manual XML map importing (#326) * Enhance: fix map downloading code, add manual XML map importing A recent move by I.R.E. to using SSL for their public MUD map URLs broke the ability for Mudlet to download those XML format files. This commit addresses this issue (as mentioned in, but not the original problem referred to in https://bugs.launchpad.net/mudlet/+bug/1427364) the revision to the code does now use "https://www.<MUD URL>/maps/map.xml" as a default name for the I.R.E. MUDS - however the method that initiates the download which was moved to TMap class from the dlgMapper one (see below) is now: (bool) TMap::downloadMap( const QString * remoteUrl = Q_NULLPTR, const QString * localFileName = Q_NULLPTR ) which if not supplied with any arguments behaves as before. However the remoteUrl argument may be given as a full QString including the scheme (the bit of the URL at the beginning before the ':') to override that and a second argument may be used to provide a different name to use for the local file name which if is a RELATIVE pathFileName will be resolved in relation to the profile directory. At present no use is made of this additional functionality but it may be useful for use with other MUDs if they should choose to provide XML map files with other remote locations and scripts using a different local filename. As a long-standing thing that needed doing I have finally provided a means to import a map XML file that - for instance - has already been download. It had been noted that there was no way to read those I.R.E. map files even if they had been obtained from a web browser able to correctly handle https: URLs - now both the TLuaInterpreter::loadMap() and the dlgProfilePreference "loadMap" button {NOT the IRE only "map download" one} will both handle files ending in ".xml" (not case sensitive so it'll work MacOS platforms as well!} For the loadMap case it will be necessary to change the filetype filter on the File Selection dialog to select "xml" files. During testing it became clear to me that it was possible to try and read one or more XML files via several mechanisms simultaneously with "unhelpful" consequences. As well as hitting the dlgProfilePreferences IRE "map download" multiple times, the TLuaInterpreter::loadMap() does NOT block until the map has been loaded and as the import time {running of XMLinport::readPackage(...)} is of significant duration for a large map (a debug, without optimisation, build on my 1.8GHz Quad-core took over two minutes to process the current Achaea map file) it is very possible to get conditions where the same profile will try to run XMLinport::readPackage(...) asynchronously - given that a profile only supports ONE map at a time it was necessary to fit a QMutex to prevent the part of the XMLinport class relating to XML Map files being called from different places in the map related code. This means that if a map download is started further downloads and any local map imports will fail until that first download has completed or aborted. Similarly a local import will prevent a download being started. As a side effect this cures: https://bugs.launchpad.net/mudlet/+bug/852861 - "Map download button starts another download thread if one is already going" The previous XML import code was not adding the rooms that it parsed to the relevant TArea::rooms member - although this would be picked-up and fixed by TMap::audit() later on, this would be accompanied by an error message about every single room. The code now builds up this information while parsing the rooms' details and inserts it so that this does not cause report-able problems during the TMap::audit() execution - the data gathered also allows missing areas to be spotted so that if a room claimed to belong to an area that was not included in the preceding areas' data an unnamed area is created for it. As a consequence of the long time to actually parse an XML map file I have enhanced the progress dialog that was originally used to track the map file download. It is now retained until the file is completely imported and shows more information about the process - importantly it shows during the XMLimport::readRoom(...) the room id being processed - and THAT method is the time/cpu hog so seeing something happening during the time that Mudlet otherwise appears to hang is useful feedback even if it adds a few seconds to the overall duration (may be more than a minute). This dialog is now also used during the other routes that involve reading an XML file and there is now a bit of consistence with the on-screen messages. Whilst inspecting XMLimport class I found there was some uncertain initialisation which I have tidied up. In summary: Added: * (bool) TConsole::importMap(const QString & location) * (void) TRoomDB::setAreaRooms(const int areaId, const QSet<int> & roomIds) * image file mudlet_map_download.png used as icon for download/import progress dialog * (bool) TMap::importMap(QFile & file) * (bool) TMap::readXmlMapFile(QFile & file) * (void) TMap::slot_downloadError(QNetworkReply::NetworkError error) * (void) TMap::reportStringToProgressDialog(const QString text) * (void) TMap::reportProgressToProgressDialog(const int current, const int maximum) Revised: * (int)TLuaInterpreter::loadMap( lua_State * ) * Moved XML map download code from dlgMapper class to the TMap one: + (void) dlgMapper::downloadMap() ==> (bool) TMap::downloadMap(const QString * remoteUrl, const QString * localFileName) + (void) dlgMapper::setDownloadProgress(qint64, qint64) ==> (void) TMap::slot_setDownloadProgress(qint64,qint64) + (void) dlgMapper::cancel() ==> (void) TMap::slot_downloadCancel() + (void) dlgMapper::replyFinished(QNetworkReply *) ==> (void) TMap::slot_replyFinished(QNetworkReply *) * Enhanced download progress indication to also include parsing which can take even more time than download! * Provide means to import local XML map file * Prevent trying to import/download more than one map at a time Renamed: * (void) XMLimport::readAreaNames() ==> XMLimport::readArea() - for consistency with related functions Commented out unused: * (void) XMLimport::readUnknownRoomElement() Note the movement of the map file download code to the TMap class does require making the latter a class with the Q_OBJECT macro (which removes the need for Q_DECLARE_TR_FUNCTIONS as a side-effect!) - though as another side-effect the TMap header needed a boost name specifier added to one identifier as that identifier ("property") exists in both boost and QObject classes!!! YOU MAY NEED TO RUN QMAKE ON THE PROJECT IF THE BUILD SYSTEM DOES NOT PICK UP THE ADDITION OF "Q_OBJECT" TO TMAP CLASS. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: Include missing #include, remove unused return value The absence of this was causing build errors on the Travis C.I. platform! Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: move TMap.h to mudlet_MOC_HDRS to fix CMake build issue As we have made TMap inherit from QOject - to have signal/slot functionality that class needs to be run through Qt's MOC - and to do that with the CMake project/build system it needs to be included in the files included in the projects *_MOC_HDRS {and removed from the *_HDRS} variable. Also spotted a trivial error in that specifying a const return value from method is ineffective and pointless - so removed it from: TMap::retrieveMapFileStats(QString,QString *,int *,int *,int *,int *) Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: clean up TMap initialisation/clearing actions Now restores the customEnvColors set up on initialisation but that was cleared when the map replaced with another one that is loaded {which subsequently replaces that element anyway} or imported {which merely writes over it, replacing any matching keys}. Initialises elements that when inspected on the entry to the constructor proper previously were not being set to a consistent value {booleans/ints/floats}. NOTE: This will now clear the map user data member when the map is cleared if the date is required to be saved when one map is loaded OR IMPORTED over an existing one then the data will need to be saved outside of the map - as is already need for areas and rooms user data! Also comment out or remove unused members/methods: * (void) TMap::getConnectedNodesGreaterThanX(int, int) * (void) TMap::getConnectedNodesSmallerThanX(int, int) * (void) TMap::getConnectedNodesGreaterThanY(int, int) * (void) TMap::getConnectedNodesSmallerThanY(int, int) * (void) TMap::astBreitenAnpassung(int, int) * (void) TMap::astHoehenAnpassung(int, int) * (void) TMap::exportMapToDatabase() * (void) TMap::importMapFromDatabase() * (QVector3D) TMap::span * (int) TMap::mViewArea * (QMap<QString, int>) TMap::pixNameTable * (QMap<int, QPixmap>) TMap::pixTable * (bool) TMap::isToDisplayAuditErrorsToConsole Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * ImplimentationFixes: activate a valid optimisation & remove redundant code Adding a true as a non-default 3rd argument to TRoomDB::addRoom(...) call in XMLimport::readRoom(...) enables a significant optimisation (skips a computationally expensive step when ADDING a room to new map) which dramatically reduces the time to parse an XML map file. It also pointed to the fact that the TRoomDB::entranceMap was already correctly being handled and didn't need to be regenerated in XMLimport::readRoom(...) so the code that was added in a previous commit was redundant and could be removed. A code error in TMap::slot_setDownloadProgress(...) that caused an issue that a reviewer found on test has been fixed - the total download filesize that was being sent by the Qt system signal that is connected to this slot was a -1 value (as IS DOCUMENTED) when the Qt system does NOT know the size of a QNetworkReply in advance of reaching the end of the download was incorrectly handled in a previous commit in this change set. Also found during testing that there is no need for an error message for the QNetworkReply::OperationCanceledError case in TMap::slot_replayFinished(...) as it is already handled in the TMap::slot_downloadCancel() slot. Changed the text put up onto the progress widget during the XML room parsing to be a room count - which is likely more useful and to only do it for every hundredth room - which reduces any delay "wasted" in writing to the display - combined, the effects seem satisfactory IMHO. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: provide error messages for TLuaInterpreter::loadMap(...) Errors for the XML map file importing process as initiated from the Lua command should be returned to that command rather than plastered onto the main profile console - this commit attempts to perform that effect. In testing found that there was no error handling for failure to find or open the nominated file so messages for that have been added as well. Due to the previous program logic the action of creating a mapper widget using the main toolbar button automatically loaded the "default" (the newest Mudlet Map file format file from the currently active profile's map sub-directory). Under some previous situations it looked as though a map might be loaded twice as mudlet::slot_mapper() was called both directly and via signal/slot action. These were resolved by turning that slot into a wrapper that now calls the body of code formerly within to a new method mudlet::createMapper( bool isToLoadDefaultMapFile = true ) with a the default value as an argument. This allows other usages of the body of code to be called directly with a suitable argument, which for the TConsole::loadMap() & TConsole::importMap() and the dlgProfilePreferences::downloadMap() cases is false as they are all do not want the "default" map! Also: * spotted a word "area" missing from an advisory text in TRoom::auditRooms(...). Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: fix minor bug, correct a spelling, undo a few capitalisations Under certain, unanticipated (error with no error message) conditions TLuaInterpreter::loadMap(...) would push both a nil and then a false value onto the stack for return {wrong} but only indicate one value {correct}. The textual matters were found during peer review. off-by: Stephen Lyons <slysven@virginmedia.com>
2016-10-13 09:18:48 +01:00
//void TMap::getConnectedNodesSmallerThanX( int id, int min )
//{
//}
2010-12-28 23:31:03 +01:00
Enhance: fix map downloading code, add manual XML map importing (#326) * Enhance: fix map downloading code, add manual XML map importing A recent move by I.R.E. to using SSL for their public MUD map URLs broke the ability for Mudlet to download those XML format files. This commit addresses this issue (as mentioned in, but not the original problem referred to in https://bugs.launchpad.net/mudlet/+bug/1427364) the revision to the code does now use "https://www.<MUD URL>/maps/map.xml" as a default name for the I.R.E. MUDS - however the method that initiates the download which was moved to TMap class from the dlgMapper one (see below) is now: (bool) TMap::downloadMap( const QString * remoteUrl = Q_NULLPTR, const QString * localFileName = Q_NULLPTR ) which if not supplied with any arguments behaves as before. However the remoteUrl argument may be given as a full QString including the scheme (the bit of the URL at the beginning before the ':') to override that and a second argument may be used to provide a different name to use for the local file name which if is a RELATIVE pathFileName will be resolved in relation to the profile directory. At present no use is made of this additional functionality but it may be useful for use with other MUDs if they should choose to provide XML map files with other remote locations and scripts using a different local filename. As a long-standing thing that needed doing I have finally provided a means to import a map XML file that - for instance - has already been download. It had been noted that there was no way to read those I.R.E. map files even if they had been obtained from a web browser able to correctly handle https: URLs - now both the TLuaInterpreter::loadMap() and the dlgProfilePreference "loadMap" button {NOT the IRE only "map download" one} will both handle files ending in ".xml" (not case sensitive so it'll work MacOS platforms as well!} For the loadMap case it will be necessary to change the filetype filter on the File Selection dialog to select "xml" files. During testing it became clear to me that it was possible to try and read one or more XML files via several mechanisms simultaneously with "unhelpful" consequences. As well as hitting the dlgProfilePreferences IRE "map download" multiple times, the TLuaInterpreter::loadMap() does NOT block until the map has been loaded and as the import time {running of XMLinport::readPackage(...)} is of significant duration for a large map (a debug, without optimisation, build on my 1.8GHz Quad-core took over two minutes to process the current Achaea map file) it is very possible to get conditions where the same profile will try to run XMLinport::readPackage(...) asynchronously - given that a profile only supports ONE map at a time it was necessary to fit a QMutex to prevent the part of the XMLinport class relating to XML Map files being called from different places in the map related code. This means that if a map download is started further downloads and any local map imports will fail until that first download has completed or aborted. Similarly a local import will prevent a download being started. As a side effect this cures: https://bugs.launchpad.net/mudlet/+bug/852861 - "Map download button starts another download thread if one is already going" The previous XML import code was not adding the rooms that it parsed to the relevant TArea::rooms member - although this would be picked-up and fixed by TMap::audit() later on, this would be accompanied by an error message about every single room. The code now builds up this information while parsing the rooms' details and inserts it so that this does not cause report-able problems during the TMap::audit() execution - the data gathered also allows missing areas to be spotted so that if a room claimed to belong to an area that was not included in the preceding areas' data an unnamed area is created for it. As a consequence of the long time to actually parse an XML map file I have enhanced the progress dialog that was originally used to track the map file download. It is now retained until the file is completely imported and shows more information about the process - importantly it shows during the XMLimport::readRoom(...) the room id being processed - and THAT method is the time/cpu hog so seeing something happening during the time that Mudlet otherwise appears to hang is useful feedback even if it adds a few seconds to the overall duration (may be more than a minute). This dialog is now also used during the other routes that involve reading an XML file and there is now a bit of consistence with the on-screen messages. Whilst inspecting XMLimport class I found there was some uncertain initialisation which I have tidied up. In summary: Added: * (bool) TConsole::importMap(const QString & location) * (void) TRoomDB::setAreaRooms(const int areaId, const QSet<int> & roomIds) * image file mudlet_map_download.png used as icon for download/import progress dialog * (bool) TMap::importMap(QFile & file) * (bool) TMap::readXmlMapFile(QFile & file) * (void) TMap::slot_downloadError(QNetworkReply::NetworkError error) * (void) TMap::reportStringToProgressDialog(const QString text) * (void) TMap::reportProgressToProgressDialog(const int current, const int maximum) Revised: * (int)TLuaInterpreter::loadMap( lua_State * ) * Moved XML map download code from dlgMapper class to the TMap one: + (void) dlgMapper::downloadMap() ==> (bool) TMap::downloadMap(const QString * remoteUrl, const QString * localFileName) + (void) dlgMapper::setDownloadProgress(qint64, qint64) ==> (void) TMap::slot_setDownloadProgress(qint64,qint64) + (void) dlgMapper::cancel() ==> (void) TMap::slot_downloadCancel() + (void) dlgMapper::replyFinished(QNetworkReply *) ==> (void) TMap::slot_replyFinished(QNetworkReply *) * Enhanced download progress indication to also include parsing which can take even more time than download! * Provide means to import local XML map file * Prevent trying to import/download more than one map at a time Renamed: * (void) XMLimport::readAreaNames() ==> XMLimport::readArea() - for consistency with related functions Commented out unused: * (void) XMLimport::readUnknownRoomElement() Note the movement of the map file download code to the TMap class does require making the latter a class with the Q_OBJECT macro (which removes the need for Q_DECLARE_TR_FUNCTIONS as a side-effect!) - though as another side-effect the TMap header needed a boost name specifier added to one identifier as that identifier ("property") exists in both boost and QObject classes!!! YOU MAY NEED TO RUN QMAKE ON THE PROJECT IF THE BUILD SYSTEM DOES NOT PICK UP THE ADDITION OF "Q_OBJECT" TO TMAP CLASS. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: Include missing #include, remove unused return value The absence of this was causing build errors on the Travis C.I. platform! Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: move TMap.h to mudlet_MOC_HDRS to fix CMake build issue As we have made TMap inherit from QOject - to have signal/slot functionality that class needs to be run through Qt's MOC - and to do that with the CMake project/build system it needs to be included in the files included in the projects *_MOC_HDRS {and removed from the *_HDRS} variable. Also spotted a trivial error in that specifying a const return value from method is ineffective and pointless - so removed it from: TMap::retrieveMapFileStats(QString,QString *,int *,int *,int *,int *) Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: clean up TMap initialisation/clearing actions Now restores the customEnvColors set up on initialisation but that was cleared when the map replaced with another one that is loaded {which subsequently replaces that element anyway} or imported {which merely writes over it, replacing any matching keys}. Initialises elements that when inspected on the entry to the constructor proper previously were not being set to a consistent value {booleans/ints/floats}. NOTE: This will now clear the map user data member when the map is cleared if the date is required to be saved when one map is loaded OR IMPORTED over an existing one then the data will need to be saved outside of the map - as is already need for areas and rooms user data! Also comment out or remove unused members/methods: * (void) TMap::getConnectedNodesGreaterThanX(int, int) * (void) TMap::getConnectedNodesSmallerThanX(int, int) * (void) TMap::getConnectedNodesGreaterThanY(int, int) * (void) TMap::getConnectedNodesSmallerThanY(int, int) * (void) TMap::astBreitenAnpassung(int, int) * (void) TMap::astHoehenAnpassung(int, int) * (void) TMap::exportMapToDatabase() * (void) TMap::importMapFromDatabase() * (QVector3D) TMap::span * (int) TMap::mViewArea * (QMap<QString, int>) TMap::pixNameTable * (QMap<int, QPixmap>) TMap::pixTable * (bool) TMap::isToDisplayAuditErrorsToConsole Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * ImplimentationFixes: activate a valid optimisation & remove redundant code Adding a true as a non-default 3rd argument to TRoomDB::addRoom(...) call in XMLimport::readRoom(...) enables a significant optimisation (skips a computationally expensive step when ADDING a room to new map) which dramatically reduces the time to parse an XML map file. It also pointed to the fact that the TRoomDB::entranceMap was already correctly being handled and didn't need to be regenerated in XMLimport::readRoom(...) so the code that was added in a previous commit was redundant and could be removed. A code error in TMap::slot_setDownloadProgress(...) that caused an issue that a reviewer found on test has been fixed - the total download filesize that was being sent by the Qt system signal that is connected to this slot was a -1 value (as IS DOCUMENTED) when the Qt system does NOT know the size of a QNetworkReply in advance of reaching the end of the download was incorrectly handled in a previous commit in this change set. Also found during testing that there is no need for an error message for the QNetworkReply::OperationCanceledError case in TMap::slot_replayFinished(...) as it is already handled in the TMap::slot_downloadCancel() slot. Changed the text put up onto the progress widget during the XML room parsing to be a room count - which is likely more useful and to only do it for every hundredth room - which reduces any delay "wasted" in writing to the display - combined, the effects seem satisfactory IMHO. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: provide error messages for TLuaInterpreter::loadMap(...) Errors for the XML map file importing process as initiated from the Lua command should be returned to that command rather than plastered onto the main profile console - this commit attempts to perform that effect. In testing found that there was no error handling for failure to find or open the nominated file so messages for that have been added as well. Due to the previous program logic the action of creating a mapper widget using the main toolbar button automatically loaded the "default" (the newest Mudlet Map file format file from the currently active profile's map sub-directory). Under some previous situations it looked as though a map might be loaded twice as mudlet::slot_mapper() was called both directly and via signal/slot action. These were resolved by turning that slot into a wrapper that now calls the body of code formerly within to a new method mudlet::createMapper( bool isToLoadDefaultMapFile = true ) with a the default value as an argument. This allows other usages of the body of code to be called directly with a suitable argument, which for the TConsole::loadMap() & TConsole::importMap() and the dlgProfilePreferences::downloadMap() cases is false as they are all do not want the "default" map! Also: * spotted a word "area" missing from an advisory text in TRoom::auditRooms(...). Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: fix minor bug, correct a spelling, undo a few capitalisations Under certain, unanticipated (error with no error message) conditions TLuaInterpreter::loadMap(...) would push both a nil and then a false value onto the stack for return {wrong} but only indicate one value {correct}. The textual matters were found during peer review. off-by: Stephen Lyons <slysven@virginmedia.com>
2016-10-13 09:18:48 +01:00
//void TMap::getConnectedNodesGreaterThanY( int id, int min )
//{
//}
2010-12-28 23:31:03 +01:00
Enhance: fix map downloading code, add manual XML map importing (#326) * Enhance: fix map downloading code, add manual XML map importing A recent move by I.R.E. to using SSL for their public MUD map URLs broke the ability for Mudlet to download those XML format files. This commit addresses this issue (as mentioned in, but not the original problem referred to in https://bugs.launchpad.net/mudlet/+bug/1427364) the revision to the code does now use "https://www.<MUD URL>/maps/map.xml" as a default name for the I.R.E. MUDS - however the method that initiates the download which was moved to TMap class from the dlgMapper one (see below) is now: (bool) TMap::downloadMap( const QString * remoteUrl = Q_NULLPTR, const QString * localFileName = Q_NULLPTR ) which if not supplied with any arguments behaves as before. However the remoteUrl argument may be given as a full QString including the scheme (the bit of the URL at the beginning before the ':') to override that and a second argument may be used to provide a different name to use for the local file name which if is a RELATIVE pathFileName will be resolved in relation to the profile directory. At present no use is made of this additional functionality but it may be useful for use with other MUDs if they should choose to provide XML map files with other remote locations and scripts using a different local filename. As a long-standing thing that needed doing I have finally provided a means to import a map XML file that - for instance - has already been download. It had been noted that there was no way to read those I.R.E. map files even if they had been obtained from a web browser able to correctly handle https: URLs - now both the TLuaInterpreter::loadMap() and the dlgProfilePreference "loadMap" button {NOT the IRE only "map download" one} will both handle files ending in ".xml" (not case sensitive so it'll work MacOS platforms as well!} For the loadMap case it will be necessary to change the filetype filter on the File Selection dialog to select "xml" files. During testing it became clear to me that it was possible to try and read one or more XML files via several mechanisms simultaneously with "unhelpful" consequences. As well as hitting the dlgProfilePreferences IRE "map download" multiple times, the TLuaInterpreter::loadMap() does NOT block until the map has been loaded and as the import time {running of XMLinport::readPackage(...)} is of significant duration for a large map (a debug, without optimisation, build on my 1.8GHz Quad-core took over two minutes to process the current Achaea map file) it is very possible to get conditions where the same profile will try to run XMLinport::readPackage(...) asynchronously - given that a profile only supports ONE map at a time it was necessary to fit a QMutex to prevent the part of the XMLinport class relating to XML Map files being called from different places in the map related code. This means that if a map download is started further downloads and any local map imports will fail until that first download has completed or aborted. Similarly a local import will prevent a download being started. As a side effect this cures: https://bugs.launchpad.net/mudlet/+bug/852861 - "Map download button starts another download thread if one is already going" The previous XML import code was not adding the rooms that it parsed to the relevant TArea::rooms member - although this would be picked-up and fixed by TMap::audit() later on, this would be accompanied by an error message about every single room. The code now builds up this information while parsing the rooms' details and inserts it so that this does not cause report-able problems during the TMap::audit() execution - the data gathered also allows missing areas to be spotted so that if a room claimed to belong to an area that was not included in the preceding areas' data an unnamed area is created for it. As a consequence of the long time to actually parse an XML map file I have enhanced the progress dialog that was originally used to track the map file download. It is now retained until the file is completely imported and shows more information about the process - importantly it shows during the XMLimport::readRoom(...) the room id being processed - and THAT method is the time/cpu hog so seeing something happening during the time that Mudlet otherwise appears to hang is useful feedback even if it adds a few seconds to the overall duration (may be more than a minute). This dialog is now also used during the other routes that involve reading an XML file and there is now a bit of consistence with the on-screen messages. Whilst inspecting XMLimport class I found there was some uncertain initialisation which I have tidied up. In summary: Added: * (bool) TConsole::importMap(const QString & location) * (void) TRoomDB::setAreaRooms(const int areaId, const QSet<int> & roomIds) * image file mudlet_map_download.png used as icon for download/import progress dialog * (bool) TMap::importMap(QFile & file) * (bool) TMap::readXmlMapFile(QFile & file) * (void) TMap::slot_downloadError(QNetworkReply::NetworkError error) * (void) TMap::reportStringToProgressDialog(const QString text) * (void) TMap::reportProgressToProgressDialog(const int current, const int maximum) Revised: * (int)TLuaInterpreter::loadMap( lua_State * ) * Moved XML map download code from dlgMapper class to the TMap one: + (void) dlgMapper::downloadMap() ==> (bool) TMap::downloadMap(const QString * remoteUrl, const QString * localFileName) + (void) dlgMapper::setDownloadProgress(qint64, qint64) ==> (void) TMap::slot_setDownloadProgress(qint64,qint64) + (void) dlgMapper::cancel() ==> (void) TMap::slot_downloadCancel() + (void) dlgMapper::replyFinished(QNetworkReply *) ==> (void) TMap::slot_replyFinished(QNetworkReply *) * Enhanced download progress indication to also include parsing which can take even more time than download! * Provide means to import local XML map file * Prevent trying to import/download more than one map at a time Renamed: * (void) XMLimport::readAreaNames() ==> XMLimport::readArea() - for consistency with related functions Commented out unused: * (void) XMLimport::readUnknownRoomElement() Note the movement of the map file download code to the TMap class does require making the latter a class with the Q_OBJECT macro (which removes the need for Q_DECLARE_TR_FUNCTIONS as a side-effect!) - though as another side-effect the TMap header needed a boost name specifier added to one identifier as that identifier ("property") exists in both boost and QObject classes!!! YOU MAY NEED TO RUN QMAKE ON THE PROJECT IF THE BUILD SYSTEM DOES NOT PICK UP THE ADDITION OF "Q_OBJECT" TO TMAP CLASS. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: Include missing #include, remove unused return value The absence of this was causing build errors on the Travis C.I. platform! Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: move TMap.h to mudlet_MOC_HDRS to fix CMake build issue As we have made TMap inherit from QOject - to have signal/slot functionality that class needs to be run through Qt's MOC - and to do that with the CMake project/build system it needs to be included in the files included in the projects *_MOC_HDRS {and removed from the *_HDRS} variable. Also spotted a trivial error in that specifying a const return value from method is ineffective and pointless - so removed it from: TMap::retrieveMapFileStats(QString,QString *,int *,int *,int *,int *) Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: clean up TMap initialisation/clearing actions Now restores the customEnvColors set up on initialisation but that was cleared when the map replaced with another one that is loaded {which subsequently replaces that element anyway} or imported {which merely writes over it, replacing any matching keys}. Initialises elements that when inspected on the entry to the constructor proper previously were not being set to a consistent value {booleans/ints/floats}. NOTE: This will now clear the map user data member when the map is cleared if the date is required to be saved when one map is loaded OR IMPORTED over an existing one then the data will need to be saved outside of the map - as is already need for areas and rooms user data! Also comment out or remove unused members/methods: * (void) TMap::getConnectedNodesGreaterThanX(int, int) * (void) TMap::getConnectedNodesSmallerThanX(int, int) * (void) TMap::getConnectedNodesGreaterThanY(int, int) * (void) TMap::getConnectedNodesSmallerThanY(int, int) * (void) TMap::astBreitenAnpassung(int, int) * (void) TMap::astHoehenAnpassung(int, int) * (void) TMap::exportMapToDatabase() * (void) TMap::importMapFromDatabase() * (QVector3D) TMap::span * (int) TMap::mViewArea * (QMap<QString, int>) TMap::pixNameTable * (QMap<int, QPixmap>) TMap::pixTable * (bool) TMap::isToDisplayAuditErrorsToConsole Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * ImplimentationFixes: activate a valid optimisation & remove redundant code Adding a true as a non-default 3rd argument to TRoomDB::addRoom(...) call in XMLimport::readRoom(...) enables a significant optimisation (skips a computationally expensive step when ADDING a room to new map) which dramatically reduces the time to parse an XML map file. It also pointed to the fact that the TRoomDB::entranceMap was already correctly being handled and didn't need to be regenerated in XMLimport::readRoom(...) so the code that was added in a previous commit was redundant and could be removed. A code error in TMap::slot_setDownloadProgress(...) that caused an issue that a reviewer found on test has been fixed - the total download filesize that was being sent by the Qt system signal that is connected to this slot was a -1 value (as IS DOCUMENTED) when the Qt system does NOT know the size of a QNetworkReply in advance of reaching the end of the download was incorrectly handled in a previous commit in this change set. Also found during testing that there is no need for an error message for the QNetworkReply::OperationCanceledError case in TMap::slot_replayFinished(...) as it is already handled in the TMap::slot_downloadCancel() slot. Changed the text put up onto the progress widget during the XML room parsing to be a room count - which is likely more useful and to only do it for every hundredth room - which reduces any delay "wasted" in writing to the display - combined, the effects seem satisfactory IMHO. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: provide error messages for TLuaInterpreter::loadMap(...) Errors for the XML map file importing process as initiated from the Lua command should be returned to that command rather than plastered onto the main profile console - this commit attempts to perform that effect. In testing found that there was no error handling for failure to find or open the nominated file so messages for that have been added as well. Due to the previous program logic the action of creating a mapper widget using the main toolbar button automatically loaded the "default" (the newest Mudlet Map file format file from the currently active profile's map sub-directory). Under some previous situations it looked as though a map might be loaded twice as mudlet::slot_mapper() was called both directly and via signal/slot action. These were resolved by turning that slot into a wrapper that now calls the body of code formerly within to a new method mudlet::createMapper( bool isToLoadDefaultMapFile = true ) with a the default value as an argument. This allows other usages of the body of code to be called directly with a suitable argument, which for the TConsole::loadMap() & TConsole::importMap() and the dlgProfilePreferences::downloadMap() cases is false as they are all do not want the "default" map! Also: * spotted a word "area" missing from an advisory text in TRoom::auditRooms(...). Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: fix minor bug, correct a spelling, undo a few capitalisations Under certain, unanticipated (error with no error message) conditions TLuaInterpreter::loadMap(...) would push both a nil and then a false value onto the stack for return {wrong} but only indicate one value {correct}. The textual matters were found during peer review. off-by: Stephen Lyons <slysven@virginmedia.com>
2016-10-13 09:18:48 +01:00
//void TMap::getConnectedNodesSmallerThanY( int id, int min )
//{
//}
2010-12-28 23:31:03 +01:00
bool TMap::gotoRoom(int r)
2010-08-25 00:41:43 +02:00
{
mTargetID = r;
return findPath(mRoomIdHash.value(mpHost->getName()), r);
2010-08-25 00:41:43 +02:00
}
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
// As can be seen this only sets the target and start point for a path find
// the speedwalk is instigated by the Host class caller...
bool TMap::gotoRoom(int r1, int r2)
2010-08-25 00:41:43 +02:00
{
return findPath(r1, r2);
2010-08-25 00:41:43 +02:00
}
void TMap::initGraph()
2010-08-25 00:41:43 +02:00
{
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
QElapsedTimer _time;
_time.start();
2011-07-04 11:50:19 +02:00
locations.clear();
roomidToIndex.clear();
2011-07-04 11:50:19 +02:00
g.clear();
g = mygraph_t();
unsigned int roomCount = 0;
unsigned int edgeCount = 0;
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
QSet<unsigned int> unUsableRoomSet;
// Keep track of the unusuable rather than the useable ones because that is
// hopefully a MUCH smaller set in normal situations!
QHashIterator<int, TRoom*> itRoom = mpRoomDB->getRoomMap();
while (itRoom.hasNext()) {
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
itRoom.next();
TRoom* pR = itRoom.value();
if (itRoom.key() < 1 || !pR || pR->isLocked) {
unUsableRoomSet.insert(itRoom.key());
continue;
}
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
location l;
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
l.pR = pR;
l.id = itRoom.key();
// locations is std::vector<location> and (locations.at( k )).id will give room ID value
locations.push_back(l);
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
// Map's usable TRooms (key) to index of entry in locations (for route finding), will lose invalid and unusable (through locking) rooms
roomidToIndex.insert(itRoom.key(), roomCount++);
}
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
// Now identify the routes between rooms, and pick out the best edges of parallel ones
foreach (location l, locations) {
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
unsigned int source = l.id;
TRoom* pSourceR = l.pR;
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
QHash<unsigned int, route> bestRoutes;
// key is target (destination room),
// value is data we will need to store later,
QMap<QString, int> exitWeights = pSourceR->getExitWeights();
int target = pSourceR->getNorth();
TRoom* pTargetR;
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
quint8 direction = DIR_NORTH;
if (target > 0 && source != target && !unUsableRoomSet.contains(target) && !pSourceR->hasExitLock(direction)) {
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
// In above tests the second test is to eliminate self-edges (they
// are of no use). The third test is to eliminate targets that we
// have already found to be unreachable because they are invalid or
// locked.
pTargetR = mpRoomDB->getRoom(target);
if (pTargetR && !pTargetR->isLocked) { // OK got something that is valid
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
route r;
r.cost = exitWeights.value(QStringLiteral("n"), pTargetR->getWeight());
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
r.direction = direction;
bestRoutes.insert(target, r);
2011-06-26 15:23:37 +02:00
}
}
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
target = pSourceR->getEast();
direction = DIR_EAST;
if (target > 0 && source != target && !unUsableRoomSet.contains(target) && !pSourceR->hasExitLock(direction)) {
pTargetR = mpRoomDB->getRoom(target);
if (pTargetR && !pTargetR->isLocked) {
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
route r;
r.cost = exitWeights.value(QStringLiteral("e"), pTargetR->getWeight());
if (!bestRoutes.contains(target) || bestRoutes.value(target).cost > r.cost) { // Ah, this is a better route
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
r.direction = direction;
bestRoutes.insert(target, r); // If the second part of conditional is the truth this will replace previous best route to this target
}
2011-06-26 15:23:37 +02:00
}
}
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
target = pSourceR->getSouth();
direction = DIR_SOUTH;
if (target > 0 && source != target && !unUsableRoomSet.contains(target) && !pSourceR->hasExitLock(direction)) {
pTargetR = mpRoomDB->getRoom(target);
if (pTargetR && !pTargetR->isLocked) {
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
route r;
r.cost = exitWeights.value(QStringLiteral("s"), pTargetR->getWeight());
if (!bestRoutes.contains(target) || bestRoutes.value(target).cost > r.cost) {
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
r.direction = direction;
bestRoutes.insert(target, r);
}
2011-07-04 11:50:19 +02:00
}
}
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
target = pSourceR->getWest();
direction = DIR_WEST;
if (target > 0 && source != target && !unUsableRoomSet.contains(target) && !pSourceR->hasExitLock(direction)) {
pTargetR = mpRoomDB->getRoom(target);
if (pTargetR && !pTargetR->isLocked) {
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
route r;
r.cost = exitWeights.value(QStringLiteral("w"), pTargetR->getWeight());
if (!bestRoutes.contains(target) || bestRoutes.value(target).cost > r.cost) {
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
r.direction = direction;
bestRoutes.insert(target, r);
}
2011-06-26 15:23:37 +02:00
}
}
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
target = pSourceR->getUp();
direction = DIR_UP;
if (target > 0 && source != target && !unUsableRoomSet.contains(target) && !pSourceR->hasExitLock(direction)) {
pTargetR = mpRoomDB->getRoom(target);
if (pTargetR && !pTargetR->isLocked) {
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
route r;
r.cost = exitWeights.value(QStringLiteral("up"), pTargetR->getWeight());
if (!bestRoutes.contains(target) || bestRoutes.value(target).cost > r.cost) {
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
r.direction = direction;
bestRoutes.insert(target, r);
}
2011-06-26 15:23:37 +02:00
}
}
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
target = pSourceR->getDown();
direction = DIR_DOWN;
if (target > 0 && source != target && !unUsableRoomSet.contains(target) && !pSourceR->hasExitLock(direction)) {
pTargetR = mpRoomDB->getRoom(target);
if (pTargetR && !pTargetR->isLocked) {
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
route r;
r.cost = exitWeights.value(QStringLiteral("down"), pTargetR->getWeight());
if (!bestRoutes.contains(target) || bestRoutes.value(target).cost > r.cost) {
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
r.direction = direction;
bestRoutes.insert(target, r);
}
2011-06-26 15:23:37 +02:00
}
}
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
target = pSourceR->getNortheast();
direction = DIR_NORTHEAST;
if (target > 0 && source != target && !unUsableRoomSet.contains(target) && !pSourceR->hasExitLock(direction)) {
pTargetR = mpRoomDB->getRoom(target);
if (pTargetR && !pTargetR->isLocked) {
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
route r;
r.cost = exitWeights.value(QStringLiteral("ne"), pTargetR->getWeight());
if (!bestRoutes.contains(target) || bestRoutes.value(target).cost > r.cost) {
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
r.direction = direction;
bestRoutes.insert(target, r);
}
2011-06-26 15:23:37 +02:00
}
}
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
target = pSourceR->getSoutheast();
direction = DIR_SOUTHEAST;
if (target > 0 && source != target && !unUsableRoomSet.contains(target) && !pSourceR->hasExitLock(direction)) {
pTargetR = mpRoomDB->getRoom(target);
if (pTargetR && !pTargetR->isLocked) {
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
route r;
r.cost = exitWeights.value(QStringLiteral("se"), pTargetR->getWeight());
if (!bestRoutes.contains(target) || bestRoutes.value(target).cost > r.cost) {
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
r.direction = direction;
bestRoutes.insert(target, r);
}
2011-06-26 15:23:37 +02:00
}
}
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
target = pSourceR->getSouthwest();
direction = DIR_SOUTHWEST;
if (target > 0 && source != target && !unUsableRoomSet.contains(target) && !pSourceR->hasExitLock(direction)) {
pTargetR = mpRoomDB->getRoom(target);
if (pTargetR && !pTargetR->isLocked) {
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
route r;
r.cost = exitWeights.value(QStringLiteral("sw"), pTargetR->getWeight());
if (!bestRoutes.contains(target) || bestRoutes.value(target).cost > r.cost) {
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
r.direction = direction;
bestRoutes.insert(target, r);
}
2011-06-26 15:23:37 +02:00
}
}
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
target = pSourceR->getNorthwest();
direction = DIR_NORTHWEST;
if (target > 0 && source != target && !unUsableRoomSet.contains(target) && !pSourceR->hasExitLock(direction)) {
pTargetR = mpRoomDB->getRoom(target);
if (pTargetR && !pTargetR->isLocked) {
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
route r;
r.cost = exitWeights.value(QStringLiteral("nw"), pTargetR->getWeight());
if (!bestRoutes.contains(target) || bestRoutes.value(target).cost > r.cost) {
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
r.direction = direction;
bestRoutes.insert(target, r);
}
2011-06-26 15:23:37 +02:00
}
}
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
target = pSourceR->getIn();
direction = DIR_IN;
if (target > 0 && source != target && !unUsableRoomSet.contains(target) && !pSourceR->hasExitLock(direction)) {
pTargetR = mpRoomDB->getRoom(target);
if (pTargetR && !pTargetR->isLocked) {
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
route r;
r.cost = exitWeights.value(QStringLiteral("in"), pTargetR->getWeight());
if (!bestRoutes.contains(target) || bestRoutes.value(target).cost > r.cost) {
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
r.direction = direction;
bestRoutes.insert(target, r);
}
2011-06-26 15:23:37 +02:00
}
}
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
target = pSourceR->getOut();
direction = DIR_OUT;
if (target > 0 && source != target && !unUsableRoomSet.contains(target) && !pSourceR->hasExitLock(direction)) {
pTargetR = mpRoomDB->getRoom(target);
if (pTargetR && !pTargetR->isLocked) {
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
route r;
r.cost = exitWeights.value(QStringLiteral("out"), pTargetR->getWeight());
if (!bestRoutes.contains(target) || bestRoutes.value(target).cost > r.cost) {
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
r.direction = direction;
bestRoutes.insert(target, r);
}
2011-06-26 15:23:37 +02:00
}
}
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
QMapIterator<int, QString> itSpecialExit(pSourceR->getOtherMap());
while (itSpecialExit.hasNext()) {
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
itSpecialExit.next();
if ((itSpecialExit.value()).startsWith(QStringLiteral("1"))) {
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
continue; // Is a locked exit so forget it...
}
target = itSpecialExit.key();
direction = DIR_OTHER;
if (target > 0 && source != target && !unUsableRoomSet.contains(target)) {
pTargetR = mpRoomDB->getRoom(target);
if (pTargetR && !pTargetR->isLocked) {
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
route r;
if (Q_LIKELY((itSpecialExit.value()).startsWith(QStringLiteral("0")))) {
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
r.specialExitName = itSpecialExit.value().mid(1);
} else {
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
r.specialExitName = itSpecialExit.value();
}
r.cost = exitWeights.value(r.specialExitName, pTargetR->getWeight());
if (!bestRoutes.contains(target) || bestRoutes.value(target).cost > r.cost) {
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
r.direction = direction;
bestRoutes.insert(target, r);
}
2011-06-26 15:23:37 +02:00
}
}
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
} // End of while(itSpecialExit.hasNext())
// Now we have eliminated possibe duplicate and useless edges we can create and
// insert the remainder into the BGL graph:
QHashIterator<unsigned int, route> itRoute = bestRoutes;
while (itRoute.hasNext()) {
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
itRoute.next();
edge_descriptor e;
bool inserted; // This is always going to be false as it gets set if
// we had tried to insert a parallel edge into a graph
// that does not support them - but we've just been
// and disposed of those already!
tie(e, inserted) = add_edge(roomidToIndex.value(source), roomidToIndex.value(itRoute.key()), itRoute.value().cost, g);
edgeHash.insert(qMakePair(source, itRoute.key()), itRoute.value());
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
// The key is made from the QPair<edgeSourceRoomId, edgeTargetRoomId>...
edgeCount++;
}
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
} // End of foreach(location l, locations)
mMapGraphNeedsUpdate = false;
qDebug() << "TMap::initGraph() INFO: built graph with:" << locations.size() << "(" << roomCount << ") locations(roomCount), and discarded" << unUsableRoomSet.count()
<< "other NOT useable rooms and found:" << edgeCount << "distinct, usable edges in:" << _time.nsecsElapsed() * 1.0e-9 << "seconds.";
}
bool TMap::findPath(int from, int to)
{
if (mMapGraphNeedsUpdate) {
initGraph();
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
}
QElapsedTimer t;
t.start();
mPathList.clear();
mDirList.clear();
mWeightList.clear();
// Clear the previous path data here so that if the following test is
// passed, the data is empty - and valid for THAT case!
if (from == to) {
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
return true; // Take a short-cut for trival "already there" case!
}
TRoom* pFrom = mpRoomDB->getRoom(from);
TRoom* pTo = mpRoomDB->getRoom(to);
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
if (!pFrom || !pTo) {
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
qDebug() << "TMap::findPath(" << from << "," << to << ") FAIL: NULL TRoom pointer for start or target rooms!";
return false;
}
bool hasUsableExit = false;
if (pFrom->getNorth() > 0 && (!pFrom->hasExitLock(DIR_NORTH))) {
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
hasUsableExit = true;
}
if (!hasUsableExit && pFrom->getSouth() > 0 && (!pFrom->hasExitLock(DIR_SOUTH))) {
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
hasUsableExit = true;
}
if (!hasUsableExit && pFrom->getWest() > 0 && (!pFrom->hasExitLock(DIR_WEST))) {
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
hasUsableExit = true;
}
if (!hasUsableExit && pFrom->getEast() > 0 && (!pFrom->hasExitLock(DIR_EAST))) {
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
hasUsableExit = true;
}
if (!hasUsableExit && pFrom->getUp() > 0 && (!pFrom->hasExitLock(DIR_UP))) {
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
hasUsableExit = true;
}
if (!hasUsableExit && pFrom->getDown() > 0 && (!pFrom->hasExitLock(DIR_DOWN))) {
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
hasUsableExit = true;
}
if (!hasUsableExit && pFrom->getNortheast() > 0 && (!pFrom->hasExitLock(DIR_NORTHEAST))) {
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
hasUsableExit = true;
}
if (!hasUsableExit && pFrom->getNorthwest() > 0 && (!pFrom->hasExitLock(DIR_NORTHWEST))) {
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
hasUsableExit = true;
}
if (!hasUsableExit && pFrom->getSoutheast() > 0 && (!pFrom->hasExitLock(DIR_SOUTHEAST))) {
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
hasUsableExit = true;
}
if (!hasUsableExit && pFrom->getSouthwest() > 0 && (!pFrom->hasExitLock(DIR_SOUTHWEST))) {
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
hasUsableExit = true;
}
if (!hasUsableExit && pFrom->getIn() > 0 && (!pFrom->hasExitLock(DIR_IN))) {
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
hasUsableExit = true;
}
if (!hasUsableExit && pFrom->getOut() > 0 && (!pFrom->hasExitLock(DIR_OUT))) {
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
hasUsableExit = true;
}
if (!hasUsableExit) {
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
// No available normal exits from this room so check the special ones
QStringList specialExitCommands = pFrom->getOtherMap().values();
while (!specialExitCommands.isEmpty()) {
if (specialExitCommands.at(0).mid(0, 1) == "0") {
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
hasUsableExit = true;
break;
}
specialExitCommands.removeFirst();
}
}
if (!hasUsableExit) {
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
qDebug() << "TMap::findPath(" << from << "," << to << ") FAIL: no usable exits from start room!";
return false; // No available exits from the start room so give up!
}
if (!roomidToIndex.contains(from)) {
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
qDebug() << "TMap::findPath(" << from << "," << to << ") FAIL: start room not in map graph!";
return false;
// The start room is NOT one that has been included in the BGL graph
// probably because it is locked - so no route finding can be done
}
vertex start = roomidToIndex.value(from);
if (!roomidToIndex.contains(to)) {
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
qDebug() << "TMap::findPath(" << from << "," << to << ") FAIL: target room not in map graph!";
return false;
// The target room is NOT one that has been included in the BGL graph
// probably because it is locked - so no route finding can be done
}
vertex goal = roomidToIndex.value(to);
std::vector<vertex> p(num_vertices(g));
2017-12-29 16:37:11 +01:00
// Somehow p is an ascending, monotonic series of numbers start at 0, it
// seems we have a redundant indirection in play there as p[0]=0, p[1]=1,..., p[n]=n ...!
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
std::vector<cost> d(num_vertices(g));
try {
astar_search(g, start, distance_heuristic<mygraph_t, cost, std::vector<location>>(locations, goal), predecessor_map(&p[0]).distance_map(&d[0]).visitor(astar_goal_visitor<vertex>(goal)));
} catch (found_goal) {
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
qDebug() << "TMap::findPath(" << from << "," << to << ") INFO: time elapsed in A*:" << t.nsecsElapsed() * 1.0e-9 << "seconds.";
t.restart();
if (!roomidToIndex.contains(to)) {
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
qDebug() << "TMap::findPath(" << from << "," << to << ") FAIL: target room not in map graph!";
return false;
}
vertex currentVertex = roomidToIndex.value(to);
unsigned int currentRoomId = (locations.at(currentVertex)).id;
// We step through the found path BACKWARDS so advance (well retard)
// the "previous" one first, and it will be the SOURCE vertex for the
// edge and current will be the TARGET vertex:
vertex previousVertex = currentVertex;
do {
previousVertex = p[currentVertex];
if (previousVertex == currentVertex) {
qDebug() << "TMap::findPath(" << from << "," << to << ") WARN: unable to build a path in:" << t.nsecsElapsed() * 1.0e-9 << "seconds.";
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
mPathList.clear();
mDirList.clear();
mWeightList.clear(); // Reset any partial results...
return false;
}
unsigned int previousRoomId = (locations.at(previousVertex)).id;
QPair<unsigned int, unsigned int> edgeRoomIdPair = qMakePair(previousRoomId, currentRoomId);
route r = edgeHash.value(edgeRoomIdPair);
mPathList.prepend(currentRoomId);
Q_ASSERT_X(r.cost > 0, "TMap::findPath()", "broken path {QPair made from source and target roomIds for a path step NOT found in QHash table of all possible steps.}");
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
// Above was found to be triggered by the situation described in:
// https://bugs.launchpad.net/mudlet/+bug/1263447 on 2015-07-17 but
// this is because previousVertex was the same as currentVertex after
// the "previousVertex = p[currentVertex]" operation at the start of
// the do{} loop - added a test for this so should bail out if it
// happens - Slysven
mWeightList.prepend( r.cost );
switch( r.direction ) { // TODO: Eventually this can instead drop in I18ned values set by country or user preference!
case DIR_NORTH: mDirList.prepend( tr( "n", "This translation converts the direction that DIR_NORTH codes for to a direction string that the game server will accept!" ) ); break;
case DIR_NORTHEAST: mDirList.prepend( tr( "ne", "This translation converts the direction that DIR_NORTHEAST codes for to a direction string that the game server will accept!" ) ); break;
case DIR_EAST: mDirList.prepend( tr( "e", "This translation converts the direction that DIR_EAST codes for to a direction string that the game server will accept!" ) ); break;
case DIR_SOUTHEAST: mDirList.prepend( tr( "se", "This translation converts the direction that DIR_SOUTHEAST codes for to a direction string that the game server will accept!" ) ); break;
case DIR_SOUTH: mDirList.prepend( tr( "s", "This translation converts the direction that DIR_SOUTH codes for to a direction string that the game server will accept!" ) ); break;
case DIR_SOUTHWEST: mDirList.prepend( tr( "sw", "This translation converts the direction that DIR_SOUTHWEST codes for to a direction string that the game server will accept!" ) ); break;
case DIR_WEST: mDirList.prepend( tr( "w", "This translation converts the direction that DIR_WEST codes for to a direction string that the game server will accept!" ) ); break;
case DIR_NORTHWEST: mDirList.prepend( tr( "nw", "This translation converts the direction that DIR_NORTHWEST codes for to a direction string that the game server will accept!" ) ); break;
case DIR_UP: mDirList.prepend( tr( "up", "This translation converts the direction that DIR_UP codes for to a direction string that the game server will accept!" ) ); break;
case DIR_DOWN: mDirList.prepend( tr( "down", "This translation converts the direction that DIR_DOWN codes for to a direction string that the game server will accept!" ) ); break;
case DIR_IN: mDirList.prepend( tr( "in", "This translation converts the direction that DIR_IN codes for to a direction string that the game server will accept!" ) ); break;
case DIR_OUT: mDirList.prepend( tr( "out", "This translation converts the direction that DIR_OUT codes for to a direction string that the game server will accept!" ) ); break;
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
case DIR_OTHER: mDirList.prepend( r.specialExitName ); break;
Revision: route most of map auditing messages to errors.txt file As the amount of messages produced by the new/improve map auditing/clean-up code can be large for old map files this commit causes them to be sent to a profile specific file that is already opened by the Host class but has not been used for some time. An option (a check-box) on the "map" tab of the "profile preferences" dialog controls whether the equivalent information is also shown on the profile's main console as in the past. If the option (a global one) which is saved between sessions/runs is NOT enabled then an advisory is sent to the console advising the user to review the file contents if a "significant" issue was detected. If it is enabled a similar message advising that the information has also been saved. In either case, as the file is appended to, and not rewritten each time, the message includes details of the first line of the report so that it can be located in the file. One difference between the on-screen and the file versions of the information is that the former puts up the issues as they are detected whereas the latter groups the information by subject, first the general overall issues, then the area ones, in order of the areas' id numbers and then the room ones, in room order. Following earlier discussions in these Pull Request I have attempted to edit all uses of the word "Id" in user visible places to be "id" instead. This threw up some other messages with issues in several files that I have tweaked here as well! Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2016-05-03 04:58:31 +01:00
default: qWarning() << "TMap::findPath(" << from << "," << to << ") WARN: found route between rooms (from id:" << previousRoomId << ", to id:" << currentRoomId << ") with an invalid DIR_xxxx code:" << r.direction << " - the path will not be valid!" ;
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
}
currentVertex = previousVertex;
currentRoomId = previousRoomId;
} while (currentVertex != start);
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
qDebug() << "TMap::findPath(" << from << "," << to << ") INFO: found path in:" << t.nsecsElapsed() * 1.0e-9 << "seconds.";
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
return true;
}
qDebug() << "TMap::findPath(" << from << "," << to << ") INFO: did NOT find path in:" << t.nsecsElapsed() * 1.0e-9 << "seconds.";
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
return false;
2010-08-25 00:41:43 +02:00
}
bool TMap::serialize(QDataStream& ofs)
2010-08-25 00:41:43 +02:00
{
if (mSaveVersion != mVersion) {
QString message = tr("[ ALERT ] - Saving map in a format {%1} that is different than the one it was\n"
"loaded as {%2}. This may be an issue if you want to share the resulting\n"
"map with others relying on the original format.")
.arg(mSaveVersion)
.arg(mVersion);
appendErrorMsgWithNoLf(message, false);
mpHost->mTelnet.postMessage(message);
}
if (mSaveVersion != mDefaultVersion) {
QString message = tr("[ WARN ] - Saving map in a format {%1} that is different than the one\n"
"recommended {%2} baring in mind the build status of the source\n"
"code. Development code versions may offer the chance to try\n"
"experimental features needing a revised format that could be\n"
"incompatible with existing release code versions. Conversely\n"
"a release version may allow you to downgrade to save a map in\n"
"a format compatible with others using older versions of MUDLET\n"
"however some features may be crippled or non-operational for\n"
"this version of MUDLET.")
.arg(mSaveVersion)
.arg(mDefaultVersion);
appendErrorMsgWithNoLf(message, false);
postMessage(message);
Enhance: add Area & Map user data structures & Lua script access commands Whilst working on the XML importer for Map files I found that I wanted some where to store the data from attributes for tags that we don't use in Mudlet directly. For room related details I could use the TRoom::userData member but then I realised that there is nothing corresponding to Areas or for the Map overall. This separate commit provides these and the lua commands to interact with them - with functionality the same as the Room based one. Of course, as there is only ONE map there is no argument needed to select an instance for those commands. Of all the "room" user data commands replicated for "area" and "map" the only one NOT so done are get????UserDataKeys() as this is a bit pointless with a getAll????UserData() one from which the keys could be extracted from the returned table {???? being "Area" or "Map"}. Added to TLuaInterpreter class to provide following user script commands: searchAreaUserData((string)<key>[, (string)<value>]) setAreaUserData((number)<area Id>, (string)<key>, (string)<value>) clearAreaUserData((number)<area Id>) clearAreaUserDataItem((number)<area Id>, (string)<key>) getAreaUserData((number)<area Id>, (string)<key>) getAllAreaUserData((number)<area Id>) setMapUserData((string)<key>, (string)<value>) clearMapUserData((string)<key>) clearMapUserDataItem() getMapUserData((string)<key>) getAllMapUserData() Refactored TMap::serialize() to allow saving in different map file formats as defined by the constants TMap::mDefaultVersion, mMinVersion and mMaxVersion - if either of the last pair are less than or more than the first value respectively then a control on the "Special Options" tab of the profile preferences dialog will be enabled - the state of each value that is allowed is clearly indicated and it is defaulted appropriately. At present: TMap::mDefaultVersion is 16 (replaces #define CURRENT_MAP_VERSION) TMap::mMinVersion is also 16 TMap::mMaxVersion is 17 This means that the new user data areas will only persist (be saved) if that control is manually adjusted to 17 FOR EACH SESSION in this development version. When we get to a release version mDefaultVersion should be upped to 17 so that the release version uses the new format but can be manually downgraded to current (16) for those who want to share a map with users who have not upgraded - with the less of those new user data items - such users can do this by opening the profile preferences, downing this setting THEN using the SAVE MAP button and then restoring to the default value and SAVING AGAIN to a different name in the recommend format. Also renamed TMap::version to TMap::mVersion... ========================================================================== As this code requires the revision to the map file format that is coded for but only enabled manually the setter commands setAreaUserData(...) and setMapUserData(...) will both emit a warning message that the data written will not CURRENTLY be saved with the map the FIRST (and only the first) time they are used when the preference control has not been manually adjusted. ========================================================================== Also: Tweaked a recent, previous merged commit that set an optional minimum time for a Timer NOT to display it's contents every time it fires in debug output screen in value: Host::mTimerDebugOutputSuppressionInterval so that the QTimeEdit that controls it defaults to adjusting the "Seconds" time field rather than the default "Hours" one as that is the one that is most likely the one the user might wist to use. Also: The control this commit adds to the Profile Preferences dialog makes use of the QComboBox::currentData() method that was introduced in Qt5.2 - the minimum Qt library requirement in the qmake project file was revised to accomodate this - if builders wish to use a Qt5.x before this they will need to manually provide extra code to allocate an integer value from the range of values wanted/offered. Also: whilst cross-checking for the cmake project file I found the top level one was missing from the qmake project file - so have added it to that. HOWEVER I HAVE NOT FOUND A WAY TO REQUIRE THE CMAKE SYSTEM TO REQUIRE QT5.2 AS A MINIMUM WHICH THIS COMMIT REQUIRES. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> Conflicts: src/src.pro
2015-12-30 13:42:41 +00:00
}
ofs << mSaveVersion;
2010-08-25 00:41:43 +02:00
ofs << envColors;
2013-03-22 12:47:58 +01:00
ofs << mpRoomDB->getAreaNamesMap();
2010-09-10 00:34:51 +02:00
ofs << customEnvColors;
2013-03-22 12:47:58 +01:00
ofs << mpRoomDB->hashTable;
if (mSaveVersion >= 17) {
Enhance: add ability to set any glyph as a room symbol (#1543) This is a squashed down commit containing several commits with messages - this is the edited combination of all the messages: As well as being able to use any grapheme it is possible to use a short word as well as anything printable from any of the Unicode Multiple Planes; although the former will become smaller to fit within both the square and round room shapes on the 2D mapper. Adds controls to the profile preference to set the (preferred) font to use to set the room symbols from and a checkbox to only use that font. Additionally a sub-dialog can be brought up which lists the details of all the different symbols on the map - showing the Unicode codepoint(s) for each and showing how they would be rendered if only the selected font is used and if any font is permitted, along with a count of the usages and the rooms that use each one... A status icon is also displayed showing whether the symbol can be rendered entirely with the selected font (green tick), only by using glyphs from other fonts (yellow ! warning) or not with the current fonts on the system (red/white cross). This allows a user to make a sensible selection of a font to use or whether they will have a problem (and a replacement by the replacement character '�') for any symbols. Updates Lua setRoomChar and getRoomChar to handle the wider range of things that can be used. getRoomChar NOW allows for an existing character to be cleared with an empty string or a space as the char attribute. The map format version has been incremented to allow the data needed to be saved directly into the binary file format but failback code is in place that means that this feature can be carried in map and room user data instead for map format versions down to 17 - the current default is 18 and there is limited support to fail gracefully down to the 16 that Mudlet 2.1 uses (all the room letter markings that are not supported will become '?', and the font data will be lost, but the correct room character data will still be in the room user data.) Following review: * I replaced some colour specifications (white and transparent) with Qt constants. * Use the same inline function flushSymbolPixmapCache() to clear the map symbol pixmap cache in all places where it might be useful. * Simplify a couple of places where an if(...) {...} else {...} can be replaced with the (...) ? (...) : (...) operator. * Limit the number of room numbers displayed for each symbol in the new widget - to avoid complications where there are huge numbers of rooms using a symbol. * Replace a use of QTableWidget::clearContents() with QTableWidgets::setRowCount(0) as I was getting some odd, deep in the Qt internal library issues {Fatal Seg. Faults!} with the former, which I suspect, but could not prove, might have been a re-entrancy issue caused by the method containing it being called indirectly by an asynchronous SIGNAL/SLOT originating in the value change from the map symbol font selection QFontComboBox... Revised to NOT do scaling when drawing room symbols from cache: the previous QPainter::drawPixmap(...) performed a scaling operation to make the symbol pixmap fit the specified rectangle. This is the cause behind the poor rendering of text characters as the scaling undoes the benefits of anti-aliasing and takes time to do. This should be faster now because the pixmaps are generated at the size/resolution they are needed (though they do have to be thrown away and regenerated if the zoom or other sizing factors change) - they do however look better to me! Also: * merged (int) TRoom::xzoom and TRoom::yzoom into TRoom::xyzoom. * added the symbol scaling "fudge-factor" to the "Special Options" tab of the "Profile preferences" dialog - it may be helpful to artificially over-size (> 1.00) or under-size (< 1.00) the symbols in some situations. * uses the word symbol rather than just glyph/grapheme in some texts. Also modified 2D mapper "Symbol" tooltip to observe that more than one letter/symbol can be used (although they will be drawn smaller so that they still fit). Add tool-tips to profile preferences dialog for font controls (except for "fudge factor" control (with range x0.50 to x2.00 for scaling of symbol to test rectangle used to fit it into the room shape)... I have consistently mispelled chosen as choosen but I have fixed that now...! Also added tooltips to map glyph usage table/widget. WorkAround: try to force a specific US mirror for zziplib on AppVeyor CI AppVeyor is based in Vancouver, Canada so the nearest SF Mirror is in the US so this commit forces the use of that mirror for that library for the CI build process as an attempt to get around the repeated, intermittent failures to get that library from SourceForge (it is now the only item that needs to be downloaded from there for such builds)... Also adds another CI file that was not mentioned before in the qmake project file and thus did not show up in the Qt IDE. Following extensive discussions it has been made clear that introducing replacements for the lua [gs]etRoomChar(...) is not going to happen. Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2018-03-28 14:06:12 +01:00
if (mSaveVersion < 19) {
// Save the data in the map user data for older versions
mUserData.insert(QStringLiteral("system.fallback_mapSymbolFont"), mMapSymbolFont.toString());
mUserData.insert(QStringLiteral("system.fallback_mapSymbolFontFudgeFactor"), QString::number(mMapSymbolFontFudgeFactor));
mUserData.insert(QStringLiteral("system.fallback_onlyUseMapSymbolFont"), mIsOnlyMapSymbolFontToBeUsed ? QStringLiteral("true") : QStringLiteral("false"));
}
Enhance: add Area & Map user data structures & Lua script access commands Whilst working on the XML importer for Map files I found that I wanted some where to store the data from attributes for tags that we don't use in Mudlet directly. For room related details I could use the TRoom::userData member but then I realised that there is nothing corresponding to Areas or for the Map overall. This separate commit provides these and the lua commands to interact with them - with functionality the same as the Room based one. Of course, as there is only ONE map there is no argument needed to select an instance for those commands. Of all the "room" user data commands replicated for "area" and "map" the only one NOT so done are get????UserDataKeys() as this is a bit pointless with a getAll????UserData() one from which the keys could be extracted from the returned table {???? being "Area" or "Map"}. Added to TLuaInterpreter class to provide following user script commands: searchAreaUserData((string)<key>[, (string)<value>]) setAreaUserData((number)<area Id>, (string)<key>, (string)<value>) clearAreaUserData((number)<area Id>) clearAreaUserDataItem((number)<area Id>, (string)<key>) getAreaUserData((number)<area Id>, (string)<key>) getAllAreaUserData((number)<area Id>) setMapUserData((string)<key>, (string)<value>) clearMapUserData((string)<key>) clearMapUserDataItem() getMapUserData((string)<key>) getAllMapUserData() Refactored TMap::serialize() to allow saving in different map file formats as defined by the constants TMap::mDefaultVersion, mMinVersion and mMaxVersion - if either of the last pair are less than or more than the first value respectively then a control on the "Special Options" tab of the profile preferences dialog will be enabled - the state of each value that is allowed is clearly indicated and it is defaulted appropriately. At present: TMap::mDefaultVersion is 16 (replaces #define CURRENT_MAP_VERSION) TMap::mMinVersion is also 16 TMap::mMaxVersion is 17 This means that the new user data areas will only persist (be saved) if that control is manually adjusted to 17 FOR EACH SESSION in this development version. When we get to a release version mDefaultVersion should be upped to 17 so that the release version uses the new format but can be manually downgraded to current (16) for those who want to share a map with users who have not upgraded - with the less of those new user data items - such users can do this by opening the profile preferences, downing this setting THEN using the SAVE MAP button and then restoring to the default value and SAVING AGAIN to a different name in the recommend format. Also renamed TMap::version to TMap::mVersion... ========================================================================== As this code requires the revision to the map file format that is coded for but only enabled manually the setter commands setAreaUserData(...) and setMapUserData(...) will both emit a warning message that the data written will not CURRENTLY be saved with the map the FIRST (and only the first) time they are used when the preference control has not been manually adjusted. ========================================================================== Also: Tweaked a recent, previous merged commit that set an optional minimum time for a Timer NOT to display it's contents every time it fires in debug output screen in value: Host::mTimerDebugOutputSuppressionInterval so that the QTimeEdit that controls it defaults to adjusting the "Seconds" time field rather than the default "Hours" one as that is the one that is most likely the one the user might wist to use. Also: The control this commit adds to the Profile Preferences dialog makes use of the QComboBox::currentData() method that was introduced in Qt5.2 - the minimum Qt library requirement in the qmake project file was revised to accomodate this - if builders wish to use a Qt5.x before this they will need to manually provide extra code to allocate an integer value from the range of values wanted/offered. Also: whilst cross-checking for the cmake project file I found the top level one was missing from the qmake project file - so have added it to that. HOWEVER I HAVE NOT FOUND A WAY TO REQUIRE THE CMAKE SYSTEM TO REQUIRE QT5.2 AS A MINIMUM WHICH THIS COMMIT REQUIRES. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> Conflicts: src/src.pro
2015-12-30 13:42:41 +00:00
ofs << mUserData;
Enhance: add ability to set any glyph as a room symbol (#1543) This is a squashed down commit containing several commits with messages - this is the edited combination of all the messages: As well as being able to use any grapheme it is possible to use a short word as well as anything printable from any of the Unicode Multiple Planes; although the former will become smaller to fit within both the square and round room shapes on the 2D mapper. Adds controls to the profile preference to set the (preferred) font to use to set the room symbols from and a checkbox to only use that font. Additionally a sub-dialog can be brought up which lists the details of all the different symbols on the map - showing the Unicode codepoint(s) for each and showing how they would be rendered if only the selected font is used and if any font is permitted, along with a count of the usages and the rooms that use each one... A status icon is also displayed showing whether the symbol can be rendered entirely with the selected font (green tick), only by using glyphs from other fonts (yellow ! warning) or not with the current fonts on the system (red/white cross). This allows a user to make a sensible selection of a font to use or whether they will have a problem (and a replacement by the replacement character '�') for any symbols. Updates Lua setRoomChar and getRoomChar to handle the wider range of things that can be used. getRoomChar NOW allows for an existing character to be cleared with an empty string or a space as the char attribute. The map format version has been incremented to allow the data needed to be saved directly into the binary file format but failback code is in place that means that this feature can be carried in map and room user data instead for map format versions down to 17 - the current default is 18 and there is limited support to fail gracefully down to the 16 that Mudlet 2.1 uses (all the room letter markings that are not supported will become '?', and the font data will be lost, but the correct room character data will still be in the room user data.) Following review: * I replaced some colour specifications (white and transparent) with Qt constants. * Use the same inline function flushSymbolPixmapCache() to clear the map symbol pixmap cache in all places where it might be useful. * Simplify a couple of places where an if(...) {...} else {...} can be replaced with the (...) ? (...) : (...) operator. * Limit the number of room numbers displayed for each symbol in the new widget - to avoid complications where there are huge numbers of rooms using a symbol. * Replace a use of QTableWidget::clearContents() with QTableWidgets::setRowCount(0) as I was getting some odd, deep in the Qt internal library issues {Fatal Seg. Faults!} with the former, which I suspect, but could not prove, might have been a re-entrancy issue caused by the method containing it being called indirectly by an asynchronous SIGNAL/SLOT originating in the value change from the map symbol font selection QFontComboBox... Revised to NOT do scaling when drawing room symbols from cache: the previous QPainter::drawPixmap(...) performed a scaling operation to make the symbol pixmap fit the specified rectangle. This is the cause behind the poor rendering of text characters as the scaling undoes the benefits of anti-aliasing and takes time to do. This should be faster now because the pixmaps are generated at the size/resolution they are needed (though they do have to be thrown away and regenerated if the zoom or other sizing factors change) - they do however look better to me! Also: * merged (int) TRoom::xzoom and TRoom::yzoom into TRoom::xyzoom. * added the symbol scaling "fudge-factor" to the "Special Options" tab of the "Profile preferences" dialog - it may be helpful to artificially over-size (> 1.00) or under-size (< 1.00) the symbols in some situations. * uses the word symbol rather than just glyph/grapheme in some texts. Also modified 2D mapper "Symbol" tooltip to observe that more than one letter/symbol can be used (although they will be drawn smaller so that they still fit). Add tool-tips to profile preferences dialog for font controls (except for "fudge factor" control (with range x0.50 to x2.00 for scaling of symbol to test rectangle used to fit it into the room shape)... I have consistently mispelled chosen as choosen but I have fixed that now...! Also added tooltips to map glyph usage table/widget. WorkAround: try to force a specific US mirror for zziplib on AppVeyor CI AppVeyor is based in Vancouver, Canada so the nearest SF Mirror is in the US so this commit forces the use of that mirror for that library for the CI build process as an attempt to get around the repeated, intermittent failures to get that library from SourceForge (it is now the only item that needs to be downloaded from there for such builds)... Also adds another CI file that was not mentioned before in the qmake project file and thus did not show up in the Qt IDE. Following extensive discussions it has been made clear that introducing replacements for the lua [gs]etRoomChar(...) is not going to happen. Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2018-03-28 14:06:12 +01:00
if (mSaveVersion >= 19) {
// Save the data directly in supported format versions
ofs << mMapSymbolFont;
ofs << mMapSymbolFontFudgeFactor;
ofs << mIsOnlyMapSymbolFontToBeUsed;
}
Enhance: add Area & Map user data structures & Lua script access commands Whilst working on the XML importer for Map files I found that I wanted some where to store the data from attributes for tags that we don't use in Mudlet directly. For room related details I could use the TRoom::userData member but then I realised that there is nothing corresponding to Areas or for the Map overall. This separate commit provides these and the lua commands to interact with them - with functionality the same as the Room based one. Of course, as there is only ONE map there is no argument needed to select an instance for those commands. Of all the "room" user data commands replicated for "area" and "map" the only one NOT so done are get????UserDataKeys() as this is a bit pointless with a getAll????UserData() one from which the keys could be extracted from the returned table {???? being "Area" or "Map"}. Added to TLuaInterpreter class to provide following user script commands: searchAreaUserData((string)<key>[, (string)<value>]) setAreaUserData((number)<area Id>, (string)<key>, (string)<value>) clearAreaUserData((number)<area Id>) clearAreaUserDataItem((number)<area Id>, (string)<key>) getAreaUserData((number)<area Id>, (string)<key>) getAllAreaUserData((number)<area Id>) setMapUserData((string)<key>, (string)<value>) clearMapUserData((string)<key>) clearMapUserDataItem() getMapUserData((string)<key>) getAllMapUserData() Refactored TMap::serialize() to allow saving in different map file formats as defined by the constants TMap::mDefaultVersion, mMinVersion and mMaxVersion - if either of the last pair are less than or more than the first value respectively then a control on the "Special Options" tab of the profile preferences dialog will be enabled - the state of each value that is allowed is clearly indicated and it is defaulted appropriately. At present: TMap::mDefaultVersion is 16 (replaces #define CURRENT_MAP_VERSION) TMap::mMinVersion is also 16 TMap::mMaxVersion is 17 This means that the new user data areas will only persist (be saved) if that control is manually adjusted to 17 FOR EACH SESSION in this development version. When we get to a release version mDefaultVersion should be upped to 17 so that the release version uses the new format but can be manually downgraded to current (16) for those who want to share a map with users who have not upgraded - with the less of those new user data items - such users can do this by opening the profile preferences, downing this setting THEN using the SAVE MAP button and then restoring to the default value and SAVING AGAIN to a different name in the recommend format. Also renamed TMap::version to TMap::mVersion... ========================================================================== As this code requires the revision to the map file format that is coded for but only enabled manually the setter commands setAreaUserData(...) and setMapUserData(...) will both emit a warning message that the data written will not CURRENTLY be saved with the map the FIRST (and only the first) time they are used when the preference control has not been manually adjusted. ========================================================================== Also: Tweaked a recent, previous merged commit that set an optional minimum time for a Timer NOT to display it's contents every time it fires in debug output screen in value: Host::mTimerDebugOutputSuppressionInterval so that the QTimeEdit that controls it defaults to adjusting the "Seconds" time field rather than the default "Hours" one as that is the one that is most likely the one the user might wist to use. Also: The control this commit adds to the Profile Preferences dialog makes use of the QComboBox::currentData() method that was introduced in Qt5.2 - the minimum Qt library requirement in the qmake project file was revised to accomodate this - if builders wish to use a Qt5.x before this they will need to manually provide extra code to allocate an integer value from the range of values wanted/offered. Also: whilst cross-checking for the cmake project file I found the top level one was missing from the qmake project file - so have added it to that. HOWEVER I HAVE NOT FOUND A WAY TO REQUIRE THE CMAKE SYSTEM TO REQUIRE QT5.2 AS A MINIMUM WHICH THIS COMMIT REQUIRES. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> Conflicts: src/src.pro
2015-12-30 13:42:41 +00:00
}
Fixup: correct some issues raised in testing * In dlgTrigger C'tor tweaked Qt Version check for inclusion of placeholder text - should be 5.3 not 5.2. * In source_editor_area.ui restore the full-widget background painting - which otherwise limited the background colour to the extent of the content not the widget and when reviewed was NOT wanted. * In dlgTriggerEditor::slot_cursorPositionChanged() rearrange "current position" details to a more acceptable order with line counts first. * Initialise Host::mTimerDebugOutputSuppressionInterval member so that the adjustment control in "Profile Preferences" comes up with a consistent value on first use. When testing it became clear that the behaviour when moving away from the zero "Show all" value would start acting on the most significant section ("Hours") rather than the more useful "Seconds". Added void dlgProfilePreferences::slot_timeValueChanged(QTime) private slot connect to the timeChanged(QTime) signal to handle things. Whilst fixing the above things I also became aware of and addressed: * When the Profile Preferences dialog is open the map format save control was not being initialised to the current setting but to the default 16 instead - this is confusing for someone who HAS changed the value and goes back to see it reset - even though it has not been until they close (and thus save) whatever the value. * Absence of tool-tips for Profile Preference Special Option mentioned above to cut down spam from short interval Timers and also the map save version override control. * There are already warning in place the first time that the Lua set{Map|Area}UserData(...) commands are used and the map format is not 17 but this is is now detected on map save. However as this can happen when the user closes Mudlet and they won't get displayed in time the other warnings are still useful - both of these can be removed in the future when the current format of 16 is not longer available. * Spotted a potential bug in that when saving rooms there is not a null room pointer check to skip the (hopefully) unlikely case of a QHash<int, TRoom*>TRoomDB:rooms value being null - this would cause a null pointer bug and thus a probable crash when straigt afterward that pointer would be dereferenced. * The Editor toolbar button to show/hide the search area also shows and hides the area where "Errors" {"popupArea"} are displayed within the Editor widget. Probably a long standing issue from the past evolution of the editor. * Spotted that the statusBar tip for the "copy HTML" context menu command for the TTextEdit class was being applied to the "copy" entry - so that the "copy" command got the wrong text and the "copy HTML" did not have any statusBer Tip. Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2016-03-05 06:48:08 +00:00
// TODO: Remove when versions < 17 are not an option...
else {
if (!mUserData.isEmpty()) {
QString message = tr("[ ALERT ] - Map User data has been lost in saved map file. Re-save in a\n"
"format of at least 17 to preserve it before quitting!")
.arg(mSaveVersion);
appendErrorMsgWithNoLf(message, false);
mpHost->mTelnet.postMessage(message);
Fixup: correct some issues raised in testing * In dlgTrigger C'tor tweaked Qt Version check for inclusion of placeholder text - should be 5.3 not 5.2. * In source_editor_area.ui restore the full-widget background painting - which otherwise limited the background colour to the extent of the content not the widget and when reviewed was NOT wanted. * In dlgTriggerEditor::slot_cursorPositionChanged() rearrange "current position" details to a more acceptable order with line counts first. * Initialise Host::mTimerDebugOutputSuppressionInterval member so that the adjustment control in "Profile Preferences" comes up with a consistent value on first use. When testing it became clear that the behaviour when moving away from the zero "Show all" value would start acting on the most significant section ("Hours") rather than the more useful "Seconds". Added void dlgProfilePreferences::slot_timeValueChanged(QTime) private slot connect to the timeChanged(QTime) signal to handle things. Whilst fixing the above things I also became aware of and addressed: * When the Profile Preferences dialog is open the map format save control was not being initialised to the current setting but to the default 16 instead - this is confusing for someone who HAS changed the value and goes back to see it reset - even though it has not been until they close (and thus save) whatever the value. * Absence of tool-tips for Profile Preference Special Option mentioned above to cut down spam from short interval Timers and also the map save version override control. * There are already warning in place the first time that the Lua set{Map|Area}UserData(...) commands are used and the map format is not 17 but this is is now detected on map save. However as this can happen when the user closes Mudlet and they won't get displayed in time the other warnings are still useful - both of these can be removed in the future when the current format of 16 is not longer available. * Spotted a potential bug in that when saving rooms there is not a null room pointer check to skip the (hopefully) unlikely case of a QHash<int, TRoom*>TRoomDB:rooms value being null - this would cause a null pointer bug and thus a probable crash when straigt afterward that pointer would be dereferenced. * The Editor toolbar button to show/hide the search area also shows and hides the area where "Errors" {"popupArea"} are displayed within the Editor widget. Probably a long standing issue from the past evolution of the editor. * Spotted that the statusBar tip for the "copy HTML" context menu command for the TTextEdit class was being applied to the "copy" entry - so that the "copy" command got the wrong text and the "copy HTML" did not have any statusBer Tip. Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2016-03-05 06:48:08 +00:00
}
}
// End of TODO:
2013-03-22 12:47:58 +01:00
ofs << mpRoomDB->getAreaMap().size();
// serialize area table
QMapIterator<int, TArea*> itAreaList(mpRoomDB->getAreaMap());
Fixup: correct some issues raised in testing * In dlgTrigger C'tor tweaked Qt Version check for inclusion of placeholder text - should be 5.3 not 5.2. * In source_editor_area.ui restore the full-widget background painting - which otherwise limited the background colour to the extent of the content not the widget and when reviewed was NOT wanted. * In dlgTriggerEditor::slot_cursorPositionChanged() rearrange "current position" details to a more acceptable order with line counts first. * Initialise Host::mTimerDebugOutputSuppressionInterval member so that the adjustment control in "Profile Preferences" comes up with a consistent value on first use. When testing it became clear that the behaviour when moving away from the zero "Show all" value would start acting on the most significant section ("Hours") rather than the more useful "Seconds". Added void dlgProfilePreferences::slot_timeValueChanged(QTime) private slot connect to the timeChanged(QTime) signal to handle things. Whilst fixing the above things I also became aware of and addressed: * When the Profile Preferences dialog is open the map format save control was not being initialised to the current setting but to the default 16 instead - this is confusing for someone who HAS changed the value and goes back to see it reset - even though it has not been until they close (and thus save) whatever the value. * Absence of tool-tips for Profile Preference Special Option mentioned above to cut down spam from short interval Timers and also the map save version override control. * There are already warning in place the first time that the Lua set{Map|Area}UserData(...) commands are used and the map format is not 17 but this is is now detected on map save. However as this can happen when the user closes Mudlet and they won't get displayed in time the other warnings are still useful - both of these can be removed in the future when the current format of 16 is not longer available. * Spotted a potential bug in that when saving rooms there is not a null room pointer check to skip the (hopefully) unlikely case of a QHash<int, TRoom*>TRoomDB:rooms value being null - this would cause a null pointer bug and thus a probable crash when straigt afterward that pointer would be dereferenced. * The Editor toolbar button to show/hide the search area also shows and hides the area where "Errors" {"popupArea"} are displayed within the Editor widget. Probably a long standing issue from the past evolution of the editor. * Spotted that the statusBar tip for the "copy HTML" context menu command for the TTextEdit class was being applied to the "copy" entry - so that the "copy" command got the wrong text and the "copy HTML" did not have any statusBer Tip. Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2016-03-05 06:48:08 +00:00
QList<int> areasWithData; // TODO: Remove when versions < 17 are not an option
while (itAreaList.hasNext()) {
itAreaList.next();
int areaID = itAreaList.key();
TArea* pA = itAreaList.value();
ofs << areaID;
if (mSaveVersion >= 18) {
ofs << pA->rooms;
} else {
// Switched to a (faster) QSet<int> from a QList<int> in version 18
QList<int> _oldList = pA->rooms.toList();
ofs << _oldList;
}
ofs << pA->zLevels;
ofs << pA->exits;
ofs << pA->gridMode;
ofs << pA->max_x;
ofs << pA->max_y;
ofs << pA->max_z;
ofs << pA->min_x;
ofs << pA->min_y;
ofs << pA->min_z;
ofs << pA->span;
if (mSaveVersion >= 17) {
Enhance: 2D Map Room Selection, better big map performance + other mods In situations when we check whether a room in an area both for internal purposes and when rooms on a mapper is selected, using QSet instead of a QList is faster in performance for large numbers of entries in set. As it reworks the mapper code it also fixes issue where the multi-room selection widget overwrites map info display - the latter is re-sized and re-positioned (and regains a semi-transparent background which helped to show this working during debugging!) The former is now: dynamically resized to only take up enough vertical space to show the selected rooms; also displays the associate room names if there are any, expanding the widget as required; sorts the display either by room name or number and in either direction. The mouse wheel handler is modified so that using the scroll wheel ONLY scrolls the list within the widget - previously (by default) once the end in either direction was hit the related events would be passed up the widget chain where it would otherwise invoke the 2D mapper's zoom in/out code. In modifying the zoom in/out code I have replaced the (obsoleted in Qt5.x) QWheelEvent::delta() method to use the QWheelEvent::angleDelta() method, using only the Y-component the latter provides. If the Control modifier is active the zoom value is modified by an extra x10 factor which is useful when working with large maps as otherwise the zooming rate is "slow" at high values - ideally the control should be logarithmic or exponential or some other "non-linear" algorithm to work more uniformly over the range of practical use cases. The code to paint the map info text has been revised also to use the mMapInfoRect which was being defined but NOT used. The info text now reports whether the room name is for the player room {set via the Lua command centerview(roomId)} or is one that is selected by mouse dragging - and if more than one room is selected by that indicates the count of rooms in the selection. In the case of multiple rooms being selected the room that single room context menu operations will act upon is highlighted by the same style of yellow target used to show the custom exit line destination but is drawn in a different point in the code so that it is drawn over the rooms. Because of the change to the way that multiple rooms are selected routines that use that information had to be revised - in doing so it was possible to improve the usability/operation of: T2DMap::slot_movePosition() T2DMap::slot_setCharacter() T2DMap::slot_spread() T2DMap::slot_shrink() T2DMap::slot_lockRoom(): T2DMap::slot_unlockRoom(): This method, also resurrected here to the 2D mapper context menu, as it is also affected by the changes: T2DMap::slot_setPlayerLocation() There was a slot_setPlayerLocation code that set a global lua variable mRoomSet and moved the player to that room Id (introduced in commit-c25faf4e 2012-05-04 07:44:36 by Heiko) but the corresponding 2D Mapper context menu item that called it was commented out and thus removed from the menu in commit-93f65962 2012-12-29 01:16:28 also by Heiko without any explaination. Since that has not been used since then I have replaced it with a new Event: sysManualLocationSetEvent with a single numeric value which is the new (valid) room Id number - user scripts can capture this event if they want to know that the user has manually re-positioned the current player room in the 2D mapper. In passing: * Fixed Text font changing between docked and un-docked forms of the built-in map widget (when not incorporated into a console) - as it was not previously explicitly set it assumed the Application one whilst docked but the Qt System one when a free floating widget - and the two do not have to be the same. This fixes: https://bugs.launchpad.net/mudlet/+bug/1432841 . * Starts to fix https://bugs.launchpad.net/mudlet/+bug/1376511 by changing from use of obsolete QWheelEvent::delta() to QWheelEvent::angleDelta() in T2DMap::wheelEvent(...); will need duplicating in TTextEdit::wheelEvent(...) and GLWidget::wheelEvent(...) . * Adds the profile name to the Mapper dockable widget so that it's parentage can be determined when multiple profiles are active. Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2016-03-08 08:35:07 +00:00
ofs << pA->xmaxEbene;
ofs << pA->ymaxEbene;
ofs << pA->xminEbene;
ofs << pA->yminEbene;
} else { // Recreate the pointless z{min|max}Ebene items
Enhance: 2D Map Room Selection, better big map performance + other mods In situations when we check whether a room in an area both for internal purposes and when rooms on a mapper is selected, using QSet instead of a QList is faster in performance for large numbers of entries in set. As it reworks the mapper code it also fixes issue where the multi-room selection widget overwrites map info display - the latter is re-sized and re-positioned (and regains a semi-transparent background which helped to show this working during debugging!) The former is now: dynamically resized to only take up enough vertical space to show the selected rooms; also displays the associate room names if there are any, expanding the widget as required; sorts the display either by room name or number and in either direction. The mouse wheel handler is modified so that using the scroll wheel ONLY scrolls the list within the widget - previously (by default) once the end in either direction was hit the related events would be passed up the widget chain where it would otherwise invoke the 2D mapper's zoom in/out code. In modifying the zoom in/out code I have replaced the (obsoleted in Qt5.x) QWheelEvent::delta() method to use the QWheelEvent::angleDelta() method, using only the Y-component the latter provides. If the Control modifier is active the zoom value is modified by an extra x10 factor which is useful when working with large maps as otherwise the zooming rate is "slow" at high values - ideally the control should be logarithmic or exponential or some other "non-linear" algorithm to work more uniformly over the range of practical use cases. The code to paint the map info text has been revised also to use the mMapInfoRect which was being defined but NOT used. The info text now reports whether the room name is for the player room {set via the Lua command centerview(roomId)} or is one that is selected by mouse dragging - and if more than one room is selected by that indicates the count of rooms in the selection. In the case of multiple rooms being selected the room that single room context menu operations will act upon is highlighted by the same style of yellow target used to show the custom exit line destination but is drawn in a different point in the code so that it is drawn over the rooms. Because of the change to the way that multiple rooms are selected routines that use that information had to be revised - in doing so it was possible to improve the usability/operation of: T2DMap::slot_movePosition() T2DMap::slot_setCharacter() T2DMap::slot_spread() T2DMap::slot_shrink() T2DMap::slot_lockRoom(): T2DMap::slot_unlockRoom(): This method, also resurrected here to the 2D mapper context menu, as it is also affected by the changes: T2DMap::slot_setPlayerLocation() There was a slot_setPlayerLocation code that set a global lua variable mRoomSet and moved the player to that room Id (introduced in commit-c25faf4e 2012-05-04 07:44:36 by Heiko) but the corresponding 2D Mapper context menu item that called it was commented out and thus removed from the menu in commit-93f65962 2012-12-29 01:16:28 also by Heiko without any explaination. Since that has not been used since then I have replaced it with a new Event: sysManualLocationSetEvent with a single numeric value which is the new (valid) room Id number - user scripts can capture this event if they want to know that the user has manually re-positioned the current player room in the 2D mapper. In passing: * Fixed Text font changing between docked and un-docked forms of the built-in map widget (when not incorporated into a console) - as it was not previously explicitly set it assumed the Application one whilst docked but the Qt System one when a free floating widget - and the two do not have to be the same. This fixes: https://bugs.launchpad.net/mudlet/+bug/1432841 . * Starts to fix https://bugs.launchpad.net/mudlet/+bug/1376511 by changing from use of obsolete QWheelEvent::delta() to QWheelEvent::angleDelta() in T2DMap::wheelEvent(...); will need duplicating in TTextEdit::wheelEvent(...) and GLWidget::wheelEvent(...) . * Adds the profile name to the Mapper dockable widget so that it's parentage can be determined when multiple profiles are active. Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2016-03-08 08:35:07 +00:00
QMap<int, int> dummyMinMaxEbene;
QListIterator<int> itZ(pA->zLevels);
while (itZ.hasNext()) {
Enhance: 2D Map Room Selection, better big map performance + other mods In situations when we check whether a room in an area both for internal purposes and when rooms on a mapper is selected, using QSet instead of a QList is faster in performance for large numbers of entries in set. As it reworks the mapper code it also fixes issue where the multi-room selection widget overwrites map info display - the latter is re-sized and re-positioned (and regains a semi-transparent background which helped to show this working during debugging!) The former is now: dynamically resized to only take up enough vertical space to show the selected rooms; also displays the associate room names if there are any, expanding the widget as required; sorts the display either by room name or number and in either direction. The mouse wheel handler is modified so that using the scroll wheel ONLY scrolls the list within the widget - previously (by default) once the end in either direction was hit the related events would be passed up the widget chain where it would otherwise invoke the 2D mapper's zoom in/out code. In modifying the zoom in/out code I have replaced the (obsoleted in Qt5.x) QWheelEvent::delta() method to use the QWheelEvent::angleDelta() method, using only the Y-component the latter provides. If the Control modifier is active the zoom value is modified by an extra x10 factor which is useful when working with large maps as otherwise the zooming rate is "slow" at high values - ideally the control should be logarithmic or exponential or some other "non-linear" algorithm to work more uniformly over the range of practical use cases. The code to paint the map info text has been revised also to use the mMapInfoRect which was being defined but NOT used. The info text now reports whether the room name is for the player room {set via the Lua command centerview(roomId)} or is one that is selected by mouse dragging - and if more than one room is selected by that indicates the count of rooms in the selection. In the case of multiple rooms being selected the room that single room context menu operations will act upon is highlighted by the same style of yellow target used to show the custom exit line destination but is drawn in a different point in the code so that it is drawn over the rooms. Because of the change to the way that multiple rooms are selected routines that use that information had to be revised - in doing so it was possible to improve the usability/operation of: T2DMap::slot_movePosition() T2DMap::slot_setCharacter() T2DMap::slot_spread() T2DMap::slot_shrink() T2DMap::slot_lockRoom(): T2DMap::slot_unlockRoom(): This method, also resurrected here to the 2D mapper context menu, as it is also affected by the changes: T2DMap::slot_setPlayerLocation() There was a slot_setPlayerLocation code that set a global lua variable mRoomSet and moved the player to that room Id (introduced in commit-c25faf4e 2012-05-04 07:44:36 by Heiko) but the corresponding 2D Mapper context menu item that called it was commented out and thus removed from the menu in commit-93f65962 2012-12-29 01:16:28 also by Heiko without any explaination. Since that has not been used since then I have replaced it with a new Event: sysManualLocationSetEvent with a single numeric value which is the new (valid) room Id number - user scripts can capture this event if they want to know that the user has manually re-positioned the current player room in the 2D mapper. In passing: * Fixed Text font changing between docked and un-docked forms of the built-in map widget (when not incorporated into a console) - as it was not previously explicitly set it assumed the Application one whilst docked but the Qt System one when a free floating widget - and the two do not have to be the same. This fixes: https://bugs.launchpad.net/mudlet/+bug/1432841 . * Starts to fix https://bugs.launchpad.net/mudlet/+bug/1376511 by changing from use of obsolete QWheelEvent::delta() to QWheelEvent::angleDelta() in T2DMap::wheelEvent(...); will need duplicating in TTextEdit::wheelEvent(...) and GLWidget::wheelEvent(...) . * Adds the profile name to the Mapper dockable widget so that it's parentage can be determined when multiple profiles are active. Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2016-03-08 08:35:07 +00:00
int dummyEbenValue = itZ.next();
dummyMinMaxEbene.insert(dummyEbenValue, dummyEbenValue);
Enhance: 2D Map Room Selection, better big map performance + other mods In situations when we check whether a room in an area both for internal purposes and when rooms on a mapper is selected, using QSet instead of a QList is faster in performance for large numbers of entries in set. As it reworks the mapper code it also fixes issue where the multi-room selection widget overwrites map info display - the latter is re-sized and re-positioned (and regains a semi-transparent background which helped to show this working during debugging!) The former is now: dynamically resized to only take up enough vertical space to show the selected rooms; also displays the associate room names if there are any, expanding the widget as required; sorts the display either by room name or number and in either direction. The mouse wheel handler is modified so that using the scroll wheel ONLY scrolls the list within the widget - previously (by default) once the end in either direction was hit the related events would be passed up the widget chain where it would otherwise invoke the 2D mapper's zoom in/out code. In modifying the zoom in/out code I have replaced the (obsoleted in Qt5.x) QWheelEvent::delta() method to use the QWheelEvent::angleDelta() method, using only the Y-component the latter provides. If the Control modifier is active the zoom value is modified by an extra x10 factor which is useful when working with large maps as otherwise the zooming rate is "slow" at high values - ideally the control should be logarithmic or exponential or some other "non-linear" algorithm to work more uniformly over the range of practical use cases. The code to paint the map info text has been revised also to use the mMapInfoRect which was being defined but NOT used. The info text now reports whether the room name is for the player room {set via the Lua command centerview(roomId)} or is one that is selected by mouse dragging - and if more than one room is selected by that indicates the count of rooms in the selection. In the case of multiple rooms being selected the room that single room context menu operations will act upon is highlighted by the same style of yellow target used to show the custom exit line destination but is drawn in a different point in the code so that it is drawn over the rooms. Because of the change to the way that multiple rooms are selected routines that use that information had to be revised - in doing so it was possible to improve the usability/operation of: T2DMap::slot_movePosition() T2DMap::slot_setCharacter() T2DMap::slot_spread() T2DMap::slot_shrink() T2DMap::slot_lockRoom(): T2DMap::slot_unlockRoom(): This method, also resurrected here to the 2D mapper context menu, as it is also affected by the changes: T2DMap::slot_setPlayerLocation() There was a slot_setPlayerLocation code that set a global lua variable mRoomSet and moved the player to that room Id (introduced in commit-c25faf4e 2012-05-04 07:44:36 by Heiko) but the corresponding 2D Mapper context menu item that called it was commented out and thus removed from the menu in commit-93f65962 2012-12-29 01:16:28 also by Heiko without any explaination. Since that has not been used since then I have replaced it with a new Event: sysManualLocationSetEvent with a single numeric value which is the new (valid) room Id number - user scripts can capture this event if they want to know that the user has manually re-positioned the current player room in the 2D mapper. In passing: * Fixed Text font changing between docked and un-docked forms of the built-in map widget (when not incorporated into a console) - as it was not previously explicitly set it assumed the Application one whilst docked but the Qt System one when a free floating widget - and the two do not have to be the same. This fixes: https://bugs.launchpad.net/mudlet/+bug/1432841 . * Starts to fix https://bugs.launchpad.net/mudlet/+bug/1376511 by changing from use of obsolete QWheelEvent::delta() to QWheelEvent::angleDelta() in T2DMap::wheelEvent(...); will need duplicating in TTextEdit::wheelEvent(...) and GLWidget::wheelEvent(...) . * Adds the profile name to the Mapper dockable widget so that it's parentage can be determined when multiple profiles are active. Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2016-03-08 08:35:07 +00:00
}
ofs << pA->xmaxEbene;
ofs << pA->ymaxEbene;
ofs << dummyMinMaxEbene;
ofs << pA->xminEbene;
ofs << pA->yminEbene;
ofs << dummyMinMaxEbene;
}
ofs << pA->pos;
ofs << pA->isZone;
ofs << pA->zoneAreaRef;
if (mSaveVersion >= 17) {
Enhance: add Area & Map user data structures & Lua script access commands Whilst working on the XML importer for Map files I found that I wanted some where to store the data from attributes for tags that we don't use in Mudlet directly. For room related details I could use the TRoom::userData member but then I realised that there is nothing corresponding to Areas or for the Map overall. This separate commit provides these and the lua commands to interact with them - with functionality the same as the Room based one. Of course, as there is only ONE map there is no argument needed to select an instance for those commands. Of all the "room" user data commands replicated for "area" and "map" the only one NOT so done are get????UserDataKeys() as this is a bit pointless with a getAll????UserData() one from which the keys could be extracted from the returned table {???? being "Area" or "Map"}. Added to TLuaInterpreter class to provide following user script commands: searchAreaUserData((string)<key>[, (string)<value>]) setAreaUserData((number)<area Id>, (string)<key>, (string)<value>) clearAreaUserData((number)<area Id>) clearAreaUserDataItem((number)<area Id>, (string)<key>) getAreaUserData((number)<area Id>, (string)<key>) getAllAreaUserData((number)<area Id>) setMapUserData((string)<key>, (string)<value>) clearMapUserData((string)<key>) clearMapUserDataItem() getMapUserData((string)<key>) getAllMapUserData() Refactored TMap::serialize() to allow saving in different map file formats as defined by the constants TMap::mDefaultVersion, mMinVersion and mMaxVersion - if either of the last pair are less than or more than the first value respectively then a control on the "Special Options" tab of the profile preferences dialog will be enabled - the state of each value that is allowed is clearly indicated and it is defaulted appropriately. At present: TMap::mDefaultVersion is 16 (replaces #define CURRENT_MAP_VERSION) TMap::mMinVersion is also 16 TMap::mMaxVersion is 17 This means that the new user data areas will only persist (be saved) if that control is manually adjusted to 17 FOR EACH SESSION in this development version. When we get to a release version mDefaultVersion should be upped to 17 so that the release version uses the new format but can be manually downgraded to current (16) for those who want to share a map with users who have not upgraded - with the less of those new user data items - such users can do this by opening the profile preferences, downing this setting THEN using the SAVE MAP button and then restoring to the default value and SAVING AGAIN to a different name in the recommend format. Also renamed TMap::version to TMap::mVersion... ========================================================================== As this code requires the revision to the map file format that is coded for but only enabled manually the setter commands setAreaUserData(...) and setMapUserData(...) will both emit a warning message that the data written will not CURRENTLY be saved with the map the FIRST (and only the first) time they are used when the preference control has not been manually adjusted. ========================================================================== Also: Tweaked a recent, previous merged commit that set an optional minimum time for a Timer NOT to display it's contents every time it fires in debug output screen in value: Host::mTimerDebugOutputSuppressionInterval so that the QTimeEdit that controls it defaults to adjusting the "Seconds" time field rather than the default "Hours" one as that is the one that is most likely the one the user might wist to use. Also: The control this commit adds to the Profile Preferences dialog makes use of the QComboBox::currentData() method that was introduced in Qt5.2 - the minimum Qt library requirement in the qmake project file was revised to accomodate this - if builders wish to use a Qt5.x before this they will need to manually provide extra code to allocate an integer value from the range of values wanted/offered. Also: whilst cross-checking for the cmake project file I found the top level one was missing from the qmake project file - so have added it to that. HOWEVER I HAVE NOT FOUND A WAY TO REQUIRE THE CMAKE SYSTEM TO REQUIRE QT5.2 AS A MINIMUM WHICH THIS COMMIT REQUIRES. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> Conflicts: src/src.pro
2015-12-30 13:42:41 +00:00
ofs << pA->mUserData;
}
Fixup: correct some issues raised in testing * In dlgTrigger C'tor tweaked Qt Version check for inclusion of placeholder text - should be 5.3 not 5.2. * In source_editor_area.ui restore the full-widget background painting - which otherwise limited the background colour to the extent of the content not the widget and when reviewed was NOT wanted. * In dlgTriggerEditor::slot_cursorPositionChanged() rearrange "current position" details to a more acceptable order with line counts first. * Initialise Host::mTimerDebugOutputSuppressionInterval member so that the adjustment control in "Profile Preferences" comes up with a consistent value on first use. When testing it became clear that the behaviour when moving away from the zero "Show all" value would start acting on the most significant section ("Hours") rather than the more useful "Seconds". Added void dlgProfilePreferences::slot_timeValueChanged(QTime) private slot connect to the timeChanged(QTime) signal to handle things. Whilst fixing the above things I also became aware of and addressed: * When the Profile Preferences dialog is open the map format save control was not being initialised to the current setting but to the default 16 instead - this is confusing for someone who HAS changed the value and goes back to see it reset - even though it has not been until they close (and thus save) whatever the value. * Absence of tool-tips for Profile Preference Special Option mentioned above to cut down spam from short interval Timers and also the map save version override control. * There are already warning in place the first time that the Lua set{Map|Area}UserData(...) commands are used and the map format is not 17 but this is is now detected on map save. However as this can happen when the user closes Mudlet and they won't get displayed in time the other warnings are still useful - both of these can be removed in the future when the current format of 16 is not longer available. * Spotted a potential bug in that when saving rooms there is not a null room pointer check to skip the (hopefully) unlikely case of a QHash<int, TRoom*>TRoomDB:rooms value being null - this would cause a null pointer bug and thus a probable crash when straigt afterward that pointer would be dereferenced. * The Editor toolbar button to show/hide the search area also shows and hides the area where "Errors" {"popupArea"} are displayed within the Editor widget. Probably a long standing issue from the past evolution of the editor. * Spotted that the statusBar tip for the "copy HTML" context menu command for the TTextEdit class was being applied to the "copy" entry - so that the "copy" command got the wrong text and the "copy HTML" did not have any statusBer Tip. Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2016-03-05 06:48:08 +00:00
// TODO: Remove when versions < 17 are not an option...
else {
if (!pA->mUserData.isEmpty()) {
areasWithData.append(areaID);
Fixup: correct some issues raised in testing * In dlgTrigger C'tor tweaked Qt Version check for inclusion of placeholder text - should be 5.3 not 5.2. * In source_editor_area.ui restore the full-widget background painting - which otherwise limited the background colour to the extent of the content not the widget and when reviewed was NOT wanted. * In dlgTriggerEditor::slot_cursorPositionChanged() rearrange "current position" details to a more acceptable order with line counts first. * Initialise Host::mTimerDebugOutputSuppressionInterval member so that the adjustment control in "Profile Preferences" comes up with a consistent value on first use. When testing it became clear that the behaviour when moving away from the zero "Show all" value would start acting on the most significant section ("Hours") rather than the more useful "Seconds". Added void dlgProfilePreferences::slot_timeValueChanged(QTime) private slot connect to the timeChanged(QTime) signal to handle things. Whilst fixing the above things I also became aware of and addressed: * When the Profile Preferences dialog is open the map format save control was not being initialised to the current setting but to the default 16 instead - this is confusing for someone who HAS changed the value and goes back to see it reset - even though it has not been until they close (and thus save) whatever the value. * Absence of tool-tips for Profile Preference Special Option mentioned above to cut down spam from short interval Timers and also the map save version override control. * There are already warning in place the first time that the Lua set{Map|Area}UserData(...) commands are used and the map format is not 17 but this is is now detected on map save. However as this can happen when the user closes Mudlet and they won't get displayed in time the other warnings are still useful - both of these can be removed in the future when the current format of 16 is not longer available. * Spotted a potential bug in that when saving rooms there is not a null room pointer check to skip the (hopefully) unlikely case of a QHash<int, TRoom*>TRoomDB:rooms value being null - this would cause a null pointer bug and thus a probable crash when straigt afterward that pointer would be dereferenced. * The Editor toolbar button to show/hide the search area also shows and hides the area where "Errors" {"popupArea"} are displayed within the Editor widget. Probably a long standing issue from the past evolution of the editor. * Spotted that the statusBar tip for the "copy HTML" context menu command for the TTextEdit class was being applied to the "copy" entry - so that the "copy" command got the wrong text and the "copy HTML" did not have any statusBer Tip. Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2016-03-05 06:48:08 +00:00
}
}
// End of TODO:
}
Fixup: correct some issues raised in testing * In dlgTrigger C'tor tweaked Qt Version check for inclusion of placeholder text - should be 5.3 not 5.2. * In source_editor_area.ui restore the full-widget background painting - which otherwise limited the background colour to the extent of the content not the widget and when reviewed was NOT wanted. * In dlgTriggerEditor::slot_cursorPositionChanged() rearrange "current position" details to a more acceptable order with line counts first. * Initialise Host::mTimerDebugOutputSuppressionInterval member so that the adjustment control in "Profile Preferences" comes up with a consistent value on first use. When testing it became clear that the behaviour when moving away from the zero "Show all" value would start acting on the most significant section ("Hours") rather than the more useful "Seconds". Added void dlgProfilePreferences::slot_timeValueChanged(QTime) private slot connect to the timeChanged(QTime) signal to handle things. Whilst fixing the above things I also became aware of and addressed: * When the Profile Preferences dialog is open the map format save control was not being initialised to the current setting but to the default 16 instead - this is confusing for someone who HAS changed the value and goes back to see it reset - even though it has not been until they close (and thus save) whatever the value. * Absence of tool-tips for Profile Preference Special Option mentioned above to cut down spam from short interval Timers and also the map save version override control. * There are already warning in place the first time that the Lua set{Map|Area}UserData(...) commands are used and the map format is not 17 but this is is now detected on map save. However as this can happen when the user closes Mudlet and they won't get displayed in time the other warnings are still useful - both of these can be removed in the future when the current format of 16 is not longer available. * Spotted a potential bug in that when saving rooms there is not a null room pointer check to skip the (hopefully) unlikely case of a QHash<int, TRoom*>TRoomDB:rooms value being null - this would cause a null pointer bug and thus a probable crash when straigt afterward that pointer would be dereferenced. * The Editor toolbar button to show/hide the search area also shows and hides the area where "Errors" {"popupArea"} are displayed within the Editor widget. Probably a long standing issue from the past evolution of the editor. * Spotted that the statusBar tip for the "copy HTML" context menu command for the TTextEdit class was being applied to the "copy" entry - so that the "copy" command got the wrong text and the "copy HTML" did not have any statusBer Tip. Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2016-03-05 06:48:08 +00:00
// TODO: Remove when versions < 17 are not an option...
if (!areasWithData.isEmpty()) {
if (areasWithData.size() > 1) {
std::sort(areasWithData.begin(), areasWithData.end());
Fixup: correct some issues raised in testing * In dlgTrigger C'tor tweaked Qt Version check for inclusion of placeholder text - should be 5.3 not 5.2. * In source_editor_area.ui restore the full-widget background painting - which otherwise limited the background colour to the extent of the content not the widget and when reviewed was NOT wanted. * In dlgTriggerEditor::slot_cursorPositionChanged() rearrange "current position" details to a more acceptable order with line counts first. * Initialise Host::mTimerDebugOutputSuppressionInterval member so that the adjustment control in "Profile Preferences" comes up with a consistent value on first use. When testing it became clear that the behaviour when moving away from the zero "Show all" value would start acting on the most significant section ("Hours") rather than the more useful "Seconds". Added void dlgProfilePreferences::slot_timeValueChanged(QTime) private slot connect to the timeChanged(QTime) signal to handle things. Whilst fixing the above things I also became aware of and addressed: * When the Profile Preferences dialog is open the map format save control was not being initialised to the current setting but to the default 16 instead - this is confusing for someone who HAS changed the value and goes back to see it reset - even though it has not been until they close (and thus save) whatever the value. * Absence of tool-tips for Profile Preference Special Option mentioned above to cut down spam from short interval Timers and also the map save version override control. * There are already warning in place the first time that the Lua set{Map|Area}UserData(...) commands are used and the map format is not 17 but this is is now detected on map save. However as this can happen when the user closes Mudlet and they won't get displayed in time the other warnings are still useful - both of these can be removed in the future when the current format of 16 is not longer available. * Spotted a potential bug in that when saving rooms there is not a null room pointer check to skip the (hopefully) unlikely case of a QHash<int, TRoom*>TRoomDB:rooms value being null - this would cause a null pointer bug and thus a probable crash when straigt afterward that pointer would be dereferenced. * The Editor toolbar button to show/hide the search area also shows and hides the area where "Errors" {"popupArea"} are displayed within the Editor widget. Probably a long standing issue from the past evolution of the editor. * Spotted that the statusBar tip for the "copy HTML" context menu command for the TTextEdit class was being applied to the "copy" entry - so that the "copy" command got the wrong text and the "copy HTML" did not have any statusBer Tip. Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2016-03-05 06:48:08 +00:00
}
QStringList areaIds;
do {
Revision: route most of map auditing messages to errors.txt file As the amount of messages produced by the new/improve map auditing/clean-up code can be large for old map files this commit causes them to be sent to a profile specific file that is already opened by the Host class but has not been used for some time. An option (a check-box) on the "map" tab of the "profile preferences" dialog controls whether the equivalent information is also shown on the profile's main console as in the past. If the option (a global one) which is saved between sessions/runs is NOT enabled then an advisory is sent to the console advising the user to review the file contents if a "significant" issue was detected. If it is enabled a similar message advising that the information has also been saved. In either case, as the file is appended to, and not rewritten each time, the message includes details of the first line of the report so that it can be located in the file. One difference between the on-screen and the file versions of the information is that the former puts up the issues as they are detected whereas the latter groups the information by subject, first the general overall issues, then the area ones, in order of the areas' id numbers and then the room ones, in room order. Following earlier discussions in these Pull Request I have attempted to edit all uses of the word "Id" in user visible places to be "id" instead. This threw up some other messages with issues in several files that I have tweaked here as well! Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2016-05-03 04:58:31 +01:00
int areaId = areasWithData.takeFirst();
areaIds.append(QString::number(areaId));
appendAreaErrorMsg(areaId,
tr("[ ALERT ] - User data for this area has been lost in saved map file. Re-save in a\n"
"format of at least 17 to preserve it before quitting!\n"));
} while (!areasWithData.isEmpty());
QString message = tr("[ ALERT ] - Area User data has been lost in saved map file. Re-save in a\n"
"format of at least 17 to preserve it before quitting!\n"
"Areas id affected: %1.")
2017-12-29 16:37:11 +01:00
.arg(areaIds.join(tr(", "))); // Translatable in case list separators are locale dependant!
mpHost->mTelnet.postMessage(message);
Fixup: correct some issues raised in testing * In dlgTrigger C'tor tweaked Qt Version check for inclusion of placeholder text - should be 5.3 not 5.2. * In source_editor_area.ui restore the full-widget background painting - which otherwise limited the background colour to the extent of the content not the widget and when reviewed was NOT wanted. * In dlgTriggerEditor::slot_cursorPositionChanged() rearrange "current position" details to a more acceptable order with line counts first. * Initialise Host::mTimerDebugOutputSuppressionInterval member so that the adjustment control in "Profile Preferences" comes up with a consistent value on first use. When testing it became clear that the behaviour when moving away from the zero "Show all" value would start acting on the most significant section ("Hours") rather than the more useful "Seconds". Added void dlgProfilePreferences::slot_timeValueChanged(QTime) private slot connect to the timeChanged(QTime) signal to handle things. Whilst fixing the above things I also became aware of and addressed: * When the Profile Preferences dialog is open the map format save control was not being initialised to the current setting but to the default 16 instead - this is confusing for someone who HAS changed the value and goes back to see it reset - even though it has not been until they close (and thus save) whatever the value. * Absence of tool-tips for Profile Preference Special Option mentioned above to cut down spam from short interval Timers and also the map save version override control. * There are already warning in place the first time that the Lua set{Map|Area}UserData(...) commands are used and the map format is not 17 but this is is now detected on map save. However as this can happen when the user closes Mudlet and they won't get displayed in time the other warnings are still useful - both of these can be removed in the future when the current format of 16 is not longer available. * Spotted a potential bug in that when saving rooms there is not a null room pointer check to skip the (hopefully) unlikely case of a QHash<int, TRoom*>TRoomDB:rooms value being null - this would cause a null pointer bug and thus a probable crash when straigt afterward that pointer would be dereferenced. * The Editor toolbar button to show/hide the search area also shows and hides the area where "Errors" {"popupArea"} are displayed within the Editor widget. Probably a long standing issue from the past evolution of the editor. * Spotted that the statusBar tip for the "copy HTML" context menu command for the TTextEdit class was being applied to the "copy" entry - so that the "copy" command got the wrong text and the "copy HTML" did not have any statusBer Tip. Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2016-03-05 06:48:08 +00:00
}
// End of TODO
if (mSaveVersion >= 18) {
// Revised in version 18 to store mRoomId as a per profile case so that
// sharing/copying between profiles respects each profile's player
// location
ofs << mRoomIdHash;
} else {
ofs << mRoomIdHash.value(mpHost->getName());
}
Enhance: add Area & Map user data structures & Lua script access commands Whilst working on the XML importer for Map files I found that I wanted some where to store the data from attributes for tags that we don't use in Mudlet directly. For room related details I could use the TRoom::userData member but then I realised that there is nothing corresponding to Areas or for the Map overall. This separate commit provides these and the lua commands to interact with them - with functionality the same as the Room based one. Of course, as there is only ONE map there is no argument needed to select an instance for those commands. Of all the "room" user data commands replicated for "area" and "map" the only one NOT so done are get????UserDataKeys() as this is a bit pointless with a getAll????UserData() one from which the keys could be extracted from the returned table {???? being "Area" or "Map"}. Added to TLuaInterpreter class to provide following user script commands: searchAreaUserData((string)<key>[, (string)<value>]) setAreaUserData((number)<area Id>, (string)<key>, (string)<value>) clearAreaUserData((number)<area Id>) clearAreaUserDataItem((number)<area Id>, (string)<key>) getAreaUserData((number)<area Id>, (string)<key>) getAllAreaUserData((number)<area Id>) setMapUserData((string)<key>, (string)<value>) clearMapUserData((string)<key>) clearMapUserDataItem() getMapUserData((string)<key>) getAllMapUserData() Refactored TMap::serialize() to allow saving in different map file formats as defined by the constants TMap::mDefaultVersion, mMinVersion and mMaxVersion - if either of the last pair are less than or more than the first value respectively then a control on the "Special Options" tab of the profile preferences dialog will be enabled - the state of each value that is allowed is clearly indicated and it is defaulted appropriately. At present: TMap::mDefaultVersion is 16 (replaces #define CURRENT_MAP_VERSION) TMap::mMinVersion is also 16 TMap::mMaxVersion is 17 This means that the new user data areas will only persist (be saved) if that control is manually adjusted to 17 FOR EACH SESSION in this development version. When we get to a release version mDefaultVersion should be upped to 17 so that the release version uses the new format but can be manually downgraded to current (16) for those who want to share a map with users who have not upgraded - with the less of those new user data items - such users can do this by opening the profile preferences, downing this setting THEN using the SAVE MAP button and then restoring to the default value and SAVING AGAIN to a different name in the recommend format. Also renamed TMap::version to TMap::mVersion... ========================================================================== As this code requires the revision to the map file format that is coded for but only enabled manually the setter commands setAreaUserData(...) and setMapUserData(...) will both emit a warning message that the data written will not CURRENTLY be saved with the map the FIRST (and only the first) time they are used when the preference control has not been manually adjusted. ========================================================================== Also: Tweaked a recent, previous merged commit that set an optional minimum time for a Timer NOT to display it's contents every time it fires in debug output screen in value: Host::mTimerDebugOutputSuppressionInterval so that the QTimeEdit that controls it defaults to adjusting the "Seconds" time field rather than the default "Hours" one as that is the one that is most likely the one the user might wist to use. Also: The control this commit adds to the Profile Preferences dialog makes use of the QComboBox::currentData() method that was introduced in Qt5.2 - the minimum Qt library requirement in the qmake project file was revised to accomodate this - if builders wish to use a Qt5.x before this they will need to manually provide extra code to allocate an integer value from the range of values wanted/offered. Also: whilst cross-checking for the cmake project file I found the top level one was missing from the qmake project file - so have added it to that. HOWEVER I HAVE NOT FOUND A WAY TO REQUIRE THE CMAKE SYSTEM TO REQUIRE QT5.2 AS A MINIMUM WHICH THIS COMMIT REQUIRES. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> Conflicts: src/src.pro
2015-12-30 13:42:41 +00:00
2011-06-26 23:26:24 +02:00
ofs << mapLabels.size(); //anzahl der areas
QMapIterator<int, QMap<int, TMapLabel>> itL1(mapLabels);
while (itL1.hasNext()) {
2011-06-26 23:26:24 +02:00
itL1.next();
int i = itL1.key();
ofs << itL1.value().size(); //anzahl der labels pro area
ofs << itL1.key(); //area id
2011-06-26 23:26:24 +02:00
QMapIterator<int, TMapLabel> itL2(mapLabels[i]);
while (itL2.hasNext()) {
2011-06-26 23:26:24 +02:00
itL2.next();
ofs << itL2.key(); //label ID
2011-06-26 23:26:24 +02:00
TMapLabel label = itL2.value();
ofs << label.pos;
ofs << label.pointer;
ofs << label.size;
ofs << label.text;
ofs << label.fgColor;
ofs << label.bgColor;
ofs << label.pix;
2012-12-29 02:16:28 +01:00
ofs << label.noScaling;
ofs << label.showOnTop;
2011-06-26 23:26:24 +02:00
}
}
QHashIterator<int, TRoom*> it(mpRoomDB->getRoomMap());
while (it.hasNext()) {
2010-08-25 00:41:43 +02:00
it.next();
TRoom* pR = it.value();
if (!pR) {
qDebug() << "TMap::serialize(...) skipping a room with a NULL TRoom pointer:" << it.key();
Fixup: correct some issues raised in testing * In dlgTrigger C'tor tweaked Qt Version check for inclusion of placeholder text - should be 5.3 not 5.2. * In source_editor_area.ui restore the full-widget background painting - which otherwise limited the background colour to the extent of the content not the widget and when reviewed was NOT wanted. * In dlgTriggerEditor::slot_cursorPositionChanged() rearrange "current position" details to a more acceptable order with line counts first. * Initialise Host::mTimerDebugOutputSuppressionInterval member so that the adjustment control in "Profile Preferences" comes up with a consistent value on first use. When testing it became clear that the behaviour when moving away from the zero "Show all" value would start acting on the most significant section ("Hours") rather than the more useful "Seconds". Added void dlgProfilePreferences::slot_timeValueChanged(QTime) private slot connect to the timeChanged(QTime) signal to handle things. Whilst fixing the above things I also became aware of and addressed: * When the Profile Preferences dialog is open the map format save control was not being initialised to the current setting but to the default 16 instead - this is confusing for someone who HAS changed the value and goes back to see it reset - even though it has not been until they close (and thus save) whatever the value. * Absence of tool-tips for Profile Preference Special Option mentioned above to cut down spam from short interval Timers and also the map save version override control. * There are already warning in place the first time that the Lua set{Map|Area}UserData(...) commands are used and the map format is not 17 but this is is now detected on map save. However as this can happen when the user closes Mudlet and they won't get displayed in time the other warnings are still useful - both of these can be removed in the future when the current format of 16 is not longer available. * Spotted a potential bug in that when saving rooms there is not a null room pointer check to skip the (hopefully) unlikely case of a QHash<int, TRoom*>TRoomDB:rooms value being null - this would cause a null pointer bug and thus a probable crash when straigt afterward that pointer would be dereferenced. * The Editor toolbar button to show/hide the search area also shows and hides the area where "Errors" {"popupArea"} are displayed within the Editor widget. Probably a long standing issue from the past evolution of the editor. * Spotted that the statusBar tip for the "copy HTML" context menu command for the TTextEdit class was being applied to the "copy" entry - so that the "copy" command got the wrong text and the "copy HTML" did not have any statusBer Tip. Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2016-03-05 06:48:08 +00:00
continue;
}
ofs << pR->getId();
Enhance: add ability to set any glyph as a room symbol (#1543) This is a squashed down commit containing several commits with messages - this is the edited combination of all the messages: As well as being able to use any grapheme it is possible to use a short word as well as anything printable from any of the Unicode Multiple Planes; although the former will become smaller to fit within both the square and round room shapes on the 2D mapper. Adds controls to the profile preference to set the (preferred) font to use to set the room symbols from and a checkbox to only use that font. Additionally a sub-dialog can be brought up which lists the details of all the different symbols on the map - showing the Unicode codepoint(s) for each and showing how they would be rendered if only the selected font is used and if any font is permitted, along with a count of the usages and the rooms that use each one... A status icon is also displayed showing whether the symbol can be rendered entirely with the selected font (green tick), only by using glyphs from other fonts (yellow ! warning) or not with the current fonts on the system (red/white cross). This allows a user to make a sensible selection of a font to use or whether they will have a problem (and a replacement by the replacement character '�') for any symbols. Updates Lua setRoomChar and getRoomChar to handle the wider range of things that can be used. getRoomChar NOW allows for an existing character to be cleared with an empty string or a space as the char attribute. The map format version has been incremented to allow the data needed to be saved directly into the binary file format but failback code is in place that means that this feature can be carried in map and room user data instead for map format versions down to 17 - the current default is 18 and there is limited support to fail gracefully down to the 16 that Mudlet 2.1 uses (all the room letter markings that are not supported will become '?', and the font data will be lost, but the correct room character data will still be in the room user data.) Following review: * I replaced some colour specifications (white and transparent) with Qt constants. * Use the same inline function flushSymbolPixmapCache() to clear the map symbol pixmap cache in all places where it might be useful. * Simplify a couple of places where an if(...) {...} else {...} can be replaced with the (...) ? (...) : (...) operator. * Limit the number of room numbers displayed for each symbol in the new widget - to avoid complications where there are huge numbers of rooms using a symbol. * Replace a use of QTableWidget::clearContents() with QTableWidgets::setRowCount(0) as I was getting some odd, deep in the Qt internal library issues {Fatal Seg. Faults!} with the former, which I suspect, but could not prove, might have been a re-entrancy issue caused by the method containing it being called indirectly by an asynchronous SIGNAL/SLOT originating in the value change from the map symbol font selection QFontComboBox... Revised to NOT do scaling when drawing room symbols from cache: the previous QPainter::drawPixmap(...) performed a scaling operation to make the symbol pixmap fit the specified rectangle. This is the cause behind the poor rendering of text characters as the scaling undoes the benefits of anti-aliasing and takes time to do. This should be faster now because the pixmaps are generated at the size/resolution they are needed (though they do have to be thrown away and regenerated if the zoom or other sizing factors change) - they do however look better to me! Also: * merged (int) TRoom::xzoom and TRoom::yzoom into TRoom::xyzoom. * added the symbol scaling "fudge-factor" to the "Special Options" tab of the "Profile preferences" dialog - it may be helpful to artificially over-size (> 1.00) or under-size (< 1.00) the symbols in some situations. * uses the word symbol rather than just glyph/grapheme in some texts. Also modified 2D mapper "Symbol" tooltip to observe that more than one letter/symbol can be used (although they will be drawn smaller so that they still fit). Add tool-tips to profile preferences dialog for font controls (except for "fudge factor" control (with range x0.50 to x2.00 for scaling of symbol to test rectangle used to fit it into the room shape)... I have consistently mispelled chosen as choosen but I have fixed that now...! Also added tooltips to map glyph usage table/widget. WorkAround: try to force a specific US mirror for zziplib on AppVeyor CI AppVeyor is based in Vancouver, Canada so the nearest SF Mirror is in the US so this commit forces the use of that mirror for that library for the CI build process as an attempt to get around the repeated, intermittent failures to get that library from SourceForge (it is now the only item that needs to be downloaded from there for such builds)... Also adds another CI file that was not mentioned before in the qmake project file and thus did not show up in the Qt IDE. Following extensive discussions it has been made clear that introducing replacements for the lua [gs]etRoomChar(...) is not going to happen. Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2018-03-28 14:06:12 +01:00
if (mSaveVersion <= 19) {
if (!pR->mSymbol.isEmpty()) {
pR->userData.insert(QLatin1String("system.fallback_symbol"), pR->mSymbol);
}
}
2013-03-22 12:47:58 +01:00
ofs << pR->getArea();
ofs << pR->x;
ofs << pR->y;
ofs << pR->z;
ofs << pR->getNorth();
ofs << pR->getNortheast();
ofs << pR->getEast();
ofs << pR->getSoutheast();
ofs << pR->getSouth();
ofs << pR->getSouthwest();
ofs << pR->getWest();
ofs << pR->getNorthwest();
ofs << pR->getUp();
ofs << pR->getDown();
ofs << pR->getIn();
ofs << pR->getOut();
ofs << pR->environment;
2013-05-26 11:47:15 +02:00
ofs << pR->getWeight();
2013-03-22 12:47:58 +01:00
ofs << pR->name;
ofs << pR->isLocked;
ofs << pR->getOtherMap();
Enhance: add ability to set any glyph as a room symbol (#1543) This is a squashed down commit containing several commits with messages - this is the edited combination of all the messages: As well as being able to use any grapheme it is possible to use a short word as well as anything printable from any of the Unicode Multiple Planes; although the former will become smaller to fit within both the square and round room shapes on the 2D mapper. Adds controls to the profile preference to set the (preferred) font to use to set the room symbols from and a checkbox to only use that font. Additionally a sub-dialog can be brought up which lists the details of all the different symbols on the map - showing the Unicode codepoint(s) for each and showing how they would be rendered if only the selected font is used and if any font is permitted, along with a count of the usages and the rooms that use each one... A status icon is also displayed showing whether the symbol can be rendered entirely with the selected font (green tick), only by using glyphs from other fonts (yellow ! warning) or not with the current fonts on the system (red/white cross). This allows a user to make a sensible selection of a font to use or whether they will have a problem (and a replacement by the replacement character '�') for any symbols. Updates Lua setRoomChar and getRoomChar to handle the wider range of things that can be used. getRoomChar NOW allows for an existing character to be cleared with an empty string or a space as the char attribute. The map format version has been incremented to allow the data needed to be saved directly into the binary file format but failback code is in place that means that this feature can be carried in map and room user data instead for map format versions down to 17 - the current default is 18 and there is limited support to fail gracefully down to the 16 that Mudlet 2.1 uses (all the room letter markings that are not supported will become '?', and the font data will be lost, but the correct room character data will still be in the room user data.) Following review: * I replaced some colour specifications (white and transparent) with Qt constants. * Use the same inline function flushSymbolPixmapCache() to clear the map symbol pixmap cache in all places where it might be useful. * Simplify a couple of places where an if(...) {...} else {...} can be replaced with the (...) ? (...) : (...) operator. * Limit the number of room numbers displayed for each symbol in the new widget - to avoid complications where there are huge numbers of rooms using a symbol. * Replace a use of QTableWidget::clearContents() with QTableWidgets::setRowCount(0) as I was getting some odd, deep in the Qt internal library issues {Fatal Seg. Faults!} with the former, which I suspect, but could not prove, might have been a re-entrancy issue caused by the method containing it being called indirectly by an asynchronous SIGNAL/SLOT originating in the value change from the map symbol font selection QFontComboBox... Revised to NOT do scaling when drawing room symbols from cache: the previous QPainter::drawPixmap(...) performed a scaling operation to make the symbol pixmap fit the specified rectangle. This is the cause behind the poor rendering of text characters as the scaling undoes the benefits of anti-aliasing and takes time to do. This should be faster now because the pixmaps are generated at the size/resolution they are needed (though they do have to be thrown away and regenerated if the zoom or other sizing factors change) - they do however look better to me! Also: * merged (int) TRoom::xzoom and TRoom::yzoom into TRoom::xyzoom. * added the symbol scaling "fudge-factor" to the "Special Options" tab of the "Profile preferences" dialog - it may be helpful to artificially over-size (> 1.00) or under-size (< 1.00) the symbols in some situations. * uses the word symbol rather than just glyph/grapheme in some texts. Also modified 2D mapper "Symbol" tooltip to observe that more than one letter/symbol can be used (although they will be drawn smaller so that they still fit). Add tool-tips to profile preferences dialog for font controls (except for "fudge factor" control (with range x0.50 to x2.00 for scaling of symbol to test rectangle used to fit it into the room shape)... I have consistently mispelled chosen as choosen but I have fixed that now...! Also added tooltips to map glyph usage table/widget. WorkAround: try to force a specific US mirror for zziplib on AppVeyor CI AppVeyor is based in Vancouver, Canada so the nearest SF Mirror is in the US so this commit forces the use of that mirror for that library for the CI build process as an attempt to get around the repeated, intermittent failures to get that library from SourceForge (it is now the only item that needs to be downloaded from there for such builds)... Also adds another CI file that was not mentioned before in the qmake project file and thus did not show up in the Qt IDE. Following extensive discussions it has been made clear that introducing replacements for the lua [gs]etRoomChar(...) is not going to happen. Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2018-03-28 14:06:12 +01:00
if (mSaveVersion >= 19) {
ofs << pR->mSymbol;
} else {
qint8 oldCharacterCode = 0;
if (pR->mSymbol.length()) {
// There is something for a symbol
QChar firstChar = pR->mSymbol.at(0);
if (pR->mSymbol.length() == 1 && firstChar.row() == 0 && firstChar.cell() > 32) {
// It is something that can be represented by the past unsigned short
oldCharacterCode = firstChar.toLatin1();
} else {
// Not representable - put in a '?' for older Mudlet
// versions that cannot display the character and will not
// parse the value placed in the room's user data:
oldCharacterCode = QChar('?').toLatin1();
}
}
ofs << oldCharacterCode;
}
2013-03-22 12:47:58 +01:00
ofs << pR->userData;
ofs << pR->customLines;
ofs << pR->customLinesArrow;
ofs << pR->customLinesColor;
ofs << pR->customLinesStyle;
ofs << pR->exitLocks;
ofs << pR->exitStubs;
2013-05-26 11:47:15 +02:00
ofs << pR->getExitWeights();
2013-03-22 12:47:58 +01:00
ofs << pR->doors;
2010-08-25 00:41:43 +02:00
}
return true;
}
bool TMap::restore(QString location, bool downloadIfNotFound)
2010-08-25 00:41:43 +02:00
{
qDebug() << "TMap::restore(" << location << ") INFO: restoring map of Profile:" << mpHost->getName() << " URL:" << mpHost->getUrl();
Enhance: add Area & Map user data structures & Lua script access commands Whilst working on the XML importer for Map files I found that I wanted some where to store the data from attributes for tags that we don't use in Mudlet directly. For room related details I could use the TRoom::userData member but then I realised that there is nothing corresponding to Areas or for the Map overall. This separate commit provides these and the lua commands to interact with them - with functionality the same as the Room based one. Of course, as there is only ONE map there is no argument needed to select an instance for those commands. Of all the "room" user data commands replicated for "area" and "map" the only one NOT so done are get????UserDataKeys() as this is a bit pointless with a getAll????UserData() one from which the keys could be extracted from the returned table {???? being "Area" or "Map"}. Added to TLuaInterpreter class to provide following user script commands: searchAreaUserData((string)<key>[, (string)<value>]) setAreaUserData((number)<area Id>, (string)<key>, (string)<value>) clearAreaUserData((number)<area Id>) clearAreaUserDataItem((number)<area Id>, (string)<key>) getAreaUserData((number)<area Id>, (string)<key>) getAllAreaUserData((number)<area Id>) setMapUserData((string)<key>, (string)<value>) clearMapUserData((string)<key>) clearMapUserDataItem() getMapUserData((string)<key>) getAllMapUserData() Refactored TMap::serialize() to allow saving in different map file formats as defined by the constants TMap::mDefaultVersion, mMinVersion and mMaxVersion - if either of the last pair are less than or more than the first value respectively then a control on the "Special Options" tab of the profile preferences dialog will be enabled - the state of each value that is allowed is clearly indicated and it is defaulted appropriately. At present: TMap::mDefaultVersion is 16 (replaces #define CURRENT_MAP_VERSION) TMap::mMinVersion is also 16 TMap::mMaxVersion is 17 This means that the new user data areas will only persist (be saved) if that control is manually adjusted to 17 FOR EACH SESSION in this development version. When we get to a release version mDefaultVersion should be upped to 17 so that the release version uses the new format but can be manually downgraded to current (16) for those who want to share a map with users who have not upgraded - with the less of those new user data items - such users can do this by opening the profile preferences, downing this setting THEN using the SAVE MAP button and then restoring to the default value and SAVING AGAIN to a different name in the recommend format. Also renamed TMap::version to TMap::mVersion... ========================================================================== As this code requires the revision to the map file format that is coded for but only enabled manually the setter commands setAreaUserData(...) and setMapUserData(...) will both emit a warning message that the data written will not CURRENTLY be saved with the map the FIRST (and only the first) time they are used when the preference control has not been manually adjusted. ========================================================================== Also: Tweaked a recent, previous merged commit that set an optional minimum time for a Timer NOT to display it's contents every time it fires in debug output screen in value: Host::mTimerDebugOutputSuppressionInterval so that the QTimeEdit that controls it defaults to adjusting the "Seconds" time field rather than the default "Hours" one as that is the one that is most likely the one the user might wist to use. Also: The control this commit adds to the Profile Preferences dialog makes use of the QComboBox::currentData() method that was introduced in Qt5.2 - the minimum Qt library requirement in the qmake project file was revised to accomodate this - if builders wish to use a Qt5.x before this they will need to manually provide extra code to allocate an integer value from the range of values wanted/offered. Also: whilst cross-checking for the cmake project file I found the top level one was missing from the qmake project file - so have added it to that. HOWEVER I HAVE NOT FOUND A WAY TO REQUIRE THE CMAKE SYSTEM TO REQUIRE QT5.2 AS A MINIMUM WHICH THIS COMMIT REQUIRES. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> Conflicts: src/src.pro
2015-12-30 13:42:41 +00:00
Backport: merge ten commits room "entrance" code from "release_30" to "development" branches, Commit 01 of 10 originally entitled: "fix for keeping reverse area exit map in sync with exit creation, adding, and deletion" Conflicts resolved in: src/TRoom.h Commit 02 of 10 originally entitled: "bug fix for entranceMap having reversed key and value" Conflicts resolved in: src/TRoomDB.cpp Commit 03 of 10 originally entitled: "removal of entranceMap cleanup" Conflicts resolved in: src/TRoomDB.cpp Commit 04 of 10 originally entitled: "BugFix: prevent crash in dlgRoomExits::initExits() on missing exit" Code deficiencies that remove rooms without properly updating connected rooms were causing segmentation faults because this method - perhaps foolishly - expected a room to exist when another room had an exit Id to the room given. This commit corrects any faulty normal exits now by resetting them to the no exit -1 value. Commit 05 of 10 originally entitled: "Fixup: prevent unneeded TRoom::setExit() calls from dlgRoomExits class" Each individual call to TRoom::setExit((int)exitRoomId,(int)directionCode) from dlgRoomExit::save() creates additional entries in TRoom::entranceMap even for non-exit directions. To reduce (but unfortunately not eliminate) the number of duplicates change the save() code to only use setExit() when a difference between the current and saved exit room numbers is found. Commit 06 of 10 originally entitled: "Fixup: clear TRoomDB::entranceMap on map clearance" Obvious but was missing. Commit 07 of 10 originally entitled: "Fixup: add getAllRoomEntrances() to Lua command set" Though suitable for release code this was added to help with debugging. This was what enabled me to spot the problems that the previous pair of commits ameliorates. This currently only reports the rooms that have exit(s) that lead to the given room Id. It is anticipated that there will be a future revision to report the particular direction(s) from the given room(s) are the one(s) that lead to the room, using a second argument that will be a boolean true to trigger that behavior (the absence of, or a false, second argument would then cause the result that this code produces.) Conflicts resolved in: src/TLuaInterpreter.cpp src/TLuaInterpreter.h Commit 08 of 10 originally entitled: "Fixup: add debugging output to TRoomDB::updateEntranceMap(TRoom *)" Set a break point in the method and change the static bool showDebug to dis-/en-able output... Conflicts resolved in: src/TRoomDB.cpp Commit 09 of 10 originally entitled: "FixEnhance: fix entranceMap maintenance, bulk room deletion & map loading" Previously we were not removing entries from the entranceMap involving the value (a room that the room Id that was a key had an entrance FROM) when a route was changed. There is a performance cost in ensuring the data is kept correctly - there may be a modest gain by storing the entrance data within each TRoom class instance rather than a central database in TRoomDB... Deletion of multiple rooms and map loading can be done more efficiently if we skip some redundant steps. Also added/revised some timing code to measure things. Conflicts resolved in: src/TRoomDB.cpp src/TRoomDB.h Commit 10 of 10 originally entitled: "BugFix: Some previous coding errors" * T2DMap::slot_setArea(): used a uint where I should have used an int as a method I called can return a -1 in some cases. * TArea::getAreaExitRoomData(): a qWarning() in a debugging line I had used the wrong type (%1,%2,...) of format string argument characters when I should of used (%i or %s)... * (bool)TArea::mIsDirty: was put in wrong block of lines in header Conflicts resolved in: src/TArea.h Further conflicts resolved which were brought about by later re-basing before posting code out to world: src/dlgRoomExits.cpp Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-08-15 22:15:39 +01:00
QElapsedTimer _time;
_time.start();
QString folder;
QStringList entries;
if (location.isEmpty()) {
Refactor: reduce use of raw string literals for directories and file paths Using a static method means that we can centralise the generation of strings used to access parts of the file system used to hold Mudlet user data - which may be useful if we change them for - say running from a thumb-drive or just to use an OS specific location for them. {Using a ".config/mudlet" sub-directory on Windows is not quite how that OS expects things to be done...!} This also reduces the number of raw strings that will have to be wrapped in QStringLiteral(...) and the like for forthcoming I18n work. Also: * The use of "mudlet-data" as a windows symlink sub-directory to ".config/mudlet" in the user home directory may not work because the Qt Documentation suggests that a ".lnk" extension is required - this commit adds that FOR THAT OS ONLY. * Previous code placed (only some - for an unexplained reason not all the files were being copied) the DejaVu fonts that we include in the resources directly into the main mudlet user data folder - but the included documentation including the COPYRIGHT.TXT and other files ONLY relate to those font files and NOT to Mudlet as a whole. I have taken the liberty of moving and loading them from a ./fonts/ subdirectory which makes more sense. I have noted that, at least, the Debian Linux packager actually removes the font files from their configuration because they already include a shared system wide copy of the same fonts and in a much newer (2.37 at present) version compared to the 1.10 that we bundle - perhaps our code needs to check for the existence/availability of the fonts before we try to load ours into the Mudlet application at run-time! Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2017-09-18 16:23:57 +01:00
folder = mudlet::getMudletPath(mudlet::profileMapsPath, mpHost->getName());
QDir dir(folder);
dir.setSorting(QDir::Time);
entries = dir.entryList(QDir::Files, QDir::Time);
}
2010-08-25 00:41:43 +02:00
bool canRestore = true;
if (!entries.empty() || !location.isEmpty()) {
Refactor: reduce use of raw string literals for directories and file paths Using a static method means that we can centralise the generation of strings used to access parts of the file system used to hold Mudlet user data - which may be useful if we change them for - say running from a thumb-drive or just to use an OS specific location for them. {Using a ".config/mudlet" sub-directory on Windows is not quite how that OS expects things to be done...!} This also reduces the number of raw strings that will have to be wrapped in QStringLiteral(...) and the like for forthcoming I18n work. Also: * The use of "mudlet-data" as a windows symlink sub-directory to ".config/mudlet" in the user home directory may not work because the Qt Documentation suggests that a ".lnk" extension is required - this commit adds that FOR THAT OS ONLY. * Previous code placed (only some - for an unexplained reason not all the files were being copied) the DejaVu fonts that we include in the resources directly into the main mudlet user data folder - but the included documentation including the COPYRIGHT.TXT and other files ONLY relate to those font files and NOT to Mudlet as a whole. I have taken the liberty of moving and loading them from a ./fonts/ subdirectory which makes more sense. I have noted that, at least, the Debian Linux packager actually removes the font files from their configuration because they already include a shared system wide copy of the same fonts and in a much newer (2.37 at present) version compared to the 1.10 that we bundle - perhaps our code needs to check for the existence/availability of the fonts before we try to load ours into the Mudlet application at run-time! Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2017-09-18 16:23:57 +01:00
QFile file(location.isEmpty() ? QStringLiteral("%1/%2").arg(folder, entries.at(0)) : location);
if (!file.open(QFile::ReadOnly)) {
QString errMsg = tr(R"([ ERROR ] - Unable to open (for reading) map file: "%1"!)").arg(file.fileName());
appendErrorMsg(errMsg, false);
postMessage(errMsg);
return false;
Enhance: add Area & Map user data structures & Lua script access commands Whilst working on the XML importer for Map files I found that I wanted some where to store the data from attributes for tags that we don't use in Mudlet directly. For room related details I could use the TRoom::userData member but then I realised that there is nothing corresponding to Areas or for the Map overall. This separate commit provides these and the lua commands to interact with them - with functionality the same as the Room based one. Of course, as there is only ONE map there is no argument needed to select an instance for those commands. Of all the "room" user data commands replicated for "area" and "map" the only one NOT so done are get????UserDataKeys() as this is a bit pointless with a getAll????UserData() one from which the keys could be extracted from the returned table {???? being "Area" or "Map"}. Added to TLuaInterpreter class to provide following user script commands: searchAreaUserData((string)<key>[, (string)<value>]) setAreaUserData((number)<area Id>, (string)<key>, (string)<value>) clearAreaUserData((number)<area Id>) clearAreaUserDataItem((number)<area Id>, (string)<key>) getAreaUserData((number)<area Id>, (string)<key>) getAllAreaUserData((number)<area Id>) setMapUserData((string)<key>, (string)<value>) clearMapUserData((string)<key>) clearMapUserDataItem() getMapUserData((string)<key>) getAllMapUserData() Refactored TMap::serialize() to allow saving in different map file formats as defined by the constants TMap::mDefaultVersion, mMinVersion and mMaxVersion - if either of the last pair are less than or more than the first value respectively then a control on the "Special Options" tab of the profile preferences dialog will be enabled - the state of each value that is allowed is clearly indicated and it is defaulted appropriately. At present: TMap::mDefaultVersion is 16 (replaces #define CURRENT_MAP_VERSION) TMap::mMinVersion is also 16 TMap::mMaxVersion is 17 This means that the new user data areas will only persist (be saved) if that control is manually adjusted to 17 FOR EACH SESSION in this development version. When we get to a release version mDefaultVersion should be upped to 17 so that the release version uses the new format but can be manually downgraded to current (16) for those who want to share a map with users who have not upgraded - with the less of those new user data items - such users can do this by opening the profile preferences, downing this setting THEN using the SAVE MAP button and then restoring to the default value and SAVING AGAIN to a different name in the recommend format. Also renamed TMap::version to TMap::mVersion... ========================================================================== As this code requires the revision to the map file format that is coded for but only enabled manually the setter commands setAreaUserData(...) and setMapUserData(...) will both emit a warning message that the data written will not CURRENTLY be saved with the map the FIRST (and only the first) time they are used when the preference control has not been manually adjusted. ========================================================================== Also: Tweaked a recent, previous merged commit that set an optional minimum time for a Timer NOT to display it's contents every time it fires in debug output screen in value: Host::mTimerDebugOutputSuppressionInterval so that the QTimeEdit that controls it defaults to adjusting the "Seconds" time field rather than the default "Hours" one as that is the one that is most likely the one the user might wist to use. Also: The control this commit adds to the Profile Preferences dialog makes use of the QComboBox::currentData() method that was introduced in Qt5.2 - the minimum Qt library requirement in the qmake project file was revised to accomodate this - if builders wish to use a Qt5.x before this they will need to manually provide extra code to allocate an integer value from the range of values wanted/offered. Also: whilst cross-checking for the cmake project file I found the top level one was missing from the qmake project file - so have added it to that. HOWEVER I HAVE NOT FOUND A WAY TO REQUIRE THE CMAKE SYSTEM TO REQUIRE QT5.2 AS A MINIMUM WHICH THIS COMMIT REQUIRES. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> Conflicts: src/src.pro
2015-12-30 13:42:41 +00:00
}
QDataStream ifs(&file);
Enhance: add Area & Map user data structures & Lua script access commands Whilst working on the XML importer for Map files I found that I wanted some where to store the data from attributes for tags that we don't use in Mudlet directly. For room related details I could use the TRoom::userData member but then I realised that there is nothing corresponding to Areas or for the Map overall. This separate commit provides these and the lua commands to interact with them - with functionality the same as the Room based one. Of course, as there is only ONE map there is no argument needed to select an instance for those commands. Of all the "room" user data commands replicated for "area" and "map" the only one NOT so done are get????UserDataKeys() as this is a bit pointless with a getAll????UserData() one from which the keys could be extracted from the returned table {???? being "Area" or "Map"}. Added to TLuaInterpreter class to provide following user script commands: searchAreaUserData((string)<key>[, (string)<value>]) setAreaUserData((number)<area Id>, (string)<key>, (string)<value>) clearAreaUserData((number)<area Id>) clearAreaUserDataItem((number)<area Id>, (string)<key>) getAreaUserData((number)<area Id>, (string)<key>) getAllAreaUserData((number)<area Id>) setMapUserData((string)<key>, (string)<value>) clearMapUserData((string)<key>) clearMapUserDataItem() getMapUserData((string)<key>) getAllMapUserData() Refactored TMap::serialize() to allow saving in different map file formats as defined by the constants TMap::mDefaultVersion, mMinVersion and mMaxVersion - if either of the last pair are less than or more than the first value respectively then a control on the "Special Options" tab of the profile preferences dialog will be enabled - the state of each value that is allowed is clearly indicated and it is defaulted appropriately. At present: TMap::mDefaultVersion is 16 (replaces #define CURRENT_MAP_VERSION) TMap::mMinVersion is also 16 TMap::mMaxVersion is 17 This means that the new user data areas will only persist (be saved) if that control is manually adjusted to 17 FOR EACH SESSION in this development version. When we get to a release version mDefaultVersion should be upped to 17 so that the release version uses the new format but can be manually downgraded to current (16) for those who want to share a map with users who have not upgraded - with the less of those new user data items - such users can do this by opening the profile preferences, downing this setting THEN using the SAVE MAP button and then restoring to the default value and SAVING AGAIN to a different name in the recommend format. Also renamed TMap::version to TMap::mVersion... ========================================================================== As this code requires the revision to the map file format that is coded for but only enabled manually the setter commands setAreaUserData(...) and setMapUserData(...) will both emit a warning message that the data written will not CURRENTLY be saved with the map the FIRST (and only the first) time they are used when the preference control has not been manually adjusted. ========================================================================== Also: Tweaked a recent, previous merged commit that set an optional minimum time for a Timer NOT to display it's contents every time it fires in debug output screen in value: Host::mTimerDebugOutputSuppressionInterval so that the QTimeEdit that controls it defaults to adjusting the "Seconds" time field rather than the default "Hours" one as that is the one that is most likely the one the user might wist to use. Also: The control this commit adds to the Profile Preferences dialog makes use of the QComboBox::currentData() method that was introduced in Qt5.2 - the minimum Qt library requirement in the qmake project file was revised to accomodate this - if builders wish to use a Qt5.x before this they will need to manually provide extra code to allocate an integer value from the range of values wanted/offered. Also: whilst cross-checking for the cmake project file I found the top level one was missing from the qmake project file - so have added it to that. HOWEVER I HAVE NOT FOUND A WAY TO REQUIRE THE CMAKE SYSTEM TO REQUIRE QT5.2 AS A MINIMUM WHICH THIS COMMIT REQUIRES. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> Conflicts: src/src.pro
2015-12-30 13:42:41 +00:00
ifs >> mVersion;
if (mVersion > mMaxVersion) {
QString errMsg = tr("[ ERROR ] - Map file is too new, its file format (%1) is higher than this version of\n"
"Mudlet can handle (%2)! The file is:\n\"%3\".")
.arg(mVersion)
.arg(mMaxVersion)
.arg(file.fileName());
appendErrorMsgWithNoLf(errMsg);
postMessage(errMsg);
QString infoMsg = tr("[ INFO ] - You will need to upgrade your Mudlet or find a map file saved in an\n"
"older format.");
appendErrorMsgWithNoLf(infoMsg);
postMessage(infoMsg);
file.close();
return false;
} else if (mVersion < 4) {
QString alertMsg = tr("[ ALERT ] - Map file is really old, it's file format (%1) is so ancient that\n"
"this version of Mudlet may not gain enough information from\n"
"it but it will try! The file is: \"%2\".")
.arg(mVersion)
.arg(file.fileName());
appendErrorMsgWithNoLf(alertMsg, false);
postMessage(alertMsg);
QString infoMsg = tr("[ INFO ] - You might wish to donate THIS map file to the Mudlet Museum!\n"
"There is so much data that it DOES NOT have that you could be\n"
2018-06-07 01:04:10 -04:00
"better off starting again...");
appendErrorMsgWithNoLf(infoMsg, false);
postMessage(infoMsg);
2010-08-25 00:41:43 +02:00
canRestore = false;
mSaveVersion = mVersion; // Make the save version the default one - unless the user intervenes
} else {
// Less than (but not less than 4) or equal to default version
QString infoMsg = tr("[ INFO ] - Reading map (format version:%1) file:\n\"%2\",\nplease wait...").arg(mVersion).arg(file.fileName());
appendErrorMsg(tr(R"([ INFO ] - Reading map (format version:%1) file: "%2".)").arg(mVersion).arg(file.fileName()), false);
postMessage(infoMsg);
mSaveVersion = mVersion; // Make the save version the default one - unless the user intervenes
2010-08-25 00:41:43 +02:00
}
Enhance: add Area & Map user data structures & Lua script access commands Whilst working on the XML importer for Map files I found that I wanted some where to store the data from attributes for tags that we don't use in Mudlet directly. For room related details I could use the TRoom::userData member but then I realised that there is nothing corresponding to Areas or for the Map overall. This separate commit provides these and the lua commands to interact with them - with functionality the same as the Room based one. Of course, as there is only ONE map there is no argument needed to select an instance for those commands. Of all the "room" user data commands replicated for "area" and "map" the only one NOT so done are get????UserDataKeys() as this is a bit pointless with a getAll????UserData() one from which the keys could be extracted from the returned table {???? being "Area" or "Map"}. Added to TLuaInterpreter class to provide following user script commands: searchAreaUserData((string)<key>[, (string)<value>]) setAreaUserData((number)<area Id>, (string)<key>, (string)<value>) clearAreaUserData((number)<area Id>) clearAreaUserDataItem((number)<area Id>, (string)<key>) getAreaUserData((number)<area Id>, (string)<key>) getAllAreaUserData((number)<area Id>) setMapUserData((string)<key>, (string)<value>) clearMapUserData((string)<key>) clearMapUserDataItem() getMapUserData((string)<key>) getAllMapUserData() Refactored TMap::serialize() to allow saving in different map file formats as defined by the constants TMap::mDefaultVersion, mMinVersion and mMaxVersion - if either of the last pair are less than or more than the first value respectively then a control on the "Special Options" tab of the profile preferences dialog will be enabled - the state of each value that is allowed is clearly indicated and it is defaulted appropriately. At present: TMap::mDefaultVersion is 16 (replaces #define CURRENT_MAP_VERSION) TMap::mMinVersion is also 16 TMap::mMaxVersion is 17 This means that the new user data areas will only persist (be saved) if that control is manually adjusted to 17 FOR EACH SESSION in this development version. When we get to a release version mDefaultVersion should be upped to 17 so that the release version uses the new format but can be manually downgraded to current (16) for those who want to share a map with users who have not upgraded - with the less of those new user data items - such users can do this by opening the profile preferences, downing this setting THEN using the SAVE MAP button and then restoring to the default value and SAVING AGAIN to a different name in the recommend format. Also renamed TMap::version to TMap::mVersion... ========================================================================== As this code requires the revision to the map file format that is coded for but only enabled manually the setter commands setAreaUserData(...) and setMapUserData(...) will both emit a warning message that the data written will not CURRENTLY be saved with the map the FIRST (and only the first) time they are used when the preference control has not been manually adjusted. ========================================================================== Also: Tweaked a recent, previous merged commit that set an optional minimum time for a Timer NOT to display it's contents every time it fires in debug output screen in value: Host::mTimerDebugOutputSuppressionInterval so that the QTimeEdit that controls it defaults to adjusting the "Seconds" time field rather than the default "Hours" one as that is the one that is most likely the one the user might wist to use. Also: The control this commit adds to the Profile Preferences dialog makes use of the QComboBox::currentData() method that was introduced in Qt5.2 - the minimum Qt library requirement in the qmake project file was revised to accomodate this - if builders wish to use a Qt5.x before this they will need to manually provide extra code to allocate an integer value from the range of values wanted/offered. Also: whilst cross-checking for the cmake project file I found the top level one was missing from the qmake project file - so have added it to that. HOWEVER I HAVE NOT FOUND A WAY TO REQUIRE THE CMAKE SYSTEM TO REQUIRE QT5.2 AS A MINIMUM WHICH THIS COMMIT REQUIRES. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> Conflicts: src/src.pro
2015-12-30 13:42:41 +00:00
// As all but the room reading have version checks the fact that sub-4
// files will still be parsed despite canRestore being false is probably OK
if (mVersion >= 4) {
Enhance: add Area & Map user data structures & Lua script access commands Whilst working on the XML importer for Map files I found that I wanted some where to store the data from attributes for tags that we don't use in Mudlet directly. For room related details I could use the TRoom::userData member but then I realised that there is nothing corresponding to Areas or for the Map overall. This separate commit provides these and the lua commands to interact with them - with functionality the same as the Room based one. Of course, as there is only ONE map there is no argument needed to select an instance for those commands. Of all the "room" user data commands replicated for "area" and "map" the only one NOT so done are get????UserDataKeys() as this is a bit pointless with a getAll????UserData() one from which the keys could be extracted from the returned table {???? being "Area" or "Map"}. Added to TLuaInterpreter class to provide following user script commands: searchAreaUserData((string)<key>[, (string)<value>]) setAreaUserData((number)<area Id>, (string)<key>, (string)<value>) clearAreaUserData((number)<area Id>) clearAreaUserDataItem((number)<area Id>, (string)<key>) getAreaUserData((number)<area Id>, (string)<key>) getAllAreaUserData((number)<area Id>) setMapUserData((string)<key>, (string)<value>) clearMapUserData((string)<key>) clearMapUserDataItem() getMapUserData((string)<key>) getAllMapUserData() Refactored TMap::serialize() to allow saving in different map file formats as defined by the constants TMap::mDefaultVersion, mMinVersion and mMaxVersion - if either of the last pair are less than or more than the first value respectively then a control on the "Special Options" tab of the profile preferences dialog will be enabled - the state of each value that is allowed is clearly indicated and it is defaulted appropriately. At present: TMap::mDefaultVersion is 16 (replaces #define CURRENT_MAP_VERSION) TMap::mMinVersion is also 16 TMap::mMaxVersion is 17 This means that the new user data areas will only persist (be saved) if that control is manually adjusted to 17 FOR EACH SESSION in this development version. When we get to a release version mDefaultVersion should be upped to 17 so that the release version uses the new format but can be manually downgraded to current (16) for those who want to share a map with users who have not upgraded - with the less of those new user data items - such users can do this by opening the profile preferences, downing this setting THEN using the SAVE MAP button and then restoring to the default value and SAVING AGAIN to a different name in the recommend format. Also renamed TMap::version to TMap::mVersion... ========================================================================== As this code requires the revision to the map file format that is coded for but only enabled manually the setter commands setAreaUserData(...) and setMapUserData(...) will both emit a warning message that the data written will not CURRENTLY be saved with the map the FIRST (and only the first) time they are used when the preference control has not been manually adjusted. ========================================================================== Also: Tweaked a recent, previous merged commit that set an optional minimum time for a Timer NOT to display it's contents every time it fires in debug output screen in value: Host::mTimerDebugOutputSuppressionInterval so that the QTimeEdit that controls it defaults to adjusting the "Seconds" time field rather than the default "Hours" one as that is the one that is most likely the one the user might wist to use. Also: The control this commit adds to the Profile Preferences dialog makes use of the QComboBox::currentData() method that was introduced in Qt5.2 - the minimum Qt library requirement in the qmake project file was revised to accomodate this - if builders wish to use a Qt5.x before this they will need to manually provide extra code to allocate an integer value from the range of values wanted/offered. Also: whilst cross-checking for the cmake project file I found the top level one was missing from the qmake project file - so have added it to that. HOWEVER I HAVE NOT FOUND A WAY TO REQUIRE THE CMAKE SYSTEM TO REQUIRE QT5.2 AS A MINIMUM WHICH THIS COMMIT REQUIRES. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> Conflicts: src/src.pro
2015-12-30 13:42:41 +00:00
ifs >> envColors;
mpRoomDB->restoreAreaMap(ifs);
2010-08-25 00:41:43 +02:00
}
if (mVersion >= 5) {
2010-09-10 00:34:51 +02:00
ifs >> customEnvColors;
}
if (mVersion >= 7) {
2013-03-22 12:47:58 +01:00
ifs >> mpRoomDB->hashTable;
2011-01-11 08:44:38 +01:00
}
Enhance: add ability to set any glyph as a room symbol (#1543) This is a squashed down commit containing several commits with messages - this is the edited combination of all the messages: As well as being able to use any grapheme it is possible to use a short word as well as anything printable from any of the Unicode Multiple Planes; although the former will become smaller to fit within both the square and round room shapes on the 2D mapper. Adds controls to the profile preference to set the (preferred) font to use to set the room symbols from and a checkbox to only use that font. Additionally a sub-dialog can be brought up which lists the details of all the different symbols on the map - showing the Unicode codepoint(s) for each and showing how they would be rendered if only the selected font is used and if any font is permitted, along with a count of the usages and the rooms that use each one... A status icon is also displayed showing whether the symbol can be rendered entirely with the selected font (green tick), only by using glyphs from other fonts (yellow ! warning) or not with the current fonts on the system (red/white cross). This allows a user to make a sensible selection of a font to use or whether they will have a problem (and a replacement by the replacement character '�') for any symbols. Updates Lua setRoomChar and getRoomChar to handle the wider range of things that can be used. getRoomChar NOW allows for an existing character to be cleared with an empty string or a space as the char attribute. The map format version has been incremented to allow the data needed to be saved directly into the binary file format but failback code is in place that means that this feature can be carried in map and room user data instead for map format versions down to 17 - the current default is 18 and there is limited support to fail gracefully down to the 16 that Mudlet 2.1 uses (all the room letter markings that are not supported will become '?', and the font data will be lost, but the correct room character data will still be in the room user data.) Following review: * I replaced some colour specifications (white and transparent) with Qt constants. * Use the same inline function flushSymbolPixmapCache() to clear the map symbol pixmap cache in all places where it might be useful. * Simplify a couple of places where an if(...) {...} else {...} can be replaced with the (...) ? (...) : (...) operator. * Limit the number of room numbers displayed for each symbol in the new widget - to avoid complications where there are huge numbers of rooms using a symbol. * Replace a use of QTableWidget::clearContents() with QTableWidgets::setRowCount(0) as I was getting some odd, deep in the Qt internal library issues {Fatal Seg. Faults!} with the former, which I suspect, but could not prove, might have been a re-entrancy issue caused by the method containing it being called indirectly by an asynchronous SIGNAL/SLOT originating in the value change from the map symbol font selection QFontComboBox... Revised to NOT do scaling when drawing room symbols from cache: the previous QPainter::drawPixmap(...) performed a scaling operation to make the symbol pixmap fit the specified rectangle. This is the cause behind the poor rendering of text characters as the scaling undoes the benefits of anti-aliasing and takes time to do. This should be faster now because the pixmaps are generated at the size/resolution they are needed (though they do have to be thrown away and regenerated if the zoom or other sizing factors change) - they do however look better to me! Also: * merged (int) TRoom::xzoom and TRoom::yzoom into TRoom::xyzoom. * added the symbol scaling "fudge-factor" to the "Special Options" tab of the "Profile preferences" dialog - it may be helpful to artificially over-size (> 1.00) or under-size (< 1.00) the symbols in some situations. * uses the word symbol rather than just glyph/grapheme in some texts. Also modified 2D mapper "Symbol" tooltip to observe that more than one letter/symbol can be used (although they will be drawn smaller so that they still fit). Add tool-tips to profile preferences dialog for font controls (except for "fudge factor" control (with range x0.50 to x2.00 for scaling of symbol to test rectangle used to fit it into the room shape)... I have consistently mispelled chosen as choosen but I have fixed that now...! Also added tooltips to map glyph usage table/widget. WorkAround: try to force a specific US mirror for zziplib on AppVeyor CI AppVeyor is based in Vancouver, Canada so the nearest SF Mirror is in the US so this commit forces the use of that mirror for that library for the CI build process as an attempt to get around the repeated, intermittent failures to get that library from SourceForge (it is now the only item that needs to be downloaded from there for such builds)... Also adds another CI file that was not mentioned before in the qmake project file and thus did not show up in the Qt IDE. Following extensive discussions it has been made clear that introducing replacements for the lua [gs]etRoomChar(...) is not going to happen. Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2018-03-28 14:06:12 +01:00
if (mVersion >= 17) {
Enhance: add Area & Map user data structures & Lua script access commands Whilst working on the XML importer for Map files I found that I wanted some where to store the data from attributes for tags that we don't use in Mudlet directly. For room related details I could use the TRoom::userData member but then I realised that there is nothing corresponding to Areas or for the Map overall. This separate commit provides these and the lua commands to interact with them - with functionality the same as the Room based one. Of course, as there is only ONE map there is no argument needed to select an instance for those commands. Of all the "room" user data commands replicated for "area" and "map" the only one NOT so done are get????UserDataKeys() as this is a bit pointless with a getAll????UserData() one from which the keys could be extracted from the returned table {???? being "Area" or "Map"}. Added to TLuaInterpreter class to provide following user script commands: searchAreaUserData((string)<key>[, (string)<value>]) setAreaUserData((number)<area Id>, (string)<key>, (string)<value>) clearAreaUserData((number)<area Id>) clearAreaUserDataItem((number)<area Id>, (string)<key>) getAreaUserData((number)<area Id>, (string)<key>) getAllAreaUserData((number)<area Id>) setMapUserData((string)<key>, (string)<value>) clearMapUserData((string)<key>) clearMapUserDataItem() getMapUserData((string)<key>) getAllMapUserData() Refactored TMap::serialize() to allow saving in different map file formats as defined by the constants TMap::mDefaultVersion, mMinVersion and mMaxVersion - if either of the last pair are less than or more than the first value respectively then a control on the "Special Options" tab of the profile preferences dialog will be enabled - the state of each value that is allowed is clearly indicated and it is defaulted appropriately. At present: TMap::mDefaultVersion is 16 (replaces #define CURRENT_MAP_VERSION) TMap::mMinVersion is also 16 TMap::mMaxVersion is 17 This means that the new user data areas will only persist (be saved) if that control is manually adjusted to 17 FOR EACH SESSION in this development version. When we get to a release version mDefaultVersion should be upped to 17 so that the release version uses the new format but can be manually downgraded to current (16) for those who want to share a map with users who have not upgraded - with the less of those new user data items - such users can do this by opening the profile preferences, downing this setting THEN using the SAVE MAP button and then restoring to the default value and SAVING AGAIN to a different name in the recommend format. Also renamed TMap::version to TMap::mVersion... ========================================================================== As this code requires the revision to the map file format that is coded for but only enabled manually the setter commands setAreaUserData(...) and setMapUserData(...) will both emit a warning message that the data written will not CURRENTLY be saved with the map the FIRST (and only the first) time they are used when the preference control has not been manually adjusted. ========================================================================== Also: Tweaked a recent, previous merged commit that set an optional minimum time for a Timer NOT to display it's contents every time it fires in debug output screen in value: Host::mTimerDebugOutputSuppressionInterval so that the QTimeEdit that controls it defaults to adjusting the "Seconds" time field rather than the default "Hours" one as that is the one that is most likely the one the user might wist to use. Also: The control this commit adds to the Profile Preferences dialog makes use of the QComboBox::currentData() method that was introduced in Qt5.2 - the minimum Qt library requirement in the qmake project file was revised to accomodate this - if builders wish to use a Qt5.x before this they will need to manually provide extra code to allocate an integer value from the range of values wanted/offered. Also: whilst cross-checking for the cmake project file I found the top level one was missing from the qmake project file - so have added it to that. HOWEVER I HAVE NOT FOUND A WAY TO REQUIRE THE CMAKE SYSTEM TO REQUIRE QT5.2 AS A MINIMUM WHICH THIS COMMIT REQUIRES. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> Conflicts: src/src.pro
2015-12-30 13:42:41 +00:00
ifs >> mUserData;
Enhance: add ability to set any glyph as a room symbol (#1543) This is a squashed down commit containing several commits with messages - this is the edited combination of all the messages: As well as being able to use any grapheme it is possible to use a short word as well as anything printable from any of the Unicode Multiple Planes; although the former will become smaller to fit within both the square and round room shapes on the 2D mapper. Adds controls to the profile preference to set the (preferred) font to use to set the room symbols from and a checkbox to only use that font. Additionally a sub-dialog can be brought up which lists the details of all the different symbols on the map - showing the Unicode codepoint(s) for each and showing how they would be rendered if only the selected font is used and if any font is permitted, along with a count of the usages and the rooms that use each one... A status icon is also displayed showing whether the symbol can be rendered entirely with the selected font (green tick), only by using glyphs from other fonts (yellow ! warning) or not with the current fonts on the system (red/white cross). This allows a user to make a sensible selection of a font to use or whether they will have a problem (and a replacement by the replacement character '�') for any symbols. Updates Lua setRoomChar and getRoomChar to handle the wider range of things that can be used. getRoomChar NOW allows for an existing character to be cleared with an empty string or a space as the char attribute. The map format version has been incremented to allow the data needed to be saved directly into the binary file format but failback code is in place that means that this feature can be carried in map and room user data instead for map format versions down to 17 - the current default is 18 and there is limited support to fail gracefully down to the 16 that Mudlet 2.1 uses (all the room letter markings that are not supported will become '?', and the font data will be lost, but the correct room character data will still be in the room user data.) Following review: * I replaced some colour specifications (white and transparent) with Qt constants. * Use the same inline function flushSymbolPixmapCache() to clear the map symbol pixmap cache in all places where it might be useful. * Simplify a couple of places where an if(...) {...} else {...} can be replaced with the (...) ? (...) : (...) operator. * Limit the number of room numbers displayed for each symbol in the new widget - to avoid complications where there are huge numbers of rooms using a symbol. * Replace a use of QTableWidget::clearContents() with QTableWidgets::setRowCount(0) as I was getting some odd, deep in the Qt internal library issues {Fatal Seg. Faults!} with the former, which I suspect, but could not prove, might have been a re-entrancy issue caused by the method containing it being called indirectly by an asynchronous SIGNAL/SLOT originating in the value change from the map symbol font selection QFontComboBox... Revised to NOT do scaling when drawing room symbols from cache: the previous QPainter::drawPixmap(...) performed a scaling operation to make the symbol pixmap fit the specified rectangle. This is the cause behind the poor rendering of text characters as the scaling undoes the benefits of anti-aliasing and takes time to do. This should be faster now because the pixmaps are generated at the size/resolution they are needed (though they do have to be thrown away and regenerated if the zoom or other sizing factors change) - they do however look better to me! Also: * merged (int) TRoom::xzoom and TRoom::yzoom into TRoom::xyzoom. * added the symbol scaling "fudge-factor" to the "Special Options" tab of the "Profile preferences" dialog - it may be helpful to artificially over-size (> 1.00) or under-size (< 1.00) the symbols in some situations. * uses the word symbol rather than just glyph/grapheme in some texts. Also modified 2D mapper "Symbol" tooltip to observe that more than one letter/symbol can be used (although they will be drawn smaller so that they still fit). Add tool-tips to profile preferences dialog for font controls (except for "fudge factor" control (with range x0.50 to x2.00 for scaling of symbol to test rectangle used to fit it into the room shape)... I have consistently mispelled chosen as choosen but I have fixed that now...! Also added tooltips to map glyph usage table/widget. WorkAround: try to force a specific US mirror for zziplib on AppVeyor CI AppVeyor is based in Vancouver, Canada so the nearest SF Mirror is in the US so this commit forces the use of that mirror for that library for the CI build process as an attempt to get around the repeated, intermittent failures to get that library from SourceForge (it is now the only item that needs to be downloaded from there for such builds)... Also adds another CI file that was not mentioned before in the qmake project file and thus did not show up in the Qt IDE. Following extensive discussions it has been made clear that introducing replacements for the lua [gs]etRoomChar(...) is not going to happen. Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2018-03-28 14:06:12 +01:00
if (mVersion >= 19) {
// Read the data from the file directly in version 19 or later
ifs >> mMapSymbolFont;
ifs >> mMapSymbolFontFudgeFactor;
ifs >> mIsOnlyMapSymbolFontToBeUsed;
} else {
// Fallback to reading the data from the map user data - and
// remove it from the data the user will see:
QString fontString = mUserData.take(QStringLiteral("system.fallback_mapSymbolFont"));
QString fontFudgeFactorString = mUserData.take(QStringLiteral("system.fallback_mapSymbolFontFudgeFactor"));
QString onlyUseSymbolFontString = mUserData.take(QStringLiteral("system.fallback_onlyUseMapSymbolFont"));
if (!fontString.isEmpty()) {
mMapSymbolFont = QFont(fontString);
}
if (!fontFudgeFactorString.isEmpty()) {
mMapSymbolFontFudgeFactor = fontFudgeFactorString.toDouble();
}
if (!onlyUseSymbolFontString.isEmpty()) {
mIsOnlyMapSymbolFontToBeUsed = (onlyUseSymbolFontString != QLatin1String("false"));
}
}
Enhance: add Area & Map user data structures & Lua script access commands Whilst working on the XML importer for Map files I found that I wanted some where to store the data from attributes for tags that we don't use in Mudlet directly. For room related details I could use the TRoom::userData member but then I realised that there is nothing corresponding to Areas or for the Map overall. This separate commit provides these and the lua commands to interact with them - with functionality the same as the Room based one. Of course, as there is only ONE map there is no argument needed to select an instance for those commands. Of all the "room" user data commands replicated for "area" and "map" the only one NOT so done are get????UserDataKeys() as this is a bit pointless with a getAll????UserData() one from which the keys could be extracted from the returned table {???? being "Area" or "Map"}. Added to TLuaInterpreter class to provide following user script commands: searchAreaUserData((string)<key>[, (string)<value>]) setAreaUserData((number)<area Id>, (string)<key>, (string)<value>) clearAreaUserData((number)<area Id>) clearAreaUserDataItem((number)<area Id>, (string)<key>) getAreaUserData((number)<area Id>, (string)<key>) getAllAreaUserData((number)<area Id>) setMapUserData((string)<key>, (string)<value>) clearMapUserData((string)<key>) clearMapUserDataItem() getMapUserData((string)<key>) getAllMapUserData() Refactored TMap::serialize() to allow saving in different map file formats as defined by the constants TMap::mDefaultVersion, mMinVersion and mMaxVersion - if either of the last pair are less than or more than the first value respectively then a control on the "Special Options" tab of the profile preferences dialog will be enabled - the state of each value that is allowed is clearly indicated and it is defaulted appropriately. At present: TMap::mDefaultVersion is 16 (replaces #define CURRENT_MAP_VERSION) TMap::mMinVersion is also 16 TMap::mMaxVersion is 17 This means that the new user data areas will only persist (be saved) if that control is manually adjusted to 17 FOR EACH SESSION in this development version. When we get to a release version mDefaultVersion should be upped to 17 so that the release version uses the new format but can be manually downgraded to current (16) for those who want to share a map with users who have not upgraded - with the less of those new user data items - such users can do this by opening the profile preferences, downing this setting THEN using the SAVE MAP button and then restoring to the default value and SAVING AGAIN to a different name in the recommend format. Also renamed TMap::version to TMap::mVersion... ========================================================================== As this code requires the revision to the map file format that is coded for but only enabled manually the setter commands setAreaUserData(...) and setMapUserData(...) will both emit a warning message that the data written will not CURRENTLY be saved with the map the FIRST (and only the first) time they are used when the preference control has not been manually adjusted. ========================================================================== Also: Tweaked a recent, previous merged commit that set an optional minimum time for a Timer NOT to display it's contents every time it fires in debug output screen in value: Host::mTimerDebugOutputSuppressionInterval so that the QTimeEdit that controls it defaults to adjusting the "Seconds" time field rather than the default "Hours" one as that is the one that is most likely the one the user might wist to use. Also: The control this commit adds to the Profile Preferences dialog makes use of the QComboBox::currentData() method that was introduced in Qt5.2 - the minimum Qt library requirement in the qmake project file was revised to accomodate this - if builders wish to use a Qt5.x before this they will need to manually provide extra code to allocate an integer value from the range of values wanted/offered. Also: whilst cross-checking for the cmake project file I found the top level one was missing from the qmake project file - so have added it to that. HOWEVER I HAVE NOT FOUND A WAY TO REQUIRE THE CMAKE SYSTEM TO REQUIRE QT5.2 AS A MINIMUM WHICH THIS COMMIT REQUIRES. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> Conflicts: src/src.pro
2015-12-30 13:42:41 +00:00
}
Enhance: add ability to set any glyph as a room symbol (#1543) This is a squashed down commit containing several commits with messages - this is the edited combination of all the messages: As well as being able to use any grapheme it is possible to use a short word as well as anything printable from any of the Unicode Multiple Planes; although the former will become smaller to fit within both the square and round room shapes on the 2D mapper. Adds controls to the profile preference to set the (preferred) font to use to set the room symbols from and a checkbox to only use that font. Additionally a sub-dialog can be brought up which lists the details of all the different symbols on the map - showing the Unicode codepoint(s) for each and showing how they would be rendered if only the selected font is used and if any font is permitted, along with a count of the usages and the rooms that use each one... A status icon is also displayed showing whether the symbol can be rendered entirely with the selected font (green tick), only by using glyphs from other fonts (yellow ! warning) or not with the current fonts on the system (red/white cross). This allows a user to make a sensible selection of a font to use or whether they will have a problem (and a replacement by the replacement character '�') for any symbols. Updates Lua setRoomChar and getRoomChar to handle the wider range of things that can be used. getRoomChar NOW allows for an existing character to be cleared with an empty string or a space as the char attribute. The map format version has been incremented to allow the data needed to be saved directly into the binary file format but failback code is in place that means that this feature can be carried in map and room user data instead for map format versions down to 17 - the current default is 18 and there is limited support to fail gracefully down to the 16 that Mudlet 2.1 uses (all the room letter markings that are not supported will become '?', and the font data will be lost, but the correct room character data will still be in the room user data.) Following review: * I replaced some colour specifications (white and transparent) with Qt constants. * Use the same inline function flushSymbolPixmapCache() to clear the map symbol pixmap cache in all places where it might be useful. * Simplify a couple of places where an if(...) {...} else {...} can be replaced with the (...) ? (...) : (...) operator. * Limit the number of room numbers displayed for each symbol in the new widget - to avoid complications where there are huge numbers of rooms using a symbol. * Replace a use of QTableWidget::clearContents() with QTableWidgets::setRowCount(0) as I was getting some odd, deep in the Qt internal library issues {Fatal Seg. Faults!} with the former, which I suspect, but could not prove, might have been a re-entrancy issue caused by the method containing it being called indirectly by an asynchronous SIGNAL/SLOT originating in the value change from the map symbol font selection QFontComboBox... Revised to NOT do scaling when drawing room symbols from cache: the previous QPainter::drawPixmap(...) performed a scaling operation to make the symbol pixmap fit the specified rectangle. This is the cause behind the poor rendering of text characters as the scaling undoes the benefits of anti-aliasing and takes time to do. This should be faster now because the pixmaps are generated at the size/resolution they are needed (though they do have to be thrown away and regenerated if the zoom or other sizing factors change) - they do however look better to me! Also: * merged (int) TRoom::xzoom and TRoom::yzoom into TRoom::xyzoom. * added the symbol scaling "fudge-factor" to the "Special Options" tab of the "Profile preferences" dialog - it may be helpful to artificially over-size (> 1.00) or under-size (< 1.00) the symbols in some situations. * uses the word symbol rather than just glyph/grapheme in some texts. Also modified 2D mapper "Symbol" tooltip to observe that more than one letter/symbol can be used (although they will be drawn smaller so that they still fit). Add tool-tips to profile preferences dialog for font controls (except for "fudge factor" control (with range x0.50 to x2.00 for scaling of symbol to test rectangle used to fit it into the room shape)... I have consistently mispelled chosen as choosen but I have fixed that now...! Also added tooltips to map glyph usage table/widget. WorkAround: try to force a specific US mirror for zziplib on AppVeyor CI AppVeyor is based in Vancouver, Canada so the nearest SF Mirror is in the US so this commit forces the use of that mirror for that library for the CI build process as an attempt to get around the repeated, intermittent failures to get that library from SourceForge (it is now the only item that needs to be downloaded from there for such builds)... Also adds another CI file that was not mentioned before in the qmake project file and thus did not show up in the Qt IDE. Following extensive discussions it has been made clear that introducing replacements for the lua [gs]etRoomChar(...) is not going to happen. Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2018-03-28 14:06:12 +01:00
mMapSymbolFont.setStyleStrategy(static_cast<QFont::StyleStrategy>(( mIsOnlyMapSymbolFontToBeUsed ? QFont::NoFontMerging : 0)
| QFont::PreferOutline | QFont::PreferAntialias | QFont::PreferQuality
#if QT_VERSION >= 0x050a00
| QFont::PreferNoShaping
#endif
));
if (mVersion >= 14) {
int areaSize;
ifs >> areaSize;
// restore area table
for (int i = 0; i < areaSize; i++) {
auto pA = new TArea(this, mpRoomDB);
int areaID;
ifs >> areaID;
if (mVersion >= 18) {
// In version 18 changed from QList<int> to QSet<int> as the later is
// faster in many of the cases where we use it.
ifs >> pA->rooms;
} else {
QList<int> oldRoomsList;
ifs >> oldRoomsList;
pA->rooms = oldRoomsList.toSet();
enhanceAndFix: fix handling of parallel edges in BGL route-finding graph This commit cleans up some problems in route finding - specifically when working out the exits to use to move from the ordered list of rooms that make up the route that the A* code determined - no longer is the first exit in a fixed order in a particular room used that happens to go to the next room - instead the correct (lowest weighted, non-locked) exit is selected. If a route is not found the reason why is output via qDebug() which should make debugging problems a bit easier for developers! The BGL graph that TMap::initgraph() producess now tracks which exit from one room to another is the best one to use (choosing just one from equally weighted ones and ignores higher weighted ones) if it is a "normal" exit the subsequent use of TMap:findPath() will now insert a "translated" direction to the TMap::mDirList - but in future it should be straightforward to arrange for a user specified "direction" name to be used - perhaps with locale specific defaults which will make using Mudlet's route-finding code possible with non-ASCII using MUDs (i.e. those not based on American English!) This commit also avoids creating spurious entries in the BGL graph that the previous code did by using the "[]" operator (which inserted *wrong* entries into (QMap<int, int>) TMap::roomidToIndex for TRooms that should NOT have been present!) That was found to be causing crashes in corner cases where ALL rooms in the map or at least some rooms or their exits in what would otherwise have been a valid route were locked against use for route-finding. Also: * Culls some dead code in TAstar.h that was copied verbatim from a usage example elsewhere (possible the boost library documentation). * Removes following unused members of TMap: * (QList<int>) mTestedNodes * (QList<int>) conList * (int) mPlausaOptOut; * typedef of: mygraph_t::vertex_iterator to: vertex_iterator * typedef of: std::pair<int, int> to: edge * Comments out the now unused members of TMap: * (QMap<int, int>) indexToRoomid * Corrects spelling of TAstar.h in qmake project file - was spelt TAStar.h! * Generates a "speedWalkWeight" table alongside the "speedWalkPath" and "speedWalkDir" ones that indicates the weight of each step in a route, it can be accessed in the same manner as those others. * Host::assemblePath() now returns the total "weight" of the route calculated - which the lua command getPath(startRoomId, targetRoomId) now returns as a second value - this will make it easier for users' scripts to choose between routes to multiple destinations. * Some Lua helper methods: * TLuaInterpreter::get_lua_string(...) * TLuaInterpreter::set_lua_string(...) * TLuaInterpreter::set_lua_table(...) now process strings as Utf-8 - this change was needed to allow non-ASCII characters to appear in exit directions but will also be needed by other commands. Whilst the first is currently unused, the second is used once in three class and the third by Host::assemblePath() and twice in TLuaInterpreter::initLuaGlobals() to set up something for "atcp" and "channel102" processing... Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2015-07-19 20:38:13 +01:00
}
// Can be useful when analysing suspect map files!
// qDebug() << "TMap::restore(...)" << "Area:" << areaID;
// qDebug() << "Rooms:" << pA->rooms;
ifs >> pA->zLevels;
ifs >> pA->exits;
ifs >> pA->gridMode;
ifs >> pA->max_x;
ifs >> pA->max_y;
ifs >> pA->max_z;
ifs >> pA->min_x;
ifs >> pA->min_y;
ifs >> pA->min_z;
ifs >> pA->span;
if (mVersion >= 17) {
Enhance: 2D Map Room Selection, better big map performance + other mods In situations when we check whether a room in an area both for internal purposes and when rooms on a mapper is selected, using QSet instead of a QList is faster in performance for large numbers of entries in set. As it reworks the mapper code it also fixes issue where the multi-room selection widget overwrites map info display - the latter is re-sized and re-positioned (and regains a semi-transparent background which helped to show this working during debugging!) The former is now: dynamically resized to only take up enough vertical space to show the selected rooms; also displays the associate room names if there are any, expanding the widget as required; sorts the display either by room name or number and in either direction. The mouse wheel handler is modified so that using the scroll wheel ONLY scrolls the list within the widget - previously (by default) once the end in either direction was hit the related events would be passed up the widget chain where it would otherwise invoke the 2D mapper's zoom in/out code. In modifying the zoom in/out code I have replaced the (obsoleted in Qt5.x) QWheelEvent::delta() method to use the QWheelEvent::angleDelta() method, using only the Y-component the latter provides. If the Control modifier is active the zoom value is modified by an extra x10 factor which is useful when working with large maps as otherwise the zooming rate is "slow" at high values - ideally the control should be logarithmic or exponential or some other "non-linear" algorithm to work more uniformly over the range of practical use cases. The code to paint the map info text has been revised also to use the mMapInfoRect which was being defined but NOT used. The info text now reports whether the room name is for the player room {set via the Lua command centerview(roomId)} or is one that is selected by mouse dragging - and if more than one room is selected by that indicates the count of rooms in the selection. In the case of multiple rooms being selected the room that single room context menu operations will act upon is highlighted by the same style of yellow target used to show the custom exit line destination but is drawn in a different point in the code so that it is drawn over the rooms. Because of the change to the way that multiple rooms are selected routines that use that information had to be revised - in doing so it was possible to improve the usability/operation of: T2DMap::slot_movePosition() T2DMap::slot_setCharacter() T2DMap::slot_spread() T2DMap::slot_shrink() T2DMap::slot_lockRoom(): T2DMap::slot_unlockRoom(): This method, also resurrected here to the 2D mapper context menu, as it is also affected by the changes: T2DMap::slot_setPlayerLocation() There was a slot_setPlayerLocation code that set a global lua variable mRoomSet and moved the player to that room Id (introduced in commit-c25faf4e 2012-05-04 07:44:36 by Heiko) but the corresponding 2D Mapper context menu item that called it was commented out and thus removed from the menu in commit-93f65962 2012-12-29 01:16:28 also by Heiko without any explaination. Since that has not been used since then I have replaced it with a new Event: sysManualLocationSetEvent with a single numeric value which is the new (valid) room Id number - user scripts can capture this event if they want to know that the user has manually re-positioned the current player room in the 2D mapper. In passing: * Fixed Text font changing between docked and un-docked forms of the built-in map widget (when not incorporated into a console) - as it was not previously explicitly set it assumed the Application one whilst docked but the Qt System one when a free floating widget - and the two do not have to be the same. This fixes: https://bugs.launchpad.net/mudlet/+bug/1432841 . * Starts to fix https://bugs.launchpad.net/mudlet/+bug/1376511 by changing from use of obsolete QWheelEvent::delta() to QWheelEvent::angleDelta() in T2DMap::wheelEvent(...); will need duplicating in TTextEdit::wheelEvent(...) and GLWidget::wheelEvent(...) . * Adds the profile name to the Mapper dockable widget so that it's parentage can be determined when multiple profiles are active. Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2016-03-08 08:35:07 +00:00
ifs >> pA->xmaxEbene;
ifs >> pA->ymaxEbene;
ifs >> pA->xminEbene;
ifs >> pA->yminEbene;
} else {
Enhance: 2D Map Room Selection, better big map performance + other mods In situations when we check whether a room in an area both for internal purposes and when rooms on a mapper is selected, using QSet instead of a QList is faster in performance for large numbers of entries in set. As it reworks the mapper code it also fixes issue where the multi-room selection widget overwrites map info display - the latter is re-sized and re-positioned (and regains a semi-transparent background which helped to show this working during debugging!) The former is now: dynamically resized to only take up enough vertical space to show the selected rooms; also displays the associate room names if there are any, expanding the widget as required; sorts the display either by room name or number and in either direction. The mouse wheel handler is modified so that using the scroll wheel ONLY scrolls the list within the widget - previously (by default) once the end in either direction was hit the related events would be passed up the widget chain where it would otherwise invoke the 2D mapper's zoom in/out code. In modifying the zoom in/out code I have replaced the (obsoleted in Qt5.x) QWheelEvent::delta() method to use the QWheelEvent::angleDelta() method, using only the Y-component the latter provides. If the Control modifier is active the zoom value is modified by an extra x10 factor which is useful when working with large maps as otherwise the zooming rate is "slow" at high values - ideally the control should be logarithmic or exponential or some other "non-linear" algorithm to work more uniformly over the range of practical use cases. The code to paint the map info text has been revised also to use the mMapInfoRect which was being defined but NOT used. The info text now reports whether the room name is for the player room {set via the Lua command centerview(roomId)} or is one that is selected by mouse dragging - and if more than one room is selected by that indicates the count of rooms in the selection. In the case of multiple rooms being selected the room that single room context menu operations will act upon is highlighted by the same style of yellow target used to show the custom exit line destination but is drawn in a different point in the code so that it is drawn over the rooms. Because of the change to the way that multiple rooms are selected routines that use that information had to be revised - in doing so it was possible to improve the usability/operation of: T2DMap::slot_movePosition() T2DMap::slot_setCharacter() T2DMap::slot_spread() T2DMap::slot_shrink() T2DMap::slot_lockRoom(): T2DMap::slot_unlockRoom(): This method, also resurrected here to the 2D mapper context menu, as it is also affected by the changes: T2DMap::slot_setPlayerLocation() There was a slot_setPlayerLocation code that set a global lua variable mRoomSet and moved the player to that room Id (introduced in commit-c25faf4e 2012-05-04 07:44:36 by Heiko) but the corresponding 2D Mapper context menu item that called it was commented out and thus removed from the menu in commit-93f65962 2012-12-29 01:16:28 also by Heiko without any explaination. Since that has not been used since then I have replaced it with a new Event: sysManualLocationSetEvent with a single numeric value which is the new (valid) room Id number - user scripts can capture this event if they want to know that the user has manually re-positioned the current player room in the 2D mapper. In passing: * Fixed Text font changing between docked and un-docked forms of the built-in map widget (when not incorporated into a console) - as it was not previously explicitly set it assumed the Application one whilst docked but the Qt System one when a free floating widget - and the two do not have to be the same. This fixes: https://bugs.launchpad.net/mudlet/+bug/1432841 . * Starts to fix https://bugs.launchpad.net/mudlet/+bug/1376511 by changing from use of obsolete QWheelEvent::delta() to QWheelEvent::angleDelta() in T2DMap::wheelEvent(...); will need duplicating in TTextEdit::wheelEvent(...) and GLWidget::wheelEvent(...) . * Adds the profile name to the Mapper dockable widget so that it's parentage can be determined when multiple profiles are active. Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2016-03-08 08:35:07 +00:00
QMap<int, int> dummyMinMaxEbene;
ifs >> pA->xmaxEbene;
ifs >> pA->ymaxEbene;
ifs >> dummyMinMaxEbene;
ifs >> pA->xminEbene;
ifs >> pA->yminEbene;
ifs >> dummyMinMaxEbene;
}
ifs >> pA->pos;
ifs >> pA->isZone;
ifs >> pA->zoneAreaRef;
if (mVersion >= 17) {
Enhance: add Area & Map user data structures & Lua script access commands Whilst working on the XML importer for Map files I found that I wanted some where to store the data from attributes for tags that we don't use in Mudlet directly. For room related details I could use the TRoom::userData member but then I realised that there is nothing corresponding to Areas or for the Map overall. This separate commit provides these and the lua commands to interact with them - with functionality the same as the Room based one. Of course, as there is only ONE map there is no argument needed to select an instance for those commands. Of all the "room" user data commands replicated for "area" and "map" the only one NOT so done are get????UserDataKeys() as this is a bit pointless with a getAll????UserData() one from which the keys could be extracted from the returned table {???? being "Area" or "Map"}. Added to TLuaInterpreter class to provide following user script commands: searchAreaUserData((string)<key>[, (string)<value>]) setAreaUserData((number)<area Id>, (string)<key>, (string)<value>) clearAreaUserData((number)<area Id>) clearAreaUserDataItem((number)<area Id>, (string)<key>) getAreaUserData((number)<area Id>, (string)<key>) getAllAreaUserData((number)<area Id>) setMapUserData((string)<key>, (string)<value>) clearMapUserData((string)<key>) clearMapUserDataItem() getMapUserData((string)<key>) getAllMapUserData() Refactored TMap::serialize() to allow saving in different map file formats as defined by the constants TMap::mDefaultVersion, mMinVersion and mMaxVersion - if either of the last pair are less than or more than the first value respectively then a control on the "Special Options" tab of the profile preferences dialog will be enabled - the state of each value that is allowed is clearly indicated and it is defaulted appropriately. At present: TMap::mDefaultVersion is 16 (replaces #define CURRENT_MAP_VERSION) TMap::mMinVersion is also 16 TMap::mMaxVersion is 17 This means that the new user data areas will only persist (be saved) if that control is manually adjusted to 17 FOR EACH SESSION in this development version. When we get to a release version mDefaultVersion should be upped to 17 so that the release version uses the new format but can be manually downgraded to current (16) for those who want to share a map with users who have not upgraded - with the less of those new user data items - such users can do this by opening the profile preferences, downing this setting THEN using the SAVE MAP button and then restoring to the default value and SAVING AGAIN to a different name in the recommend format. Also renamed TMap::version to TMap::mVersion... ========================================================================== As this code requires the revision to the map file format that is coded for but only enabled manually the setter commands setAreaUserData(...) and setMapUserData(...) will both emit a warning message that the data written will not CURRENTLY be saved with the map the FIRST (and only the first) time they are used when the preference control has not been manually adjusted. ========================================================================== Also: Tweaked a recent, previous merged commit that set an optional minimum time for a Timer NOT to display it's contents every time it fires in debug output screen in value: Host::mTimerDebugOutputSuppressionInterval so that the QTimeEdit that controls it defaults to adjusting the "Seconds" time field rather than the default "Hours" one as that is the one that is most likely the one the user might wist to use. Also: The control this commit adds to the Profile Preferences dialog makes use of the QComboBox::currentData() method that was introduced in Qt5.2 - the minimum Qt library requirement in the qmake project file was revised to accomodate this - if builders wish to use a Qt5.x before this they will need to manually provide extra code to allocate an integer value from the range of values wanted/offered. Also: whilst cross-checking for the cmake project file I found the top level one was missing from the qmake project file - so have added it to that. HOWEVER I HAVE NOT FOUND A WAY TO REQUIRE THE CMAKE SYSTEM TO REQUIRE QT5.2 AS A MINIMUM WHICH THIS COMMIT REQUIRES. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> Conflicts: src/src.pro
2015-12-30 13:42:41 +00:00
ifs >> pA->mUserData;
}
mpRoomDB->restoreSingleArea(areaID, pA);
}
}
if (!mpRoomDB->getAreaMap().keys().contains(-1)) {
auto pDefaultA = new TArea(this, mpRoomDB);
mpRoomDB->restoreSingleArea(-1, pDefaultA);
QString defaultAreaInsertionMsg = tr("[ INFO ] - Default (reset) area (for rooms that have not been assigned to an\n"
"area) not found, adding reserved -1 id.");
appendErrorMsgWithNoLf(defaultAreaInsertionMsg, false);
if (mudlet::self()->showMapAuditErrors()) {
postMessage(defaultAreaInsertionMsg);
}
}
if (mVersion >= 18) {
// In version 18 we changed to store the "userRoom" for each profile
// so that when copied/shared between profiles they do not interfere
// with each other's saved value
ifs >> mRoomIdHash;
} else if (mVersion >= 12) {
int oldRoomId;
ifs >> oldRoomId;
mRoomIdHash[mpHost->getName()] = oldRoomId;
}
Enhance: add Area & Map user data structures & Lua script access commands Whilst working on the XML importer for Map files I found that I wanted some where to store the data from attributes for tags that we don't use in Mudlet directly. For room related details I could use the TRoom::userData member but then I realised that there is nothing corresponding to Areas or for the Map overall. This separate commit provides these and the lua commands to interact with them - with functionality the same as the Room based one. Of course, as there is only ONE map there is no argument needed to select an instance for those commands. Of all the "room" user data commands replicated for "area" and "map" the only one NOT so done are get????UserDataKeys() as this is a bit pointless with a getAll????UserData() one from which the keys could be extracted from the returned table {???? being "Area" or "Map"}. Added to TLuaInterpreter class to provide following user script commands: searchAreaUserData((string)<key>[, (string)<value>]) setAreaUserData((number)<area Id>, (string)<key>, (string)<value>) clearAreaUserData((number)<area Id>) clearAreaUserDataItem((number)<area Id>, (string)<key>) getAreaUserData((number)<area Id>, (string)<key>) getAllAreaUserData((number)<area Id>) setMapUserData((string)<key>, (string)<value>) clearMapUserData((string)<key>) clearMapUserDataItem() getMapUserData((string)<key>) getAllMapUserData() Refactored TMap::serialize() to allow saving in different map file formats as defined by the constants TMap::mDefaultVersion, mMinVersion and mMaxVersion - if either of the last pair are less than or more than the first value respectively then a control on the "Special Options" tab of the profile preferences dialog will be enabled - the state of each value that is allowed is clearly indicated and it is defaulted appropriately. At present: TMap::mDefaultVersion is 16 (replaces #define CURRENT_MAP_VERSION) TMap::mMinVersion is also 16 TMap::mMaxVersion is 17 This means that the new user data areas will only persist (be saved) if that control is manually adjusted to 17 FOR EACH SESSION in this development version. When we get to a release version mDefaultVersion should be upped to 17 so that the release version uses the new format but can be manually downgraded to current (16) for those who want to share a map with users who have not upgraded - with the less of those new user data items - such users can do this by opening the profile preferences, downing this setting THEN using the SAVE MAP button and then restoring to the default value and SAVING AGAIN to a different name in the recommend format. Also renamed TMap::version to TMap::mVersion... ========================================================================== As this code requires the revision to the map file format that is coded for but only enabled manually the setter commands setAreaUserData(...) and setMapUserData(...) will both emit a warning message that the data written will not CURRENTLY be saved with the map the FIRST (and only the first) time they are used when the preference control has not been manually adjusted. ========================================================================== Also: Tweaked a recent, previous merged commit that set an optional minimum time for a Timer NOT to display it's contents every time it fires in debug output screen in value: Host::mTimerDebugOutputSuppressionInterval so that the QTimeEdit that controls it defaults to adjusting the "Seconds" time field rather than the default "Hours" one as that is the one that is most likely the one the user might wist to use. Also: The control this commit adds to the Profile Preferences dialog makes use of the QComboBox::currentData() method that was introduced in Qt5.2 - the minimum Qt library requirement in the qmake project file was revised to accomodate this - if builders wish to use a Qt5.x before this they will need to manually provide extra code to allocate an integer value from the range of values wanted/offered. Also: whilst cross-checking for the cmake project file I found the top level one was missing from the qmake project file - so have added it to that. HOWEVER I HAVE NOT FOUND A WAY TO REQUIRE THE CMAKE SYSTEM TO REQUIRE QT5.2 AS A MINIMUM WHICH THIS COMMIT REQUIRES. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> Conflicts: src/src.pro
2015-12-30 13:42:41 +00:00
if (mVersion >= 11) {
2011-06-26 23:26:24 +02:00
int size;
ifs >> size; //size of mapLabels
int areaLabelCount = 0;
while (!ifs.atEnd() && areaLabelCount < size) {
2011-06-26 23:26:24 +02:00
int areaID;
int size_labels;
ifs >> size_labels;
ifs >> areaID;
int labelCount = 0;
QMap<int, TMapLabel> _map;
while (!ifs.atEnd() && labelCount < size_labels) {
2011-06-26 23:26:24 +02:00
int labelID;
ifs >> labelID;
TMapLabel label;
if (mVersion >= 12) {
ifs >> label.pos;
} else {
QPointF __label_pos;
ifs >> __label_pos;
label.pos = QVector3D(__label_pos.x(), __label_pos.y(), 0);
}
2011-06-26 23:26:24 +02:00
ifs >> label.pointer;
ifs >> label.size;
ifs >> label.text;
ifs >> label.fgColor;
ifs >> label.bgColor;
ifs >> label.pix;
if (mVersion >= 15) {
2012-12-29 02:16:28 +01:00
ifs >> label.noScaling;
ifs >> label.showOnTop;
}
_map.insert(labelID, label);
2011-06-26 23:26:24 +02:00
labelCount++;
}
mapLabels[areaID] = _map;
areaLabelCount++;
}
}
Enhance: add Area & Map user data structures & Lua script access commands Whilst working on the XML importer for Map files I found that I wanted some where to store the data from attributes for tags that we don't use in Mudlet directly. For room related details I could use the TRoom::userData member but then I realised that there is nothing corresponding to Areas or for the Map overall. This separate commit provides these and the lua commands to interact with them - with functionality the same as the Room based one. Of course, as there is only ONE map there is no argument needed to select an instance for those commands. Of all the "room" user data commands replicated for "area" and "map" the only one NOT so done are get????UserDataKeys() as this is a bit pointless with a getAll????UserData() one from which the keys could be extracted from the returned table {???? being "Area" or "Map"}. Added to TLuaInterpreter class to provide following user script commands: searchAreaUserData((string)<key>[, (string)<value>]) setAreaUserData((number)<area Id>, (string)<key>, (string)<value>) clearAreaUserData((number)<area Id>) clearAreaUserDataItem((number)<area Id>, (string)<key>) getAreaUserData((number)<area Id>, (string)<key>) getAllAreaUserData((number)<area Id>) setMapUserData((string)<key>, (string)<value>) clearMapUserData((string)<key>) clearMapUserDataItem() getMapUserData((string)<key>) getAllMapUserData() Refactored TMap::serialize() to allow saving in different map file formats as defined by the constants TMap::mDefaultVersion, mMinVersion and mMaxVersion - if either of the last pair are less than or more than the first value respectively then a control on the "Special Options" tab of the profile preferences dialog will be enabled - the state of each value that is allowed is clearly indicated and it is defaulted appropriately. At present: TMap::mDefaultVersion is 16 (replaces #define CURRENT_MAP_VERSION) TMap::mMinVersion is also 16 TMap::mMaxVersion is 17 This means that the new user data areas will only persist (be saved) if that control is manually adjusted to 17 FOR EACH SESSION in this development version. When we get to a release version mDefaultVersion should be upped to 17 so that the release version uses the new format but can be manually downgraded to current (16) for those who want to share a map with users who have not upgraded - with the less of those new user data items - such users can do this by opening the profile preferences, downing this setting THEN using the SAVE MAP button and then restoring to the default value and SAVING AGAIN to a different name in the recommend format. Also renamed TMap::version to TMap::mVersion... ========================================================================== As this code requires the revision to the map file format that is coded for but only enabled manually the setter commands setAreaUserData(...) and setMapUserData(...) will both emit a warning message that the data written will not CURRENTLY be saved with the map the FIRST (and only the first) time they are used when the preference control has not been manually adjusted. ========================================================================== Also: Tweaked a recent, previous merged commit that set an optional minimum time for a Timer NOT to display it's contents every time it fires in debug output screen in value: Host::mTimerDebugOutputSuppressionInterval so that the QTimeEdit that controls it defaults to adjusting the "Seconds" time field rather than the default "Hours" one as that is the one that is most likely the one the user might wist to use. Also: The control this commit adds to the Profile Preferences dialog makes use of the QComboBox::currentData() method that was introduced in Qt5.2 - the minimum Qt library requirement in the qmake project file was revised to accomodate this - if builders wish to use a Qt5.x before this they will need to manually provide extra code to allocate an integer value from the range of values wanted/offered. Also: whilst cross-checking for the cmake project file I found the top level one was missing from the qmake project file - so have added it to that. HOWEVER I HAVE NOT FOUND A WAY TO REQUIRE THE CMAKE SYSTEM TO REQUIRE QT5.2 AS A MINIMUM WHICH THIS COMMIT REQUIRES. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> Conflicts: src/src.pro
2015-12-30 13:42:41 +00:00
while (!ifs.atEnd()) {
2010-08-25 00:41:43 +02:00
int i;
ifs >> i;
auto pT = new TRoom(mpRoomDB);
pT->restore(ifs, i, mVersion);
mpRoomDB->restoreSingleRoom(i, pT);
2010-08-25 00:41:43 +02:00
}
Enhance: add Area & Map user data structures & Lua script access commands Whilst working on the XML importer for Map files I found that I wanted some where to store the data from attributes for tags that we don't use in Mudlet directly. For room related details I could use the TRoom::userData member but then I realised that there is nothing corresponding to Areas or for the Map overall. This separate commit provides these and the lua commands to interact with them - with functionality the same as the Room based one. Of course, as there is only ONE map there is no argument needed to select an instance for those commands. Of all the "room" user data commands replicated for "area" and "map" the only one NOT so done are get????UserDataKeys() as this is a bit pointless with a getAll????UserData() one from which the keys could be extracted from the returned table {???? being "Area" or "Map"}. Added to TLuaInterpreter class to provide following user script commands: searchAreaUserData((string)<key>[, (string)<value>]) setAreaUserData((number)<area Id>, (string)<key>, (string)<value>) clearAreaUserData((number)<area Id>) clearAreaUserDataItem((number)<area Id>, (string)<key>) getAreaUserData((number)<area Id>, (string)<key>) getAllAreaUserData((number)<area Id>) setMapUserData((string)<key>, (string)<value>) clearMapUserData((string)<key>) clearMapUserDataItem() getMapUserData((string)<key>) getAllMapUserData() Refactored TMap::serialize() to allow saving in different map file formats as defined by the constants TMap::mDefaultVersion, mMinVersion and mMaxVersion - if either of the last pair are less than or more than the first value respectively then a control on the "Special Options" tab of the profile preferences dialog will be enabled - the state of each value that is allowed is clearly indicated and it is defaulted appropriately. At present: TMap::mDefaultVersion is 16 (replaces #define CURRENT_MAP_VERSION) TMap::mMinVersion is also 16 TMap::mMaxVersion is 17 This means that the new user data areas will only persist (be saved) if that control is manually adjusted to 17 FOR EACH SESSION in this development version. When we get to a release version mDefaultVersion should be upped to 17 so that the release version uses the new format but can be manually downgraded to current (16) for those who want to share a map with users who have not upgraded - with the less of those new user data items - such users can do this by opening the profile preferences, downing this setting THEN using the SAVE MAP button and then restoring to the default value and SAVING AGAIN to a different name in the recommend format. Also renamed TMap::version to TMap::mVersion... ========================================================================== As this code requires the revision to the map file format that is coded for but only enabled manually the setter commands setAreaUserData(...) and setMapUserData(...) will both emit a warning message that the data written will not CURRENTLY be saved with the map the FIRST (and only the first) time they are used when the preference control has not been manually adjusted. ========================================================================== Also: Tweaked a recent, previous merged commit that set an optional minimum time for a Timer NOT to display it's contents every time it fires in debug output screen in value: Host::mTimerDebugOutputSuppressionInterval so that the QTimeEdit that controls it defaults to adjusting the "Seconds" time field rather than the default "Hours" one as that is the one that is most likely the one the user might wist to use. Also: The control this commit adds to the Profile Preferences dialog makes use of the QComboBox::currentData() method that was introduced in Qt5.2 - the minimum Qt library requirement in the qmake project file was revised to accomodate this - if builders wish to use a Qt5.x before this they will need to manually provide extra code to allocate an integer value from the range of values wanted/offered. Also: whilst cross-checking for the cmake project file I found the top level one was missing from the qmake project file - so have added it to that. HOWEVER I HAVE NOT FOUND A WAY TO REQUIRE THE CMAKE SYSTEM TO REQUIRE QT5.2 AS A MINIMUM WHICH THIS COMMIT REQUIRES. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> Conflicts: src/src.pro
2015-12-30 13:42:41 +00:00
2011-01-20 22:06:21 +01:00
customEnvColors[257] = mpHost->mRed_2;
customEnvColors[258] = mpHost->mGreen_2;
customEnvColors[259] = mpHost->mYellow_2;
customEnvColors[260] = mpHost->mBlue_2;
customEnvColors[261] = mpHost->mMagenta_2;
customEnvColors[262] = mpHost->mCyan_2;
customEnvColors[263] = mpHost->mWhite_2;
customEnvColors[264] = mpHost->mBlack_2;
customEnvColors[265] = mpHost->mLightRed_2;
customEnvColors[266] = mpHost->mLightGreen_2;
customEnvColors[267] = mpHost->mLightYellow_2;
customEnvColors[268] = mpHost->mLightBlue_2;
customEnvColors[269] = mpHost->mLightMagenta_2;
customEnvColors[270] = mpHost->mLightCyan_2;
customEnvColors[271] = mpHost->mLightWhite_2;
2011-01-22 19:23:56 +01:00
customEnvColors[272] = mpHost->mLightBlack_2;
Enhance: add Area & Map user data structures & Lua script access commands Whilst working on the XML importer for Map files I found that I wanted some where to store the data from attributes for tags that we don't use in Mudlet directly. For room related details I could use the TRoom::userData member but then I realised that there is nothing corresponding to Areas or for the Map overall. This separate commit provides these and the lua commands to interact with them - with functionality the same as the Room based one. Of course, as there is only ONE map there is no argument needed to select an instance for those commands. Of all the "room" user data commands replicated for "area" and "map" the only one NOT so done are get????UserDataKeys() as this is a bit pointless with a getAll????UserData() one from which the keys could be extracted from the returned table {???? being "Area" or "Map"}. Added to TLuaInterpreter class to provide following user script commands: searchAreaUserData((string)<key>[, (string)<value>]) setAreaUserData((number)<area Id>, (string)<key>, (string)<value>) clearAreaUserData((number)<area Id>) clearAreaUserDataItem((number)<area Id>, (string)<key>) getAreaUserData((number)<area Id>, (string)<key>) getAllAreaUserData((number)<area Id>) setMapUserData((string)<key>, (string)<value>) clearMapUserData((string)<key>) clearMapUserDataItem() getMapUserData((string)<key>) getAllMapUserData() Refactored TMap::serialize() to allow saving in different map file formats as defined by the constants TMap::mDefaultVersion, mMinVersion and mMaxVersion - if either of the last pair are less than or more than the first value respectively then a control on the "Special Options" tab of the profile preferences dialog will be enabled - the state of each value that is allowed is clearly indicated and it is defaulted appropriately. At present: TMap::mDefaultVersion is 16 (replaces #define CURRENT_MAP_VERSION) TMap::mMinVersion is also 16 TMap::mMaxVersion is 17 This means that the new user data areas will only persist (be saved) if that control is manually adjusted to 17 FOR EACH SESSION in this development version. When we get to a release version mDefaultVersion should be upped to 17 so that the release version uses the new format but can be manually downgraded to current (16) for those who want to share a map with users who have not upgraded - with the less of those new user data items - such users can do this by opening the profile preferences, downing this setting THEN using the SAVE MAP button and then restoring to the default value and SAVING AGAIN to a different name in the recommend format. Also renamed TMap::version to TMap::mVersion... ========================================================================== As this code requires the revision to the map file format that is coded for but only enabled manually the setter commands setAreaUserData(...) and setMapUserData(...) will both emit a warning message that the data written will not CURRENTLY be saved with the map the FIRST (and only the first) time they are used when the preference control has not been manually adjusted. ========================================================================== Also: Tweaked a recent, previous merged commit that set an optional minimum time for a Timer NOT to display it's contents every time it fires in debug output screen in value: Host::mTimerDebugOutputSuppressionInterval so that the QTimeEdit that controls it defaults to adjusting the "Seconds" time field rather than the default "Hours" one as that is the one that is most likely the one the user might wist to use. Also: The control this commit adds to the Profile Preferences dialog makes use of the QComboBox::currentData() method that was introduced in Qt5.2 - the minimum Qt library requirement in the qmake project file was revised to accomodate this - if builders wish to use a Qt5.x before this they will need to manually provide extra code to allocate an integer value from the range of values wanted/offered. Also: whilst cross-checking for the cmake project file I found the top level one was missing from the qmake project file - so have added it to that. HOWEVER I HAVE NOT FOUND A WAY TO REQUIRE THE CMAKE SYSTEM TO REQUIRE QT5.2 AS A MINIMUM WHICH THIS COMMIT REQUIRES. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> Conflicts: src/src.pro
2015-12-30 13:42:41 +00:00
QString okMsg = tr("[ INFO ] - Successfully read the map file (%1s), checking some\n"
"consistency details..." )
.arg(_time.nsecsElapsed() * 1.0e-9, 0, 'f', 2);
Revision: route most of map auditing messages to errors.txt file As the amount of messages produced by the new/improve map auditing/clean-up code can be large for old map files this commit causes them to be sent to a profile specific file that is already opened by the Host class but has not been used for some time. An option (a check-box) on the "map" tab of the "profile preferences" dialog controls whether the equivalent information is also shown on the profile's main console as in the past. If the option (a global one) which is saved between sessions/runs is NOT enabled then an advisory is sent to the console advising the user to review the file contents if a "significant" issue was detected. If it is enabled a similar message advising that the information has also been saved. In either case, as the file is appended to, and not rewritten each time, the message includes details of the first line of the report so that it can be located in the file. One difference between the on-screen and the file versions of the information is that the former puts up the issues as they are detected whereas the latter groups the information by subject, first the general overall issues, then the area ones, in order of the areas' id numbers and then the room ones, in room order. Following earlier discussions in these Pull Request I have attempted to edit all uses of the word "Id" in user visible places to be "id" instead. This threw up some other messages with issues in several files that I have tweaked here as well! Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2016-05-03 04:58:31 +01:00
postMessage(okMsg);
appendErrorMsgWithNoLf(okMsg);
if (canRestore) {
2010-08-25 00:41:43 +02:00
return true;
}
}
Enhance: add Area & Map user data structures & Lua script access commands Whilst working on the XML importer for Map files I found that I wanted some where to store the data from attributes for tags that we don't use in Mudlet directly. For room related details I could use the TRoom::userData member but then I realised that there is nothing corresponding to Areas or for the Map overall. This separate commit provides these and the lua commands to interact with them - with functionality the same as the Room based one. Of course, as there is only ONE map there is no argument needed to select an instance for those commands. Of all the "room" user data commands replicated for "area" and "map" the only one NOT so done are get????UserDataKeys() as this is a bit pointless with a getAll????UserData() one from which the keys could be extracted from the returned table {???? being "Area" or "Map"}. Added to TLuaInterpreter class to provide following user script commands: searchAreaUserData((string)<key>[, (string)<value>]) setAreaUserData((number)<area Id>, (string)<key>, (string)<value>) clearAreaUserData((number)<area Id>) clearAreaUserDataItem((number)<area Id>, (string)<key>) getAreaUserData((number)<area Id>, (string)<key>) getAllAreaUserData((number)<area Id>) setMapUserData((string)<key>, (string)<value>) clearMapUserData((string)<key>) clearMapUserDataItem() getMapUserData((string)<key>) getAllMapUserData() Refactored TMap::serialize() to allow saving in different map file formats as defined by the constants TMap::mDefaultVersion, mMinVersion and mMaxVersion - if either of the last pair are less than or more than the first value respectively then a control on the "Special Options" tab of the profile preferences dialog will be enabled - the state of each value that is allowed is clearly indicated and it is defaulted appropriately. At present: TMap::mDefaultVersion is 16 (replaces #define CURRENT_MAP_VERSION) TMap::mMinVersion is also 16 TMap::mMaxVersion is 17 This means that the new user data areas will only persist (be saved) if that control is manually adjusted to 17 FOR EACH SESSION in this development version. When we get to a release version mDefaultVersion should be upped to 17 so that the release version uses the new format but can be manually downgraded to current (16) for those who want to share a map with users who have not upgraded - with the less of those new user data items - such users can do this by opening the profile preferences, downing this setting THEN using the SAVE MAP button and then restoring to the default value and SAVING AGAIN to a different name in the recommend format. Also renamed TMap::version to TMap::mVersion... ========================================================================== As this code requires the revision to the map file format that is coded for but only enabled manually the setter commands setAreaUserData(...) and setMapUserData(...) will both emit a warning message that the data written will not CURRENTLY be saved with the map the FIRST (and only the first) time they are used when the preference control has not been manually adjusted. ========================================================================== Also: Tweaked a recent, previous merged commit that set an optional minimum time for a Timer NOT to display it's contents every time it fires in debug output screen in value: Host::mTimerDebugOutputSuppressionInterval so that the QTimeEdit that controls it defaults to adjusting the "Seconds" time field rather than the default "Hours" one as that is the one that is most likely the one the user might wist to use. Also: The control this commit adds to the Profile Preferences dialog makes use of the QComboBox::currentData() method that was introduced in Qt5.2 - the minimum Qt library requirement in the qmake project file was revised to accomodate this - if builders wish to use a Qt5.x before this they will need to manually provide extra code to allocate an integer value from the range of values wanted/offered. Also: whilst cross-checking for the cmake project file I found the top level one was missing from the qmake project file - so have added it to that. HOWEVER I HAVE NOT FOUND A WAY TO REQUIRE THE CMAKE SYSTEM TO REQUIRE QT5.2 AS A MINIMUM WHICH THIS COMMIT REQUIRES. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> Conflicts: src/src.pro
2015-12-30 13:42:41 +00:00
if ((!canRestore || entries.empty()) && downloadIfNotFound) {
2010-08-25 00:41:43 +02:00
QMessageBox msgBox;
if (mpHost->mUrl.contains(QStringLiteral("achaea.com"), Qt::CaseInsensitive) || mpHost->mUrl.contains(QStringLiteral("aetolia.com"), Qt::CaseInsensitive)
|| mpHost->mUrl.contains(QStringLiteral("imperian.com"), Qt::CaseInsensitive)
|| mpHost->mUrl.contains(QStringLiteral("lusternia.com"), Qt::CaseInsensitive)
|| mpHost->mUrl.contains(QStringLiteral("stickmud.com"), Qt::CaseInsensitive)) {
msgBox.setText(tr("No map found. Would you like to download the map or start your own?"));
QPushButton* yesButton = msgBox.addButton(tr("Download the map"), QMessageBox::ActionRole);
QPushButton* noButton = msgBox.addButton(tr("Start my own"), QMessageBox::ActionRole);
2010-08-25 00:41:43 +02:00
msgBox.exec();
if (msgBox.clickedButton() == yesButton) {
// no https support
if (mpHost->mUrl.contains(QStringLiteral("stickmud.com"), Qt::CaseInsensitive)) {
downloadMap(QStringLiteral("http://www.%1/maps/map.xml").arg(mpHost->mUrl));
} else {
downloadMap();
}
} else if (msgBox.clickedButton() == noButton) {
; //No-op to avoid unused "noButton"
}
2010-08-25 00:41:43 +02:00
}
}
Enhance: add Area & Map user data structures & Lua script access commands Whilst working on the XML importer for Map files I found that I wanted some where to store the data from attributes for tags that we don't use in Mudlet directly. For room related details I could use the TRoom::userData member but then I realised that there is nothing corresponding to Areas or for the Map overall. This separate commit provides these and the lua commands to interact with them - with functionality the same as the Room based one. Of course, as there is only ONE map there is no argument needed to select an instance for those commands. Of all the "room" user data commands replicated for "area" and "map" the only one NOT so done are get????UserDataKeys() as this is a bit pointless with a getAll????UserData() one from which the keys could be extracted from the returned table {???? being "Area" or "Map"}. Added to TLuaInterpreter class to provide following user script commands: searchAreaUserData((string)<key>[, (string)<value>]) setAreaUserData((number)<area Id>, (string)<key>, (string)<value>) clearAreaUserData((number)<area Id>) clearAreaUserDataItem((number)<area Id>, (string)<key>) getAreaUserData((number)<area Id>, (string)<key>) getAllAreaUserData((number)<area Id>) setMapUserData((string)<key>, (string)<value>) clearMapUserData((string)<key>) clearMapUserDataItem() getMapUserData((string)<key>) getAllMapUserData() Refactored TMap::serialize() to allow saving in different map file formats as defined by the constants TMap::mDefaultVersion, mMinVersion and mMaxVersion - if either of the last pair are less than or more than the first value respectively then a control on the "Special Options" tab of the profile preferences dialog will be enabled - the state of each value that is allowed is clearly indicated and it is defaulted appropriately. At present: TMap::mDefaultVersion is 16 (replaces #define CURRENT_MAP_VERSION) TMap::mMinVersion is also 16 TMap::mMaxVersion is 17 This means that the new user data areas will only persist (be saved) if that control is manually adjusted to 17 FOR EACH SESSION in this development version. When we get to a release version mDefaultVersion should be upped to 17 so that the release version uses the new format but can be manually downgraded to current (16) for those who want to share a map with users who have not upgraded - with the less of those new user data items - such users can do this by opening the profile preferences, downing this setting THEN using the SAVE MAP button and then restoring to the default value and SAVING AGAIN to a different name in the recommend format. Also renamed TMap::version to TMap::mVersion... ========================================================================== As this code requires the revision to the map file format that is coded for but only enabled manually the setter commands setAreaUserData(...) and setMapUserData(...) will both emit a warning message that the data written will not CURRENTLY be saved with the map the FIRST (and only the first) time they are used when the preference control has not been manually adjusted. ========================================================================== Also: Tweaked a recent, previous merged commit that set an optional minimum time for a Timer NOT to display it's contents every time it fires in debug output screen in value: Host::mTimerDebugOutputSuppressionInterval so that the QTimeEdit that controls it defaults to adjusting the "Seconds" time field rather than the default "Hours" one as that is the one that is most likely the one the user might wist to use. Also: The control this commit adds to the Profile Preferences dialog makes use of the QComboBox::currentData() method that was introduced in Qt5.2 - the minimum Qt library requirement in the qmake project file was revised to accomodate this - if builders wish to use a Qt5.x before this they will need to manually provide extra code to allocate an integer value from the range of values wanted/offered. Also: whilst cross-checking for the cmake project file I found the top level one was missing from the qmake project file - so have added it to that. HOWEVER I HAVE NOT FOUND A WAY TO REQUIRE THE CMAKE SYSTEM TO REQUIRE QT5.2 AS A MINIMUM WHICH THIS COMMIT REQUIRES. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> Conflicts: src/src.pro
2015-12-30 13:42:41 +00:00
return canRestore; //FIXME
2010-08-25 00:41:43 +02:00
}
// Reads the newest map file from the profile and retrieves some stats and data,
// including the current player room - was mRoomId in 12 to pre-18 map files and
// is in mRoomIdHash since then so that it can be reinserted into a map that is
// copied across (if the room STILL exists! This is to avoid a replacement map
// (copied/shared) from one profile to another from repositioning the other
// player location. Though this is written as a member function it is intended
// also for use to retrieve details from maps from OTHER profiles, importantly
// it does (or should) NOT interact with this TMap instance...!
bool TMap::retrieveMapFileStats(QString profile, QString* latestFileName = nullptr, int* fileVersion = nullptr, int* roomId = nullptr, int* areaCount = nullptr, int* roomCount = nullptr)
{
if (profile.isEmpty()) {
return false;
}
QString folder;
QStringList entries;
Refactor: reduce use of raw string literals for directories and file paths Using a static method means that we can centralise the generation of strings used to access parts of the file system used to hold Mudlet user data - which may be useful if we change them for - say running from a thumb-drive or just to use an OS specific location for them. {Using a ".config/mudlet" sub-directory on Windows is not quite how that OS expects things to be done...!} This also reduces the number of raw strings that will have to be wrapped in QStringLiteral(...) and the like for forthcoming I18n work. Also: * The use of "mudlet-data" as a windows symlink sub-directory to ".config/mudlet" in the user home directory may not work because the Qt Documentation suggests that a ".lnk" extension is required - this commit adds that FOR THAT OS ONLY. * Previous code placed (only some - for an unexplained reason not all the files were being copied) the DejaVu fonts that we include in the resources directly into the main mudlet user data folder - but the included documentation including the COPYRIGHT.TXT and other files ONLY relate to those font files and NOT to Mudlet as a whole. I have taken the liberty of moving and loading them from a ./fonts/ subdirectory which makes more sense. I have noted that, at least, the Debian Linux packager actually removes the font files from their configuration because they already include a shared system wide copy of the same fonts and in a much newer (2.37 at present) version compared to the 1.10 that we bundle - perhaps our code needs to check for the existence/availability of the fonts before we try to load ours into the Mudlet application at run-time! Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2017-09-18 16:23:57 +01:00
folder = mudlet::getMudletPath(mudlet::profileMapsPath, profile);
QDir dir(folder);
dir.setSorting(QDir::Time);
entries = dir.entryList(QDir::Files | QDir::NoDotAndDotDot, QDir::Time);
if (entries.isEmpty()) {
return false;
}
// As the files are sorted by time this gets the latest one
Refactor: reduce use of raw string literals for directories and file paths Using a static method means that we can centralise the generation of strings used to access parts of the file system used to hold Mudlet user data - which may be useful if we change them for - say running from a thumb-drive or just to use an OS specific location for them. {Using a ".config/mudlet" sub-directory on Windows is not quite how that OS expects things to be done...!} This also reduces the number of raw strings that will have to be wrapped in QStringLiteral(...) and the like for forthcoming I18n work. Also: * The use of "mudlet-data" as a windows symlink sub-directory to ".config/mudlet" in the user home directory may not work because the Qt Documentation suggests that a ".lnk" extension is required - this commit adds that FOR THAT OS ONLY. * Previous code placed (only some - for an unexplained reason not all the files were being copied) the DejaVu fonts that we include in the resources directly into the main mudlet user data folder - but the included documentation including the COPYRIGHT.TXT and other files ONLY relate to those font files and NOT to Mudlet as a whole. I have taken the liberty of moving and loading them from a ./fonts/ subdirectory which makes more sense. I have noted that, at least, the Debian Linux packager actually removes the font files from their configuration because they already include a shared system wide copy of the same fonts and in a much newer (2.37 at present) version compared to the 1.10 that we bundle - perhaps our code needs to check for the existence/availability of the fonts before we try to load ours into the Mudlet application at run-time! Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2017-09-18 16:23:57 +01:00
QFile file(QStringLiteral("%1/%2").arg(folder, entries.at(0)));
if (!file.open(QFile::ReadOnly)) {
QString errMsg = tr(R"([ ERROR ] - Unable to open (for reading) map file: "%1"!)").arg(file.fileName());
appendErrorMsg(errMsg, false);
postMessage(errMsg);
return false;
}
if (latestFileName) {
*latestFileName = file.fileName();
}
int otherProfileVersion = 0;
QDataStream ifs(&file);
ifs >> otherProfileVersion;
QString infoMsg = tr(R"([ INFO ] - Checking map file: "%1", format version:%2...)").arg(file.fileName()).arg(otherProfileVersion);
appendErrorMsg(infoMsg, false);
if (mudlet::self()->showMapAuditErrors()) {
postMessage(infoMsg);
Revision: route most of map auditing messages to errors.txt file As the amount of messages produced by the new/improve map auditing/clean-up code can be large for old map files this commit causes them to be sent to a profile specific file that is already opened by the Host class but has not been used for some time. An option (a check-box) on the "map" tab of the "profile preferences" dialog controls whether the equivalent information is also shown on the profile's main console as in the past. If the option (a global one) which is saved between sessions/runs is NOT enabled then an advisory is sent to the console advising the user to review the file contents if a "significant" issue was detected. If it is enabled a similar message advising that the information has also been saved. In either case, as the file is appended to, and not rewritten each time, the message includes details of the first line of the report so that it can be located in the file. One difference between the on-screen and the file versions of the information is that the former puts up the issues as they are detected whereas the latter groups the information by subject, first the general overall issues, then the area ones, in order of the areas' id numbers and then the room ones, in room order. Following earlier discussions in these Pull Request I have attempted to edit all uses of the word "Id" in user visible places to be "id" instead. This threw up some other messages with issues in several files that I have tweaked here as well! Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2016-05-03 04:58:31 +01:00
}
if (otherProfileVersion > mDefaultVersion) {
if (QByteArray(APP_BUILD).isEmpty()) {
// This is a release version - should not support any map file versions higher that it was built for
if (fileVersion) {
*fileVersion = otherProfileVersion;
}
file.close();
return true;
} else {
// Is a development version so check against mMaxVersion
if (otherProfileVersion > mMaxVersion) {
// Oh dear, can't handle THIS
if (fileVersion) {
*fileVersion = otherProfileVersion;
}
file.close();
return true;
} else {
if (fileVersion) {
*fileVersion = otherProfileVersion;
}
}
}
} else {
if (fileVersion) {
*fileVersion = otherProfileVersion;
}
}
if (otherProfileVersion >= 4) {
// envColorMap
QMap<int, int> _dummyQMapIntInt;
ifs >> _dummyQMapIntInt;
// AreaNamesMap
QMap<int, QString> _dummyQMapIntQString;
ifs >> _dummyQMapIntQString;
}
if (otherProfileVersion >= 5) {
// customEnvColors
QMap<int, QColor> _dummyQMapIntQColor;
ifs >> _dummyQMapIntQColor;
}
if (otherProfileVersion >= 7) {
// hashTable
QHash<QString, int> _dummyQHashQStringInt;
ifs >> _dummyQHashQStringInt;
}
if (otherProfileVersion >= 17) {
// userMapData
QMap<QString, QString> _dummyQMapQStringQString;
ifs >> _dummyQMapQStringQString;
}
if (otherProfileVersion >= 14) {
int areaSize;
ifs >> areaSize;
if (areaCount) {
*areaCount = areaSize;
}
// read each area
for (int i = 0; i < areaSize; i++) {
TArea pA(nullptr, nullptr);
int areaID;
ifs >> areaID;
ifs >> pA.rooms;
ifs >> pA.zLevels;
ifs >> pA.exits;
ifs >> pA.gridMode;
ifs >> pA.max_x;
ifs >> pA.max_y;
ifs >> pA.max_z;
ifs >> pA.min_x;
ifs >> pA.min_y;
ifs >> pA.min_z;
ifs >> pA.span;
if (otherProfileVersion >= 17) {
ifs >> pA.xmaxEbene;
ifs >> pA.ymaxEbene;
ifs >> pA.xminEbene;
ifs >> pA.yminEbene;
} else {
QMap<int, int> dummyMinMaxEbene;
ifs >> pA.xmaxEbene;
ifs >> pA.ymaxEbene;
ifs >> dummyMinMaxEbene;
ifs >> pA.xminEbene;
ifs >> pA.yminEbene;
ifs >> dummyMinMaxEbene;
}
ifs >> pA.pos;
ifs >> pA.isZone;
ifs >> pA.zoneAreaRef;
if (otherProfileVersion >= 17) {
ifs >> pA.mUserData;
}
}
}
if (otherProfileVersion >= 18) {
// In version 18 we changed to store the "userRoom" for each profile
// so that when copied/shared between profiles they do not interfere
// with each other's saved value
QHash<QString, int> _dummyQHashQStringInt;
ifs >> _dummyQHashQStringInt;
if (roomId) {
*roomId = _dummyQHashQStringInt.value(profile);
}
} else if (otherProfileVersion >= 12) {
int oldRoomId;
ifs >> oldRoomId;
if (roomId) {
*roomId = oldRoomId;
}
} else {
if (roomId) {
*roomId = -1; // Not found value
}
}
if (otherProfileVersion >= 11) {
int size;
ifs >> size; //size of mapLabels
int areaLabelCount = 0;
while (!ifs.atEnd() && areaLabelCount < size) {
int areaID;
int size_labels;
ifs >> size_labels;
ifs >> areaID;
int labelCount = 0;
while (!ifs.atEnd() && labelCount < size_labels) {
int labelID;
ifs >> labelID;
TMapLabel label;
if (otherProfileVersion >= 12) {
ifs >> label.pos;
} else {
QPointF __label_pos;
ifs >> __label_pos;
label.pos = QVector3D(__label_pos.x(), __label_pos.y(), 0);
}
ifs >> label.pointer;
ifs >> label.size;
ifs >> label.text;
ifs >> label.fgColor;
ifs >> label.bgColor;
ifs >> label.pix;
if (otherProfileVersion >= 15) {
ifs >> label.noScaling;
ifs >> label.showOnTop;
}
labelCount++;
}
areaLabelCount++;
}
}
TRoom _pT(nullptr);
QSet<int> _dummyRoomIdSet;
while (!ifs.atEnd()) {
int i;
ifs >> i;
_pT.restore(ifs, i, otherProfileVersion);
// Can't do mpRoomDB->restoreSingleRoom( ifs, i, pT ) as it would mess up
// this TMap::mpRoomDB
// So emulate using _dummyRoomIdSet
if (i > 0 && !_dummyRoomIdSet.contains(i)) {
_dummyRoomIdSet.insert(i);
}
}
if (roomCount) {
*roomCount = _dummyRoomIdSet.count();
}
return true;
}
2010-08-25 00:41:43 +02:00
int TMap::createMapLabel(int area, QString text, float x, float y, float z, QColor fg, QColor bg, bool showOnTop, bool noScaling, qreal zoom, int fontSize)
2011-06-26 15:23:37 +02:00
{
if (!mpRoomDB->getArea(area)) {
return -1;
}
2011-06-26 15:23:37 +02:00
TMapLabel label;
label.text = text;
label.bgColor = bg;
label.bgColor.setAlpha(50);
label.fgColor = fg;
label.size = QSizeF(100, 100);
label.pos = QVector3D(x, y, z);
label.showOnTop = showOnTop;
label.noScaling = noScaling;
if (label.text.length() < 1) {
return -1;
}
QRectF lr = QRectF(0, 0, 1000, 1000);
QPixmap pix(lr.size().toSize());
pix.fill(Qt::transparent);
QPainter lp(&pix);
lp.fillRect(lr, label.bgColor);
QPen lpen;
lpen.setColor(label.fgColor);
QFont font;
font.setPointSize(fontSize); //good: font size = 50, zoom = 30.0
lp.setRenderHint(QPainter::TextAntialiasing, true);
lp.setPen(lpen);
lp.setFont(font);
QRectF br;
lp.drawText(lr, Qt::AlignLeft | Qt::AlignTop, label.text, &br);
label.size = br.normalized().size();
label.pix = pix.copy(br.normalized().topLeft().x(), br.normalized().topLeft().y(), br.normalized().width(), br.normalized().height());
QSizeF s = QSizeF(label.size.width() / zoom, label.size.height() / zoom);
label.size = s;
label.clickSize = s;
if (!mpRoomDB->getArea(area)) {
return -1;
}
2017-04-17 21:35:44 -07:00
int label_id;
// No labels exist for this area, so start from zero.
if (!mapLabels.contains(area)) {
2011-06-26 23:26:24 +02:00
QMap<int, TMapLabel> m;
2017-04-17 21:35:44 -07:00
label_id = 0;
m[label_id] = label;
2011-06-26 23:26:24 +02:00
mapLabels[area] = m;
2017-04-17 21:35:44 -07:00
} else {
label_id = createMapLabelID(area);
if (label_id > -1) {
mapLabels[area].insert(label_id, label);
}
2011-06-26 23:26:24 +02:00
}
2017-04-17 21:35:44 -07:00
if (mpMapper) {
mpMapper->mp2dMap->update();
}
return label_id;
2011-06-26 15:23:37 +02:00
}
int TMap::createMapImageLabel(int area, QString imagePath, float x, float y, float z, float width, float height, float zoom, bool showOnTop, bool noScaling)
{
if (!mpRoomDB->getArea(area)) {
return -1;
}
TMapLabel label;
label.size = QSizeF(width, height);
label.pos = QVector3D(x, y, z);
label.showOnTop = showOnTop;
label.noScaling = noScaling;
QRectF drawRect = QRectF(0, 0, width * zoom, height * zoom);
QPixmap imagePixmap = QPixmap(imagePath);
QPixmap pix = QPixmap(drawRect.size().toSize());
pix.fill(Qt::transparent);
QPainter lp(&pix);
lp.drawPixmap(QPoint(0, 0), imagePixmap.scaled(drawRect.size().toSize()));
label.size = QSizeF(width, height);
label.pix = pix;
2017-04-16 22:33:35 -07:00
if (!mpRoomDB->getArea(area)) {
return -1;
}
int label_id;
// No labels exist for this area, so start from zero.
if (!mapLabels.contains(area)) {
QMap<int, TMapLabel> m;
2017-04-16 22:33:35 -07:00
label_id = 0;
m[label_id] = label;
mapLabels[area] = m;
2017-04-16 22:33:35 -07:00
} else {
label_id = createMapLabelID(area);
if (label_id > -1) {
mapLabels[area].insert(label_id, label);
}
}
2017-04-16 22:33:35 -07:00
if (mpMapper) {
mpMapper->mp2dMap->update();
}
return label_id;
}
int TMap::createMapLabelID(int area)
{
if (mapLabels.contains(area)) {
QList<int> idList = mapLabels[area].keys();
int id = 0;
while (id >= 0) {
if (!idList.contains(id)) {
return id;
}
id++;
}
}
return -1;
}
void TMap::deleteMapLabel(int area, int labelID)
2011-06-26 15:23:37 +02:00
{
if (!mpRoomDB->getArea(area)) {
return;
}
if (!mapLabels.contains(area)) {
return;
}
if (!mapLabels[area].contains(labelID)) {
return;
}
mapLabels[area].remove(labelID);
if (mpMapper) {
mpMapper->mp2dMap->update();
}
2011-06-26 15:23:37 +02:00
}
void TMap::postMessage(const QString text)
{
mStoredMessages.append(text);
Host* pHost = mpHost;
if (pHost) {
while (!mStoredMessages.isEmpty()) {
pHost->postMessage(mStoredMessages.takeFirst());
}
}
}
Enhance: make area selection widget centre map on room in middle of area As discussed in http://forums.mudlet.org/viewtopic.php?f=13&t=4818#p24498 this commit improves the way the centre of the view is selected when the area selection widget is used to (temporarily) show a view of a different area: * A) if the selected area has the same z-coordinate as the current view in the (2D) mapper then the mean coordinate of all the rooms on THAT level is calculated and then the room nearest to that is chosen to be at the centre of the view in the selected area. * B) if the selected area does not have any rooms on the same level then the level with the MOST rooms (and the lowest z coordinate if there are ties) is chosen and the room closest to the mean again selected. * C) if there are NOT rooms in the area then the view is centred on the origin. * D) if (after using the control more than once OR even if NOT) the original area is selected then the view snaps back to the current player room (this can be used to recenter on that if the scroll buttons have been used to offset the view!) The center of view position is made from code within the 2D mapper - but there is no need to do the same for the 3D one - instead the area ID and position is passed up to the TMap class instance which forwards the details to the 3D mapper. The bottom line is that (unless it is an empty area) a reasonable choice of room is ALWAYS displayed in the centre of the map when the area is changed manually (and the 2 and 3D maps will be centred on the same room). Code associated with loading maps has been refactored in an attempt to ensure that the area selection widget is set to the correct value before the first use by the user - there was four places where the map file was being loaded (although the one in the Host class constructor seems unnecessary - and problematic to handle as the Host class is instantiated before the mapper widget is created!) I *think* I have got it straight now but some testing in the map down load from server case may need a check to see that I have not broken anything. Also: * have tweaked the map information display to change the text format to emphasise when it reflects details of a selection (the text turns a bit orange and is written BOLD) or if the player room (which is what is referred to if NO rooms are selected) is in this area (the data is written in BOLD) or is not in the current area shown (the data is written in ITALICS and not bold). Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2016-04-28 23:48:08 +01:00
// Used by the 2D mapper to send view center coordinates to 3D one
void TMap::set3DViewCenter(const int areaId, const int xPos, const int yPos, const int zPos)
Enhance: make area selection widget centre map on room in middle of area As discussed in http://forums.mudlet.org/viewtopic.php?f=13&t=4818#p24498 this commit improves the way the centre of the view is selected when the area selection widget is used to (temporarily) show a view of a different area: * A) if the selected area has the same z-coordinate as the current view in the (2D) mapper then the mean coordinate of all the rooms on THAT level is calculated and then the room nearest to that is chosen to be at the centre of the view in the selected area. * B) if the selected area does not have any rooms on the same level then the level with the MOST rooms (and the lowest z coordinate if there are ties) is chosen and the room closest to the mean again selected. * C) if there are NOT rooms in the area then the view is centred on the origin. * D) if (after using the control more than once OR even if NOT) the original area is selected then the view snaps back to the current player room (this can be used to recenter on that if the scroll buttons have been used to offset the view!) The center of view position is made from code within the 2D mapper - but there is no need to do the same for the 3D one - instead the area ID and position is passed up to the TMap class instance which forwards the details to the 3D mapper. The bottom line is that (unless it is an empty area) a reasonable choice of room is ALWAYS displayed in the centre of the map when the area is changed manually (and the 2 and 3D maps will be centred on the same room). Code associated with loading maps has been refactored in an attempt to ensure that the area selection widget is set to the correct value before the first use by the user - there was four places where the map file was being loaded (although the one in the Host class constructor seems unnecessary - and problematic to handle as the Host class is instantiated before the mapper widget is created!) I *think* I have got it straight now but some testing in the map down load from server case may need a check to see that I have not broken anything. Also: * have tweaked the map information display to change the text format to emphasise when it reflects details of a selection (the text turns a bit orange and is written BOLD) or if the player room (which is what is referred to if NO rooms are selected) is in this area (the data is written in BOLD) or is not in the current area shown (the data is written in ITALICS and not bold). Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2016-04-28 23:48:08 +01:00
{
mpM->setViewCenter(areaId, xPos, yPos, zPos);
Enhance: make area selection widget centre map on room in middle of area As discussed in http://forums.mudlet.org/viewtopic.php?f=13&t=4818#p24498 this commit improves the way the centre of the view is selected when the area selection widget is used to (temporarily) show a view of a different area: * A) if the selected area has the same z-coordinate as the current view in the (2D) mapper then the mean coordinate of all the rooms on THAT level is calculated and then the room nearest to that is chosen to be at the centre of the view in the selected area. * B) if the selected area does not have any rooms on the same level then the level with the MOST rooms (and the lowest z coordinate if there are ties) is chosen and the room closest to the mean again selected. * C) if there are NOT rooms in the area then the view is centred on the origin. * D) if (after using the control more than once OR even if NOT) the original area is selected then the view snaps back to the current player room (this can be used to recenter on that if the scroll buttons have been used to offset the view!) The center of view position is made from code within the 2D mapper - but there is no need to do the same for the 3D one - instead the area ID and position is passed up to the TMap class instance which forwards the details to the 3D mapper. The bottom line is that (unless it is an empty area) a reasonable choice of room is ALWAYS displayed in the centre of the map when the area is changed manually (and the 2 and 3D maps will be centred on the same room). Code associated with loading maps has been refactored in an attempt to ensure that the area selection widget is set to the correct value before the first use by the user - there was four places where the map file was being loaded (although the one in the Host class constructor seems unnecessary - and problematic to handle as the Host class is instantiated before the mapper widget is created!) I *think* I have got it straight now but some testing in the map down load from server case may need a check to see that I have not broken anything. Also: * have tweaked the map information display to change the text format to emphasise when it reflects details of a selection (the text turns a bit orange and is written BOLD) or if the player room (which is what is referred to if NO rooms are selected) is in this area (the data is written in BOLD) or is not in the current area shown (the data is written in ITALICS and not bold). Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2016-04-28 23:48:08 +01:00
}
Revision: route most of map auditing messages to errors.txt file As the amount of messages produced by the new/improve map auditing/clean-up code can be large for old map files this commit causes them to be sent to a profile specific file that is already opened by the Host class but has not been used for some time. An option (a check-box) on the "map" tab of the "profile preferences" dialog controls whether the equivalent information is also shown on the profile's main console as in the past. If the option (a global one) which is saved between sessions/runs is NOT enabled then an advisory is sent to the console advising the user to review the file contents if a "significant" issue was detected. If it is enabled a similar message advising that the information has also been saved. In either case, as the file is appended to, and not rewritten each time, the message includes details of the first line of the report so that it can be located in the file. One difference between the on-screen and the file versions of the information is that the former puts up the issues as they are detected whereas the latter groups the information by subject, first the general overall issues, then the area ones, in order of the areas' id numbers and then the room ones, in room order. Following earlier discussions in these Pull Request I have attempted to edit all uses of the word "Id" in user visible places to be "id" instead. This threw up some other messages with issues in several files that I have tweaked here as well! Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2016-05-03 04:58:31 +01:00
void TMap::appendRoomErrorMsg(const int roomId, const QString msg, const bool isToSetFileViewingRecommended)
Revision: route most of map auditing messages to errors.txt file As the amount of messages produced by the new/improve map auditing/clean-up code can be large for old map files this commit causes them to be sent to a profile specific file that is already opened by the Host class but has not been used for some time. An option (a check-box) on the "map" tab of the "profile preferences" dialog controls whether the equivalent information is also shown on the profile's main console as in the past. If the option (a global one) which is saved between sessions/runs is NOT enabled then an advisory is sent to the console advising the user to review the file contents if a "significant" issue was detected. If it is enabled a similar message advising that the information has also been saved. In either case, as the file is appended to, and not rewritten each time, the message includes details of the first line of the report so that it can be located in the file. One difference between the on-screen and the file versions of the information is that the former puts up the issues as they are detected whereas the latter groups the information by subject, first the general overall issues, then the area ones, in order of the areas' id numbers and then the room ones, in room order. Following earlier discussions in these Pull Request I have attempted to edit all uses of the word "Id" in user visible places to be "id" instead. This threw up some other messages with issues in several files that I have tweaked here as well! Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2016-05-03 04:58:31 +01:00
{
mMapAuditRoomErrors[roomId].append(msg);
Revision: route most of map auditing messages to errors.txt file As the amount of messages produced by the new/improve map auditing/clean-up code can be large for old map files this commit causes them to be sent to a profile specific file that is already opened by the Host class but has not been used for some time. An option (a check-box) on the "map" tab of the "profile preferences" dialog controls whether the equivalent information is also shown on the profile's main console as in the past. If the option (a global one) which is saved between sessions/runs is NOT enabled then an advisory is sent to the console advising the user to review the file contents if a "significant" issue was detected. If it is enabled a similar message advising that the information has also been saved. In either case, as the file is appended to, and not rewritten each time, the message includes details of the first line of the report so that it can be located in the file. One difference between the on-screen and the file versions of the information is that the former puts up the issues as they are detected whereas the latter groups the information by subject, first the general overall issues, then the area ones, in order of the areas' id numbers and then the room ones, in room order. Following earlier discussions in these Pull Request I have attempted to edit all uses of the word "Id" in user visible places to be "id" instead. This threw up some other messages with issues in several files that I have tweaked here as well! Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2016-05-03 04:58:31 +01:00
mIsFileViewingRecommended = isToSetFileViewingRecommended ? true : mIsFileViewingRecommended;
}
void TMap::appendAreaErrorMsg(const int areaId, const QString msg, const bool isToSetFileViewingRecommended)
Revision: route most of map auditing messages to errors.txt file As the amount of messages produced by the new/improve map auditing/clean-up code can be large for old map files this commit causes them to be sent to a profile specific file that is already opened by the Host class but has not been used for some time. An option (a check-box) on the "map" tab of the "profile preferences" dialog controls whether the equivalent information is also shown on the profile's main console as in the past. If the option (a global one) which is saved between sessions/runs is NOT enabled then an advisory is sent to the console advising the user to review the file contents if a "significant" issue was detected. If it is enabled a similar message advising that the information has also been saved. In either case, as the file is appended to, and not rewritten each time, the message includes details of the first line of the report so that it can be located in the file. One difference between the on-screen and the file versions of the information is that the former puts up the issues as they are detected whereas the latter groups the information by subject, first the general overall issues, then the area ones, in order of the areas' id numbers and then the room ones, in room order. Following earlier discussions in these Pull Request I have attempted to edit all uses of the word "Id" in user visible places to be "id" instead. This threw up some other messages with issues in several files that I have tweaked here as well! Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2016-05-03 04:58:31 +01:00
{
mMapAuditAreaErrors[areaId].append(msg);
Revision: route most of map auditing messages to errors.txt file As the amount of messages produced by the new/improve map auditing/clean-up code can be large for old map files this commit causes them to be sent to a profile specific file that is already opened by the Host class but has not been used for some time. An option (a check-box) on the "map" tab of the "profile preferences" dialog controls whether the equivalent information is also shown on the profile's main console as in the past. If the option (a global one) which is saved between sessions/runs is NOT enabled then an advisory is sent to the console advising the user to review the file contents if a "significant" issue was detected. If it is enabled a similar message advising that the information has also been saved. In either case, as the file is appended to, and not rewritten each time, the message includes details of the first line of the report so that it can be located in the file. One difference between the on-screen and the file versions of the information is that the former puts up the issues as they are detected whereas the latter groups the information by subject, first the general overall issues, then the area ones, in order of the areas' id numbers and then the room ones, in room order. Following earlier discussions in these Pull Request I have attempted to edit all uses of the word "Id" in user visible places to be "id" instead. This threw up some other messages with issues in several files that I have tweaked here as well! Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2016-05-03 04:58:31 +01:00
mIsFileViewingRecommended = isToSetFileViewingRecommended ? true : mIsFileViewingRecommended;
}
void TMap::appendErrorMsg(const QString msg, const bool isToSetFileViewingRecommended)
Revision: route most of map auditing messages to errors.txt file As the amount of messages produced by the new/improve map auditing/clean-up code can be large for old map files this commit causes them to be sent to a profile specific file that is already opened by the Host class but has not been used for some time. An option (a check-box) on the "map" tab of the "profile preferences" dialog controls whether the equivalent information is also shown on the profile's main console as in the past. If the option (a global one) which is saved between sessions/runs is NOT enabled then an advisory is sent to the console advising the user to review the file contents if a "significant" issue was detected. If it is enabled a similar message advising that the information has also been saved. In either case, as the file is appended to, and not rewritten each time, the message includes details of the first line of the report so that it can be located in the file. One difference between the on-screen and the file versions of the information is that the former puts up the issues as they are detected whereas the latter groups the information by subject, first the general overall issues, then the area ones, in order of the areas' id numbers and then the room ones, in room order. Following earlier discussions in these Pull Request I have attempted to edit all uses of the word "Id" in user visible places to be "id" instead. This threw up some other messages with issues in several files that I have tweaked here as well! Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2016-05-03 04:58:31 +01:00
{
mMapAuditErrors.append(msg);
Revision: route most of map auditing messages to errors.txt file As the amount of messages produced by the new/improve map auditing/clean-up code can be large for old map files this commit causes them to be sent to a profile specific file that is already opened by the Host class but has not been used for some time. An option (a check-box) on the "map" tab of the "profile preferences" dialog controls whether the equivalent information is also shown on the profile's main console as in the past. If the option (a global one) which is saved between sessions/runs is NOT enabled then an advisory is sent to the console advising the user to review the file contents if a "significant" issue was detected. If it is enabled a similar message advising that the information has also been saved. In either case, as the file is appended to, and not rewritten each time, the message includes details of the first line of the report so that it can be located in the file. One difference between the on-screen and the file versions of the information is that the former puts up the issues as they are detected whereas the latter groups the information by subject, first the general overall issues, then the area ones, in order of the areas' id numbers and then the room ones, in room order. Following earlier discussions in these Pull Request I have attempted to edit all uses of the word "Id" in user visible places to be "id" instead. This threw up some other messages with issues in several files that I have tweaked here as well! Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2016-05-03 04:58:31 +01:00
mIsFileViewingRecommended = isToSetFileViewingRecommended ? true : mIsFileViewingRecommended;
}
void TMap::appendErrorMsgWithNoLf(const QString msg, const bool isToSetFileViewingRecommended)
Revision: route most of map auditing messages to errors.txt file As the amount of messages produced by the new/improve map auditing/clean-up code can be large for old map files this commit causes them to be sent to a profile specific file that is already opened by the Host class but has not been used for some time. An option (a check-box) on the "map" tab of the "profile preferences" dialog controls whether the equivalent information is also shown on the profile's main console as in the past. If the option (a global one) which is saved between sessions/runs is NOT enabled then an advisory is sent to the console advising the user to review the file contents if a "significant" issue was detected. If it is enabled a similar message advising that the information has also been saved. In either case, as the file is appended to, and not rewritten each time, the message includes details of the first line of the report so that it can be located in the file. One difference between the on-screen and the file versions of the information is that the former puts up the issues as they are detected whereas the latter groups the information by subject, first the general overall issues, then the area ones, in order of the areas' id numbers and then the room ones, in room order. Following earlier discussions in these Pull Request I have attempted to edit all uses of the word "Id" in user visible places to be "id" instead. This threw up some other messages with issues in several files that I have tweaked here as well! Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2016-05-03 04:58:31 +01:00
{
QString text = msg;
text.replace(QChar::LineFeed, QChar::Space);
mMapAuditErrors.append(text);
Revision: route most of map auditing messages to errors.txt file As the amount of messages produced by the new/improve map auditing/clean-up code can be large for old map files this commit causes them to be sent to a profile specific file that is already opened by the Host class but has not been used for some time. An option (a check-box) on the "map" tab of the "profile preferences" dialog controls whether the equivalent information is also shown on the profile's main console as in the past. If the option (a global one) which is saved between sessions/runs is NOT enabled then an advisory is sent to the console advising the user to review the file contents if a "significant" issue was detected. If it is enabled a similar message advising that the information has also been saved. In either case, as the file is appended to, and not rewritten each time, the message includes details of the first line of the report so that it can be located in the file. One difference between the on-screen and the file versions of the information is that the former puts up the issues as they are detected whereas the latter groups the information by subject, first the general overall issues, then the area ones, in order of the areas' id numbers and then the room ones, in room order. Following earlier discussions in these Pull Request I have attempted to edit all uses of the word "Id" in user visible places to be "id" instead. This threw up some other messages with issues in several files that I have tweaked here as well! Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2016-05-03 04:58:31 +01:00
mIsFileViewingRecommended = isToSetFileViewingRecommended ? true : mIsFileViewingRecommended;
}
const QString TMap::createFileHeaderLine(const QString title, const QChar fillChar)
Revision: route most of map auditing messages to errors.txt file As the amount of messages produced by the new/improve map auditing/clean-up code can be large for old map files this commit causes them to be sent to a profile specific file that is already opened by the Host class but has not been used for some time. An option (a check-box) on the "map" tab of the "profile preferences" dialog controls whether the equivalent information is also shown on the profile's main console as in the past. If the option (a global one) which is saved between sessions/runs is NOT enabled then an advisory is sent to the console advising the user to review the file contents if a "significant" issue was detected. If it is enabled a similar message advising that the information has also been saved. In either case, as the file is appended to, and not rewritten each time, the message includes details of the first line of the report so that it can be located in the file. One difference between the on-screen and the file versions of the information is that the former puts up the issues as they are detected whereas the latter groups the information by subject, first the general overall issues, then the area ones, in order of the areas' id numbers and then the room ones, in room order. Following earlier discussions in these Pull Request I have attempted to edit all uses of the word "Id" in user visible places to be "id" instead. This threw up some other messages with issues in several files that I have tweaked here as well! Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2016-05-03 04:58:31 +01:00
{
QString text;
if (title.length() <= 76) {
text = QStringLiteral("%1 %2 %1\n").arg(QString(fillChar).repeated((78 - title.length()) / 2), title);
} else {
Revision: route most of map auditing messages to errors.txt file As the amount of messages produced by the new/improve map auditing/clean-up code can be large for old map files this commit causes them to be sent to a profile specific file that is already opened by the Host class but has not been used for some time. An option (a check-box) on the "map" tab of the "profile preferences" dialog controls whether the equivalent information is also shown on the profile's main console as in the past. If the option (a global one) which is saved between sessions/runs is NOT enabled then an advisory is sent to the console advising the user to review the file contents if a "significant" issue was detected. If it is enabled a similar message advising that the information has also been saved. In either case, as the file is appended to, and not rewritten each time, the message includes details of the first line of the report so that it can be located in the file. One difference between the on-screen and the file versions of the information is that the former puts up the issues as they are detected whereas the latter groups the information by subject, first the general overall issues, then the area ones, in order of the areas' id numbers and then the room ones, in room order. Following earlier discussions in these Pull Request I have attempted to edit all uses of the word "Id" in user visible places to be "id" instead. This threw up some other messages with issues in several files that I have tweaked here as well! Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2016-05-03 04:58:31 +01:00
text = title;
text.append(QChar::LineFeed);
Revision: route most of map auditing messages to errors.txt file As the amount of messages produced by the new/improve map auditing/clean-up code can be large for old map files this commit causes them to be sent to a profile specific file that is already opened by the Host class but has not been used for some time. An option (a check-box) on the "map" tab of the "profile preferences" dialog controls whether the equivalent information is also shown on the profile's main console as in the past. If the option (a global one) which is saved between sessions/runs is NOT enabled then an advisory is sent to the console advising the user to review the file contents if a "significant" issue was detected. If it is enabled a similar message advising that the information has also been saved. In either case, as the file is appended to, and not rewritten each time, the message includes details of the first line of the report so that it can be located in the file. One difference between the on-screen and the file versions of the information is that the former puts up the issues as they are detected whereas the latter groups the information by subject, first the general overall issues, then the area ones, in order of the areas' id numbers and then the room ones, in room order. Following earlier discussions in these Pull Request I have attempted to edit all uses of the word "Id" in user visible places to be "id" instead. This threw up some other messages with issues in several files that I have tweaked here as well! Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2016-05-03 04:58:31 +01:00
}
return text;
}
void TMap::pushErrorMessagesToFile(const QString title, const bool isACleanup)
Revision: route most of map auditing messages to errors.txt file As the amount of messages produced by the new/improve map auditing/clean-up code can be large for old map files this commit causes them to be sent to a profile specific file that is already opened by the Host class but has not been used for some time. An option (a check-box) on the "map" tab of the "profile preferences" dialog controls whether the equivalent information is also shown on the profile's main console as in the past. If the option (a global one) which is saved between sessions/runs is NOT enabled then an advisory is sent to the console advising the user to review the file contents if a "significant" issue was detected. If it is enabled a similar message advising that the information has also been saved. In either case, as the file is appended to, and not rewritten each time, the message includes details of the first line of the report so that it can be located in the file. One difference between the on-screen and the file versions of the information is that the former puts up the issues as they are detected whereas the latter groups the information by subject, first the general overall issues, then the area ones, in order of the areas' id numbers and then the room ones, in room order. Following earlier discussions in these Pull Request I have attempted to edit all uses of the word "Id" in user visible places to be "id" instead. This threw up some other messages with issues in several files that I have tweaked here as well! Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2016-05-03 04:58:31 +01:00
{
Host* pHost = mpHost;
if (!pHost) {
Revision: route most of map auditing messages to errors.txt file As the amount of messages produced by the new/improve map auditing/clean-up code can be large for old map files this commit causes them to be sent to a profile specific file that is already opened by the Host class but has not been used for some time. An option (a check-box) on the "map" tab of the "profile preferences" dialog controls whether the equivalent information is also shown on the profile's main console as in the past. If the option (a global one) which is saved between sessions/runs is NOT enabled then an advisory is sent to the console advising the user to review the file contents if a "significant" issue was detected. If it is enabled a similar message advising that the information has also been saved. In either case, as the file is appended to, and not rewritten each time, the message includes details of the first line of the report so that it can be located in the file. One difference between the on-screen and the file versions of the information is that the former puts up the issues as they are detected whereas the latter groups the information by subject, first the general overall issues, then the area ones, in order of the areas' id numbers and then the room ones, in room order. Following earlier discussions in these Pull Request I have attempted to edit all uses of the word "Id" in user visible places to be "id" instead. This threw up some other messages with issues in several files that I have tweaked here as well! Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2016-05-03 04:58:31 +01:00
qWarning() << "TMap::pushErrorMessagesToFile( ... ) ERROR: called with a NULL HOST pointer - something is wrong!";
return;
}
// Replacement storage locations:
QMap<int, QList<QString>> mapAuditRoomErrors; // Key is room number (where renumbered is the original one), Value is the errors, appended as they are found
QMap<int, QList<QString>> mapAuditAreaErrors; // As for the Room ones but with key as the area number
QList<QString> mapAuditErrors; // For the whole map
Revision: route most of map auditing messages to errors.txt file As the amount of messages produced by the new/improve map auditing/clean-up code can be large for old map files this commit causes them to be sent to a profile specific file that is already opened by the Host class but has not been used for some time. An option (a check-box) on the "map" tab of the "profile preferences" dialog controls whether the equivalent information is also shown on the profile's main console as in the past. If the option (a global one) which is saved between sessions/runs is NOT enabled then an advisory is sent to the console advising the user to review the file contents if a "significant" issue was detected. If it is enabled a similar message advising that the information has also been saved. In either case, as the file is appended to, and not rewritten each time, the message includes details of the first line of the report so that it can be located in the file. One difference between the on-screen and the file versions of the information is that the former puts up the issues as they are detected whereas the latter groups the information by subject, first the general overall issues, then the area ones, in order of the areas' id numbers and then the room ones, in room order. Following earlier discussions in these Pull Request I have attempted to edit all uses of the word "Id" in user visible places to be "id" instead. This threw up some other messages with issues in several files that I have tweaked here as well! Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2016-05-03 04:58:31 +01:00
// Switch message storage locations to freeze them so we can dump them to
// file; according to Qt documentation "Swaps XXX other with this XXX. This
// operation is very fast and never fails."
mapAuditErrors.swap(mMapAuditErrors);
mapAuditAreaErrors.swap(mMapAuditAreaErrors);
mapAuditRoomErrors.swap(mMapAuditRoomErrors);
Revision: route most of map auditing messages to errors.txt file As the amount of messages produced by the new/improve map auditing/clean-up code can be large for old map files this commit causes them to be sent to a profile specific file that is already opened by the Host class but has not been used for some time. An option (a check-box) on the "map" tab of the "profile preferences" dialog controls whether the equivalent information is also shown on the profile's main console as in the past. If the option (a global one) which is saved between sessions/runs is NOT enabled then an advisory is sent to the console advising the user to review the file contents if a "significant" issue was detected. If it is enabled a similar message advising that the information has also been saved. In either case, as the file is appended to, and not rewritten each time, the message includes details of the first line of the report so that it can be located in the file. One difference between the on-screen and the file versions of the information is that the former puts up the issues as they are detected whereas the latter groups the information by subject, first the general overall issues, then the area ones, in order of the areas' id numbers and then the room ones, in room order. Following earlier discussions in these Pull Request I have attempted to edit all uses of the word "Id" in user visible places to be "id" instead. This threw up some other messages with issues in several files that I have tweaked here as well! Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2016-05-03 04:58:31 +01:00
if (mapAuditErrors.isEmpty() && mapAuditAreaErrors.isEmpty() && mapAuditRoomErrors.isEmpty() && isACleanup) {
Revision: route most of map auditing messages to errors.txt file As the amount of messages produced by the new/improve map auditing/clean-up code can be large for old map files this commit causes them to be sent to a profile specific file that is already opened by the Host class but has not been used for some time. An option (a check-box) on the "map" tab of the "profile preferences" dialog controls whether the equivalent information is also shown on the profile's main console as in the past. If the option (a global one) which is saved between sessions/runs is NOT enabled then an advisory is sent to the console advising the user to review the file contents if a "significant" issue was detected. If it is enabled a similar message advising that the information has also been saved. In either case, as the file is appended to, and not rewritten each time, the message includes details of the first line of the report so that it can be located in the file. One difference between the on-screen and the file versions of the information is that the former puts up the issues as they are detected whereas the latter groups the information by subject, first the general overall issues, then the area ones, in order of the areas' id numbers and then the room ones, in room order. Following earlier discussions in these Pull Request I have attempted to edit all uses of the word "Id" in user visible places to be "id" instead. This threw up some other messages with issues in several files that I have tweaked here as well! Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2016-05-03 04:58:31 +01:00
mIsFileViewingRecommended = false;
return; // Nothing to do
}
pHost->mErrorLogStream << createFileHeaderLine(title, QLatin1Char('#'));
pHost->mErrorLogStream << createFileHeaderLine(tr("Map issues"), QLatin1Char('='));
QListIterator<QString> itMapMsg(mapAuditErrors);
while (itMapMsg.hasNext()) {
pHost->mErrorLogStream << itMapMsg.next() << QLatin1Char('\n');
;
Revision: route most of map auditing messages to errors.txt file As the amount of messages produced by the new/improve map auditing/clean-up code can be large for old map files this commit causes them to be sent to a profile specific file that is already opened by the Host class but has not been used for some time. An option (a check-box) on the "map" tab of the "profile preferences" dialog controls whether the equivalent information is also shown on the profile's main console as in the past. If the option (a global one) which is saved between sessions/runs is NOT enabled then an advisory is sent to the console advising the user to review the file contents if a "significant" issue was detected. If it is enabled a similar message advising that the information has also been saved. In either case, as the file is appended to, and not rewritten each time, the message includes details of the first line of the report so that it can be located in the file. One difference between the on-screen and the file versions of the information is that the former puts up the issues as they are detected whereas the latter groups the information by subject, first the general overall issues, then the area ones, in order of the areas' id numbers and then the room ones, in room order. Following earlier discussions in these Pull Request I have attempted to edit all uses of the word "Id" in user visible places to be "id" instead. This threw up some other messages with issues in several files that I have tweaked here as well! Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2016-05-03 04:58:31 +01:00
}
pHost->mErrorLogStream << createFileHeaderLine(tr("Area issues"), QLatin1Char('='));
QMapIterator<int, QList<QString>> itAreasMsg(mapAuditAreaErrors);
while (itAreasMsg.hasNext()) {
Revision: route most of map auditing messages to errors.txt file As the amount of messages produced by the new/improve map auditing/clean-up code can be large for old map files this commit causes them to be sent to a profile specific file that is already opened by the Host class but has not been used for some time. An option (a check-box) on the "map" tab of the "profile preferences" dialog controls whether the equivalent information is also shown on the profile's main console as in the past. If the option (a global one) which is saved between sessions/runs is NOT enabled then an advisory is sent to the console advising the user to review the file contents if a "significant" issue was detected. If it is enabled a similar message advising that the information has also been saved. In either case, as the file is appended to, and not rewritten each time, the message includes details of the first line of the report so that it can be located in the file. One difference between the on-screen and the file versions of the information is that the former puts up the issues as they are detected whereas the latter groups the information by subject, first the general overall issues, then the area ones, in order of the areas' id numbers and then the room ones, in room order. Following earlier discussions in these Pull Request I have attempted to edit all uses of the word "Id" in user visible places to be "id" instead. This threw up some other messages with issues in several files that I have tweaked here as well! Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2016-05-03 04:58:31 +01:00
itAreasMsg.next();
QString titleText;
if (!mpRoomDB->getAreaNamesMap().value(itAreasMsg.key()).isEmpty()) {
titleText = tr(R"(Area id: %1 "%2")").arg(itAreasMsg.key()).arg(mpRoomDB->getAreaNamesMap().value(itAreasMsg.key()));
} else {
titleText = tr("Area id: %1").arg(itAreasMsg.key());
Revision: route most of map auditing messages to errors.txt file As the amount of messages produced by the new/improve map auditing/clean-up code can be large for old map files this commit causes them to be sent to a profile specific file that is already opened by the Host class but has not been used for some time. An option (a check-box) on the "map" tab of the "profile preferences" dialog controls whether the equivalent information is also shown on the profile's main console as in the past. If the option (a global one) which is saved between sessions/runs is NOT enabled then an advisory is sent to the console advising the user to review the file contents if a "significant" issue was detected. If it is enabled a similar message advising that the information has also been saved. In either case, as the file is appended to, and not rewritten each time, the message includes details of the first line of the report so that it can be located in the file. One difference between the on-screen and the file versions of the information is that the former puts up the issues as they are detected whereas the latter groups the information by subject, first the general overall issues, then the area ones, in order of the areas' id numbers and then the room ones, in room order. Following earlier discussions in these Pull Request I have attempted to edit all uses of the word "Id" in user visible places to be "id" instead. This threw up some other messages with issues in several files that I have tweaked here as well! Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2016-05-03 04:58:31 +01:00
}
pHost->mErrorLogStream << createFileHeaderLine(titleText, QLatin1Char('-'));
QListIterator<QString> itMapAreaMsg(itAreasMsg.value());
while (itMapAreaMsg.hasNext()) {
pHost->mErrorLogStream << itMapAreaMsg.next() << QLatin1Char('\n');
Revision: route most of map auditing messages to errors.txt file As the amount of messages produced by the new/improve map auditing/clean-up code can be large for old map files this commit causes them to be sent to a profile specific file that is already opened by the Host class but has not been used for some time. An option (a check-box) on the "map" tab of the "profile preferences" dialog controls whether the equivalent information is also shown on the profile's main console as in the past. If the option (a global one) which is saved between sessions/runs is NOT enabled then an advisory is sent to the console advising the user to review the file contents if a "significant" issue was detected. If it is enabled a similar message advising that the information has also been saved. In either case, as the file is appended to, and not rewritten each time, the message includes details of the first line of the report so that it can be located in the file. One difference between the on-screen and the file versions of the information is that the former puts up the issues as they are detected whereas the latter groups the information by subject, first the general overall issues, then the area ones, in order of the areas' id numbers and then the room ones, in room order. Following earlier discussions in these Pull Request I have attempted to edit all uses of the word "Id" in user visible places to be "id" instead. This threw up some other messages with issues in several files that I have tweaked here as well! Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2016-05-03 04:58:31 +01:00
}
}
pHost->mErrorLogStream << createFileHeaderLine(tr("Room issues"), QLatin1Char('='));
QMapIterator<int, QList<QString>> itRoomsMsg(mapAuditRoomErrors);
while (itRoomsMsg.hasNext()) {
Revision: route most of map auditing messages to errors.txt file As the amount of messages produced by the new/improve map auditing/clean-up code can be large for old map files this commit causes them to be sent to a profile specific file that is already opened by the Host class but has not been used for some time. An option (a check-box) on the "map" tab of the "profile preferences" dialog controls whether the equivalent information is also shown on the profile's main console as in the past. If the option (a global one) which is saved between sessions/runs is NOT enabled then an advisory is sent to the console advising the user to review the file contents if a "significant" issue was detected. If it is enabled a similar message advising that the information has also been saved. In either case, as the file is appended to, and not rewritten each time, the message includes details of the first line of the report so that it can be located in the file. One difference between the on-screen and the file versions of the information is that the former puts up the issues as they are detected whereas the latter groups the information by subject, first the general overall issues, then the area ones, in order of the areas' id numbers and then the room ones, in room order. Following earlier discussions in these Pull Request I have attempted to edit all uses of the word "Id" in user visible places to be "id" instead. This threw up some other messages with issues in several files that I have tweaked here as well! Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2016-05-03 04:58:31 +01:00
itRoomsMsg.next();
QString titleText;
TRoom* pR = mpRoomDB->getRoom(itRoomsMsg.key());
if (pR && !pR->name.isEmpty()) {
titleText = tr(R"(Room id: %1 "%2")").arg(itRoomsMsg.key()).arg(pR->name);
} else {
titleText = tr("Room id: %1").arg(itRoomsMsg.key());
Revision: route most of map auditing messages to errors.txt file As the amount of messages produced by the new/improve map auditing/clean-up code can be large for old map files this commit causes them to be sent to a profile specific file that is already opened by the Host class but has not been used for some time. An option (a check-box) on the "map" tab of the "profile preferences" dialog controls whether the equivalent information is also shown on the profile's main console as in the past. If the option (a global one) which is saved between sessions/runs is NOT enabled then an advisory is sent to the console advising the user to review the file contents if a "significant" issue was detected. If it is enabled a similar message advising that the information has also been saved. In either case, as the file is appended to, and not rewritten each time, the message includes details of the first line of the report so that it can be located in the file. One difference between the on-screen and the file versions of the information is that the former puts up the issues as they are detected whereas the latter groups the information by subject, first the general overall issues, then the area ones, in order of the areas' id numbers and then the room ones, in room order. Following earlier discussions in these Pull Request I have attempted to edit all uses of the word "Id" in user visible places to be "id" instead. This threw up some other messages with issues in several files that I have tweaked here as well! Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2016-05-03 04:58:31 +01:00
}
pHost->mErrorLogStream << createFileHeaderLine(titleText, QLatin1Char('-'));
QListIterator<QString> itMapRoomMsg(itRoomsMsg.value());
while (itMapRoomMsg.hasNext()) {
pHost->mErrorLogStream << itMapRoomMsg.next() << QLatin1Char('\n');
;
Revision: route most of map auditing messages to errors.txt file As the amount of messages produced by the new/improve map auditing/clean-up code can be large for old map files this commit causes them to be sent to a profile specific file that is already opened by the Host class but has not been used for some time. An option (a check-box) on the "map" tab of the "profile preferences" dialog controls whether the equivalent information is also shown on the profile's main console as in the past. If the option (a global one) which is saved between sessions/runs is NOT enabled then an advisory is sent to the console advising the user to review the file contents if a "significant" issue was detected. If it is enabled a similar message advising that the information has also been saved. In either case, as the file is appended to, and not rewritten each time, the message includes details of the first line of the report so that it can be located in the file. One difference between the on-screen and the file versions of the information is that the former puts up the issues as they are detected whereas the latter groups the information by subject, first the general overall issues, then the area ones, in order of the areas' id numbers and then the room ones, in room order. Following earlier discussions in these Pull Request I have attempted to edit all uses of the word "Id" in user visible places to be "id" instead. This threw up some other messages with issues in several files that I have tweaked here as well! Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2016-05-03 04:58:31 +01:00
}
}
pHost->mErrorLogStream << createFileHeaderLine(tr("End of report"), QLatin1Char('#'));
Revision: route most of map auditing messages to errors.txt file As the amount of messages produced by the new/improve map auditing/clean-up code can be large for old map files this commit causes them to be sent to a profile specific file that is already opened by the Host class but has not been used for some time. An option (a check-box) on the "map" tab of the "profile preferences" dialog controls whether the equivalent information is also shown on the profile's main console as in the past. If the option (a global one) which is saved between sessions/runs is NOT enabled then an advisory is sent to the console advising the user to review the file contents if a "significant" issue was detected. If it is enabled a similar message advising that the information has also been saved. In either case, as the file is appended to, and not rewritten each time, the message includes details of the first line of the report so that it can be located in the file. One difference between the on-screen and the file versions of the information is that the former puts up the issues as they are detected whereas the latter groups the information by subject, first the general overall issues, then the area ones, in order of the areas' id numbers and then the room ones, in room order. Following earlier discussions in these Pull Request I have attempted to edit all uses of the word "Id" in user visible places to be "id" instead. This threw up some other messages with issues in several files that I have tweaked here as well! Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2016-05-03 04:58:31 +01:00
pHost->mErrorLogStream.flush();
mapAuditErrors.clear();
mapAuditAreaErrors.clear();
mapAuditRoomErrors.clear();
if (mIsFileViewingRecommended && (!mudlet::self()->showMapAuditErrors())) {
postMessage(tr("[ ALERT ] - At least one thing was detected during that last map operation\n"
"that it is recommended that you review the most recent report in\n"
"the file:\n"
"\"%1\"\n"
"- look for the (last) report with the title:\n"
"\"%2\".")
Refactor: reduce use of raw string literals for directories and file paths Using a static method means that we can centralise the generation of strings used to access parts of the file system used to hold Mudlet user data - which may be useful if we change them for - say running from a thumb-drive or just to use an OS specific location for them. {Using a ".config/mudlet" sub-directory on Windows is not quite how that OS expects things to be done...!} This also reduces the number of raw strings that will have to be wrapped in QStringLiteral(...) and the like for forthcoming I18n work. Also: * The use of "mudlet-data" as a windows symlink sub-directory to ".config/mudlet" in the user home directory may not work because the Qt Documentation suggests that a ".lnk" extension is required - this commit adds that FOR THAT OS ONLY. * Previous code placed (only some - for an unexplained reason not all the files were being copied) the DejaVu fonts that we include in the resources directly into the main mudlet user data folder - but the included documentation including the COPYRIGHT.TXT and other files ONLY relate to those font files and NOT to Mudlet as a whole. I have taken the liberty of moving and loading them from a ./fonts/ subdirectory which makes more sense. I have noted that, at least, the Debian Linux packager actually removes the font files from their configuration because they already include a shared system wide copy of the same fonts and in a much newer (2.37 at present) version compared to the 1.10 that we bundle - perhaps our code needs to check for the existence/availability of the fonts before we try to load ours into the Mudlet application at run-time! Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2017-09-18 16:23:57 +01:00
.arg(mudlet::getMudletPath(mudlet::profileLogErrorsFilePath, mpHost->getName()), title));
} else if (mIsFileViewingRecommended && mudlet::self()->showMapAuditErrors()) {
postMessage(tr("[ INFO ] - The equivalent to the above information about that last map\n"
"operation has been saved for review as the most recent report in\n"
"the file:\n"
"\"%1\"\n"
"- look for the (last) report with the title:\n"
"\"%2\".")
Refactor: reduce use of raw string literals for directories and file paths Using a static method means that we can centralise the generation of strings used to access parts of the file system used to hold Mudlet user data - which may be useful if we change them for - say running from a thumb-drive or just to use an OS specific location for them. {Using a ".config/mudlet" sub-directory on Windows is not quite how that OS expects things to be done...!} This also reduces the number of raw strings that will have to be wrapped in QStringLiteral(...) and the like for forthcoming I18n work. Also: * The use of "mudlet-data" as a windows symlink sub-directory to ".config/mudlet" in the user home directory may not work because the Qt Documentation suggests that a ".lnk" extension is required - this commit adds that FOR THAT OS ONLY. * Previous code placed (only some - for an unexplained reason not all the files were being copied) the DejaVu fonts that we include in the resources directly into the main mudlet user data folder - but the included documentation including the COPYRIGHT.TXT and other files ONLY relate to those font files and NOT to Mudlet as a whole. I have taken the liberty of moving and loading them from a ./fonts/ subdirectory which makes more sense. I have noted that, at least, the Debian Linux packager actually removes the font files from their configuration because they already include a shared system wide copy of the same fonts and in a much newer (2.37 at present) version compared to the 1.10 that we bundle - perhaps our code needs to check for the existence/availability of the fonts before we try to load ours into the Mudlet application at run-time! Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2017-09-18 16:23:57 +01:00
.arg(mudlet::getMudletPath(mudlet::profileLogErrorsFilePath, mpHost->getName()), title));
Revision: route most of map auditing messages to errors.txt file As the amount of messages produced by the new/improve map auditing/clean-up code can be large for old map files this commit causes them to be sent to a profile specific file that is already opened by the Host class but has not been used for some time. An option (a check-box) on the "map" tab of the "profile preferences" dialog controls whether the equivalent information is also shown on the profile's main console as in the past. If the option (a global one) which is saved between sessions/runs is NOT enabled then an advisory is sent to the console advising the user to review the file contents if a "significant" issue was detected. If it is enabled a similar message advising that the information has also been saved. In either case, as the file is appended to, and not rewritten each time, the message includes details of the first line of the report so that it can be located in the file. One difference between the on-screen and the file versions of the information is that the former puts up the issues as they are detected whereas the latter groups the information by subject, first the general overall issues, then the area ones, in order of the areas' id numbers and then the room ones, in room order. Following earlier discussions in these Pull Request I have attempted to edit all uses of the word "Id" in user visible places to be "id" instead. This threw up some other messages with issues in several files that I have tweaked here as well! Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2016-05-03 04:58:31 +01:00
}
mIsFileViewingRecommended = false;
}
Enhance: fix map downloading code, add manual XML map importing (#326) * Enhance: fix map downloading code, add manual XML map importing A recent move by I.R.E. to using SSL for their public MUD map URLs broke the ability for Mudlet to download those XML format files. This commit addresses this issue (as mentioned in, but not the original problem referred to in https://bugs.launchpad.net/mudlet/+bug/1427364) the revision to the code does now use "https://www.<MUD URL>/maps/map.xml" as a default name for the I.R.E. MUDS - however the method that initiates the download which was moved to TMap class from the dlgMapper one (see below) is now: (bool) TMap::downloadMap( const QString * remoteUrl = Q_NULLPTR, const QString * localFileName = Q_NULLPTR ) which if not supplied with any arguments behaves as before. However the remoteUrl argument may be given as a full QString including the scheme (the bit of the URL at the beginning before the ':') to override that and a second argument may be used to provide a different name to use for the local file name which if is a RELATIVE pathFileName will be resolved in relation to the profile directory. At present no use is made of this additional functionality but it may be useful for use with other MUDs if they should choose to provide XML map files with other remote locations and scripts using a different local filename. As a long-standing thing that needed doing I have finally provided a means to import a map XML file that - for instance - has already been download. It had been noted that there was no way to read those I.R.E. map files even if they had been obtained from a web browser able to correctly handle https: URLs - now both the TLuaInterpreter::loadMap() and the dlgProfilePreference "loadMap" button {NOT the IRE only "map download" one} will both handle files ending in ".xml" (not case sensitive so it'll work MacOS platforms as well!} For the loadMap case it will be necessary to change the filetype filter on the File Selection dialog to select "xml" files. During testing it became clear to me that it was possible to try and read one or more XML files via several mechanisms simultaneously with "unhelpful" consequences. As well as hitting the dlgProfilePreferences IRE "map download" multiple times, the TLuaInterpreter::loadMap() does NOT block until the map has been loaded and as the import time {running of XMLinport::readPackage(...)} is of significant duration for a large map (a debug, without optimisation, build on my 1.8GHz Quad-core took over two minutes to process the current Achaea map file) it is very possible to get conditions where the same profile will try to run XMLinport::readPackage(...) asynchronously - given that a profile only supports ONE map at a time it was necessary to fit a QMutex to prevent the part of the XMLinport class relating to XML Map files being called from different places in the map related code. This means that if a map download is started further downloads and any local map imports will fail until that first download has completed or aborted. Similarly a local import will prevent a download being started. As a side effect this cures: https://bugs.launchpad.net/mudlet/+bug/852861 - "Map download button starts another download thread if one is already going" The previous XML import code was not adding the rooms that it parsed to the relevant TArea::rooms member - although this would be picked-up and fixed by TMap::audit() later on, this would be accompanied by an error message about every single room. The code now builds up this information while parsing the rooms' details and inserts it so that this does not cause report-able problems during the TMap::audit() execution - the data gathered also allows missing areas to be spotted so that if a room claimed to belong to an area that was not included in the preceding areas' data an unnamed area is created for it. As a consequence of the long time to actually parse an XML map file I have enhanced the progress dialog that was originally used to track the map file download. It is now retained until the file is completely imported and shows more information about the process - importantly it shows during the XMLimport::readRoom(...) the room id being processed - and THAT method is the time/cpu hog so seeing something happening during the time that Mudlet otherwise appears to hang is useful feedback even if it adds a few seconds to the overall duration (may be more than a minute). This dialog is now also used during the other routes that involve reading an XML file and there is now a bit of consistence with the on-screen messages. Whilst inspecting XMLimport class I found there was some uncertain initialisation which I have tidied up. In summary: Added: * (bool) TConsole::importMap(const QString & location) * (void) TRoomDB::setAreaRooms(const int areaId, const QSet<int> & roomIds) * image file mudlet_map_download.png used as icon for download/import progress dialog * (bool) TMap::importMap(QFile & file) * (bool) TMap::readXmlMapFile(QFile & file) * (void) TMap::slot_downloadError(QNetworkReply::NetworkError error) * (void) TMap::reportStringToProgressDialog(const QString text) * (void) TMap::reportProgressToProgressDialog(const int current, const int maximum) Revised: * (int)TLuaInterpreter::loadMap( lua_State * ) * Moved XML map download code from dlgMapper class to the TMap one: + (void) dlgMapper::downloadMap() ==> (bool) TMap::downloadMap(const QString * remoteUrl, const QString * localFileName) + (void) dlgMapper::setDownloadProgress(qint64, qint64) ==> (void) TMap::slot_setDownloadProgress(qint64,qint64) + (void) dlgMapper::cancel() ==> (void) TMap::slot_downloadCancel() + (void) dlgMapper::replyFinished(QNetworkReply *) ==> (void) TMap::slot_replyFinished(QNetworkReply *) * Enhanced download progress indication to also include parsing which can take even more time than download! * Provide means to import local XML map file * Prevent trying to import/download more than one map at a time Renamed: * (void) XMLimport::readAreaNames() ==> XMLimport::readArea() - for consistency with related functions Commented out unused: * (void) XMLimport::readUnknownRoomElement() Note the movement of the map file download code to the TMap class does require making the latter a class with the Q_OBJECT macro (which removes the need for Q_DECLARE_TR_FUNCTIONS as a side-effect!) - though as another side-effect the TMap header needed a boost name specifier added to one identifier as that identifier ("property") exists in both boost and QObject classes!!! YOU MAY NEED TO RUN QMAKE ON THE PROJECT IF THE BUILD SYSTEM DOES NOT PICK UP THE ADDITION OF "Q_OBJECT" TO TMAP CLASS. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: Include missing #include, remove unused return value The absence of this was causing build errors on the Travis C.I. platform! Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: move TMap.h to mudlet_MOC_HDRS to fix CMake build issue As we have made TMap inherit from QOject - to have signal/slot functionality that class needs to be run through Qt's MOC - and to do that with the CMake project/build system it needs to be included in the files included in the projects *_MOC_HDRS {and removed from the *_HDRS} variable. Also spotted a trivial error in that specifying a const return value from method is ineffective and pointless - so removed it from: TMap::retrieveMapFileStats(QString,QString *,int *,int *,int *,int *) Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: clean up TMap initialisation/clearing actions Now restores the customEnvColors set up on initialisation but that was cleared when the map replaced with another one that is loaded {which subsequently replaces that element anyway} or imported {which merely writes over it, replacing any matching keys}. Initialises elements that when inspected on the entry to the constructor proper previously were not being set to a consistent value {booleans/ints/floats}. NOTE: This will now clear the map user data member when the map is cleared if the date is required to be saved when one map is loaded OR IMPORTED over an existing one then the data will need to be saved outside of the map - as is already need for areas and rooms user data! Also comment out or remove unused members/methods: * (void) TMap::getConnectedNodesGreaterThanX(int, int) * (void) TMap::getConnectedNodesSmallerThanX(int, int) * (void) TMap::getConnectedNodesGreaterThanY(int, int) * (void) TMap::getConnectedNodesSmallerThanY(int, int) * (void) TMap::astBreitenAnpassung(int, int) * (void) TMap::astHoehenAnpassung(int, int) * (void) TMap::exportMapToDatabase() * (void) TMap::importMapFromDatabase() * (QVector3D) TMap::span * (int) TMap::mViewArea * (QMap<QString, int>) TMap::pixNameTable * (QMap<int, QPixmap>) TMap::pixTable * (bool) TMap::isToDisplayAuditErrorsToConsole Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * ImplimentationFixes: activate a valid optimisation & remove redundant code Adding a true as a non-default 3rd argument to TRoomDB::addRoom(...) call in XMLimport::readRoom(...) enables a significant optimisation (skips a computationally expensive step when ADDING a room to new map) which dramatically reduces the time to parse an XML map file. It also pointed to the fact that the TRoomDB::entranceMap was already correctly being handled and didn't need to be regenerated in XMLimport::readRoom(...) so the code that was added in a previous commit was redundant and could be removed. A code error in TMap::slot_setDownloadProgress(...) that caused an issue that a reviewer found on test has been fixed - the total download filesize that was being sent by the Qt system signal that is connected to this slot was a -1 value (as IS DOCUMENTED) when the Qt system does NOT know the size of a QNetworkReply in advance of reaching the end of the download was incorrectly handled in a previous commit in this change set. Also found during testing that there is no need for an error message for the QNetworkReply::OperationCanceledError case in TMap::slot_replayFinished(...) as it is already handled in the TMap::slot_downloadCancel() slot. Changed the text put up onto the progress widget during the XML room parsing to be a room count - which is likely more useful and to only do it for every hundredth room - which reduces any delay "wasted" in writing to the display - combined, the effects seem satisfactory IMHO. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: provide error messages for TLuaInterpreter::loadMap(...) Errors for the XML map file importing process as initiated from the Lua command should be returned to that command rather than plastered onto the main profile console - this commit attempts to perform that effect. In testing found that there was no error handling for failure to find or open the nominated file so messages for that have been added as well. Due to the previous program logic the action of creating a mapper widget using the main toolbar button automatically loaded the "default" (the newest Mudlet Map file format file from the currently active profile's map sub-directory). Under some previous situations it looked as though a map might be loaded twice as mudlet::slot_mapper() was called both directly and via signal/slot action. These were resolved by turning that slot into a wrapper that now calls the body of code formerly within to a new method mudlet::createMapper( bool isToLoadDefaultMapFile = true ) with a the default value as an argument. This allows other usages of the body of code to be called directly with a suitable argument, which for the TConsole::loadMap() & TConsole::importMap() and the dlgProfilePreferences::downloadMap() cases is false as they are all do not want the "default" map! Also: * spotted a word "area" missing from an advisory text in TRoom::auditRooms(...). Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: fix minor bug, correct a spelling, undo a few capitalisations Under certain, unanticipated (error with no error message) conditions TLuaInterpreter::loadMap(...) would push both a nil and then a false value onto the stack for return {wrong} but only indicate one value {correct}. The textual matters were found during peer review. off-by: Stephen Lyons <slysven@virginmedia.com>
2016-10-13 09:18:48 +01:00
void TMap::downloadMap(const QString& remoteUrl, const QString& localFileName)
Enhance: fix map downloading code, add manual XML map importing (#326) * Enhance: fix map downloading code, add manual XML map importing A recent move by I.R.E. to using SSL for their public MUD map URLs broke the ability for Mudlet to download those XML format files. This commit addresses this issue (as mentioned in, but not the original problem referred to in https://bugs.launchpad.net/mudlet/+bug/1427364) the revision to the code does now use "https://www.<MUD URL>/maps/map.xml" as a default name for the I.R.E. MUDS - however the method that initiates the download which was moved to TMap class from the dlgMapper one (see below) is now: (bool) TMap::downloadMap( const QString * remoteUrl = Q_NULLPTR, const QString * localFileName = Q_NULLPTR ) which if not supplied with any arguments behaves as before. However the remoteUrl argument may be given as a full QString including the scheme (the bit of the URL at the beginning before the ':') to override that and a second argument may be used to provide a different name to use for the local file name which if is a RELATIVE pathFileName will be resolved in relation to the profile directory. At present no use is made of this additional functionality but it may be useful for use with other MUDs if they should choose to provide XML map files with other remote locations and scripts using a different local filename. As a long-standing thing that needed doing I have finally provided a means to import a map XML file that - for instance - has already been download. It had been noted that there was no way to read those I.R.E. map files even if they had been obtained from a web browser able to correctly handle https: URLs - now both the TLuaInterpreter::loadMap() and the dlgProfilePreference "loadMap" button {NOT the IRE only "map download" one} will both handle files ending in ".xml" (not case sensitive so it'll work MacOS platforms as well!} For the loadMap case it will be necessary to change the filetype filter on the File Selection dialog to select "xml" files. During testing it became clear to me that it was possible to try and read one or more XML files via several mechanisms simultaneously with "unhelpful" consequences. As well as hitting the dlgProfilePreferences IRE "map download" multiple times, the TLuaInterpreter::loadMap() does NOT block until the map has been loaded and as the import time {running of XMLinport::readPackage(...)} is of significant duration for a large map (a debug, without optimisation, build on my 1.8GHz Quad-core took over two minutes to process the current Achaea map file) it is very possible to get conditions where the same profile will try to run XMLinport::readPackage(...) asynchronously - given that a profile only supports ONE map at a time it was necessary to fit a QMutex to prevent the part of the XMLinport class relating to XML Map files being called from different places in the map related code. This means that if a map download is started further downloads and any local map imports will fail until that first download has completed or aborted. Similarly a local import will prevent a download being started. As a side effect this cures: https://bugs.launchpad.net/mudlet/+bug/852861 - "Map download button starts another download thread if one is already going" The previous XML import code was not adding the rooms that it parsed to the relevant TArea::rooms member - although this would be picked-up and fixed by TMap::audit() later on, this would be accompanied by an error message about every single room. The code now builds up this information while parsing the rooms' details and inserts it so that this does not cause report-able problems during the TMap::audit() execution - the data gathered also allows missing areas to be spotted so that if a room claimed to belong to an area that was not included in the preceding areas' data an unnamed area is created for it. As a consequence of the long time to actually parse an XML map file I have enhanced the progress dialog that was originally used to track the map file download. It is now retained until the file is completely imported and shows more information about the process - importantly it shows during the XMLimport::readRoom(...) the room id being processed - and THAT method is the time/cpu hog so seeing something happening during the time that Mudlet otherwise appears to hang is useful feedback even if it adds a few seconds to the overall duration (may be more than a minute). This dialog is now also used during the other routes that involve reading an XML file and there is now a bit of consistence with the on-screen messages. Whilst inspecting XMLimport class I found there was some uncertain initialisation which I have tidied up. In summary: Added: * (bool) TConsole::importMap(const QString & location) * (void) TRoomDB::setAreaRooms(const int areaId, const QSet<int> & roomIds) * image file mudlet_map_download.png used as icon for download/import progress dialog * (bool) TMap::importMap(QFile & file) * (bool) TMap::readXmlMapFile(QFile & file) * (void) TMap::slot_downloadError(QNetworkReply::NetworkError error) * (void) TMap::reportStringToProgressDialog(const QString text) * (void) TMap::reportProgressToProgressDialog(const int current, const int maximum) Revised: * (int)TLuaInterpreter::loadMap( lua_State * ) * Moved XML map download code from dlgMapper class to the TMap one: + (void) dlgMapper::downloadMap() ==> (bool) TMap::downloadMap(const QString * remoteUrl, const QString * localFileName) + (void) dlgMapper::setDownloadProgress(qint64, qint64) ==> (void) TMap::slot_setDownloadProgress(qint64,qint64) + (void) dlgMapper::cancel() ==> (void) TMap::slot_downloadCancel() + (void) dlgMapper::replyFinished(QNetworkReply *) ==> (void) TMap::slot_replyFinished(QNetworkReply *) * Enhanced download progress indication to also include parsing which can take even more time than download! * Provide means to import local XML map file * Prevent trying to import/download more than one map at a time Renamed: * (void) XMLimport::readAreaNames() ==> XMLimport::readArea() - for consistency with related functions Commented out unused: * (void) XMLimport::readUnknownRoomElement() Note the movement of the map file download code to the TMap class does require making the latter a class with the Q_OBJECT macro (which removes the need for Q_DECLARE_TR_FUNCTIONS as a side-effect!) - though as another side-effect the TMap header needed a boost name specifier added to one identifier as that identifier ("property") exists in both boost and QObject classes!!! YOU MAY NEED TO RUN QMAKE ON THE PROJECT IF THE BUILD SYSTEM DOES NOT PICK UP THE ADDITION OF "Q_OBJECT" TO TMAP CLASS. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: Include missing #include, remove unused return value The absence of this was causing build errors on the Travis C.I. platform! Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: move TMap.h to mudlet_MOC_HDRS to fix CMake build issue As we have made TMap inherit from QOject - to have signal/slot functionality that class needs to be run through Qt's MOC - and to do that with the CMake project/build system it needs to be included in the files included in the projects *_MOC_HDRS {and removed from the *_HDRS} variable. Also spotted a trivial error in that specifying a const return value from method is ineffective and pointless - so removed it from: TMap::retrieveMapFileStats(QString,QString *,int *,int *,int *,int *) Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: clean up TMap initialisation/clearing actions Now restores the customEnvColors set up on initialisation but that was cleared when the map replaced with another one that is loaded {which subsequently replaces that element anyway} or imported {which merely writes over it, replacing any matching keys}. Initialises elements that when inspected on the entry to the constructor proper previously were not being set to a consistent value {booleans/ints/floats}. NOTE: This will now clear the map user data member when the map is cleared if the date is required to be saved when one map is loaded OR IMPORTED over an existing one then the data will need to be saved outside of the map - as is already need for areas and rooms user data! Also comment out or remove unused members/methods: * (void) TMap::getConnectedNodesGreaterThanX(int, int) * (void) TMap::getConnectedNodesSmallerThanX(int, int) * (void) TMap::getConnectedNodesGreaterThanY(int, int) * (void) TMap::getConnectedNodesSmallerThanY(int, int) * (void) TMap::astBreitenAnpassung(int, int) * (void) TMap::astHoehenAnpassung(int, int) * (void) TMap::exportMapToDatabase() * (void) TMap::importMapFromDatabase() * (QVector3D) TMap::span * (int) TMap::mViewArea * (QMap<QString, int>) TMap::pixNameTable * (QMap<int, QPixmap>) TMap::pixTable * (bool) TMap::isToDisplayAuditErrorsToConsole Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * ImplimentationFixes: activate a valid optimisation & remove redundant code Adding a true as a non-default 3rd argument to TRoomDB::addRoom(...) call in XMLimport::readRoom(...) enables a significant optimisation (skips a computationally expensive step when ADDING a room to new map) which dramatically reduces the time to parse an XML map file. It also pointed to the fact that the TRoomDB::entranceMap was already correctly being handled and didn't need to be regenerated in XMLimport::readRoom(...) so the code that was added in a previous commit was redundant and could be removed. A code error in TMap::slot_setDownloadProgress(...) that caused an issue that a reviewer found on test has been fixed - the total download filesize that was being sent by the Qt system signal that is connected to this slot was a -1 value (as IS DOCUMENTED) when the Qt system does NOT know the size of a QNetworkReply in advance of reaching the end of the download was incorrectly handled in a previous commit in this change set. Also found during testing that there is no need for an error message for the QNetworkReply::OperationCanceledError case in TMap::slot_replayFinished(...) as it is already handled in the TMap::slot_downloadCancel() slot. Changed the text put up onto the progress widget during the XML room parsing to be a room count - which is likely more useful and to only do it for every hundredth room - which reduces any delay "wasted" in writing to the display - combined, the effects seem satisfactory IMHO. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: provide error messages for TLuaInterpreter::loadMap(...) Errors for the XML map file importing process as initiated from the Lua command should be returned to that command rather than plastered onto the main profile console - this commit attempts to perform that effect. In testing found that there was no error handling for failure to find or open the nominated file so messages for that have been added as well. Due to the previous program logic the action of creating a mapper widget using the main toolbar button automatically loaded the "default" (the newest Mudlet Map file format file from the currently active profile's map sub-directory). Under some previous situations it looked as though a map might be loaded twice as mudlet::slot_mapper() was called both directly and via signal/slot action. These were resolved by turning that slot into a wrapper that now calls the body of code formerly within to a new method mudlet::createMapper( bool isToLoadDefaultMapFile = true ) with a the default value as an argument. This allows other usages of the body of code to be called directly with a suitable argument, which for the TConsole::loadMap() & TConsole::importMap() and the dlgProfilePreferences::downloadMap() cases is false as they are all do not want the "default" map! Also: * spotted a word "area" missing from an advisory text in TRoom::auditRooms(...). Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: fix minor bug, correct a spelling, undo a few capitalisations Under certain, unanticipated (error with no error message) conditions TLuaInterpreter::loadMap(...) would push both a nil and then a false value onto the stack for return {wrong} but only indicate one value {correct}. The textual matters were found during peer review. off-by: Stephen Lyons <slysven@virginmedia.com>
2016-10-13 09:18:48 +01:00
{
Host* pHost = mpHost;
if (!pHost) {
Enhance: fix map downloading code, add manual XML map importing (#326) * Enhance: fix map downloading code, add manual XML map importing A recent move by I.R.E. to using SSL for their public MUD map URLs broke the ability for Mudlet to download those XML format files. This commit addresses this issue (as mentioned in, but not the original problem referred to in https://bugs.launchpad.net/mudlet/+bug/1427364) the revision to the code does now use "https://www.<MUD URL>/maps/map.xml" as a default name for the I.R.E. MUDS - however the method that initiates the download which was moved to TMap class from the dlgMapper one (see below) is now: (bool) TMap::downloadMap( const QString * remoteUrl = Q_NULLPTR, const QString * localFileName = Q_NULLPTR ) which if not supplied with any arguments behaves as before. However the remoteUrl argument may be given as a full QString including the scheme (the bit of the URL at the beginning before the ':') to override that and a second argument may be used to provide a different name to use for the local file name which if is a RELATIVE pathFileName will be resolved in relation to the profile directory. At present no use is made of this additional functionality but it may be useful for use with other MUDs if they should choose to provide XML map files with other remote locations and scripts using a different local filename. As a long-standing thing that needed doing I have finally provided a means to import a map XML file that - for instance - has already been download. It had been noted that there was no way to read those I.R.E. map files even if they had been obtained from a web browser able to correctly handle https: URLs - now both the TLuaInterpreter::loadMap() and the dlgProfilePreference "loadMap" button {NOT the IRE only "map download" one} will both handle files ending in ".xml" (not case sensitive so it'll work MacOS platforms as well!} For the loadMap case it will be necessary to change the filetype filter on the File Selection dialog to select "xml" files. During testing it became clear to me that it was possible to try and read one or more XML files via several mechanisms simultaneously with "unhelpful" consequences. As well as hitting the dlgProfilePreferences IRE "map download" multiple times, the TLuaInterpreter::loadMap() does NOT block until the map has been loaded and as the import time {running of XMLinport::readPackage(...)} is of significant duration for a large map (a debug, without optimisation, build on my 1.8GHz Quad-core took over two minutes to process the current Achaea map file) it is very possible to get conditions where the same profile will try to run XMLinport::readPackage(...) asynchronously - given that a profile only supports ONE map at a time it was necessary to fit a QMutex to prevent the part of the XMLinport class relating to XML Map files being called from different places in the map related code. This means that if a map download is started further downloads and any local map imports will fail until that first download has completed or aborted. Similarly a local import will prevent a download being started. As a side effect this cures: https://bugs.launchpad.net/mudlet/+bug/852861 - "Map download button starts another download thread if one is already going" The previous XML import code was not adding the rooms that it parsed to the relevant TArea::rooms member - although this would be picked-up and fixed by TMap::audit() later on, this would be accompanied by an error message about every single room. The code now builds up this information while parsing the rooms' details and inserts it so that this does not cause report-able problems during the TMap::audit() execution - the data gathered also allows missing areas to be spotted so that if a room claimed to belong to an area that was not included in the preceding areas' data an unnamed area is created for it. As a consequence of the long time to actually parse an XML map file I have enhanced the progress dialog that was originally used to track the map file download. It is now retained until the file is completely imported and shows more information about the process - importantly it shows during the XMLimport::readRoom(...) the room id being processed - and THAT method is the time/cpu hog so seeing something happening during the time that Mudlet otherwise appears to hang is useful feedback even if it adds a few seconds to the overall duration (may be more than a minute). This dialog is now also used during the other routes that involve reading an XML file and there is now a bit of consistence with the on-screen messages. Whilst inspecting XMLimport class I found there was some uncertain initialisation which I have tidied up. In summary: Added: * (bool) TConsole::importMap(const QString & location) * (void) TRoomDB::setAreaRooms(const int areaId, const QSet<int> & roomIds) * image file mudlet_map_download.png used as icon for download/import progress dialog * (bool) TMap::importMap(QFile & file) * (bool) TMap::readXmlMapFile(QFile & file) * (void) TMap::slot_downloadError(QNetworkReply::NetworkError error) * (void) TMap::reportStringToProgressDialog(const QString text) * (void) TMap::reportProgressToProgressDialog(const int current, const int maximum) Revised: * (int)TLuaInterpreter::loadMap( lua_State * ) * Moved XML map download code from dlgMapper class to the TMap one: + (void) dlgMapper::downloadMap() ==> (bool) TMap::downloadMap(const QString * remoteUrl, const QString * localFileName) + (void) dlgMapper::setDownloadProgress(qint64, qint64) ==> (void) TMap::slot_setDownloadProgress(qint64,qint64) + (void) dlgMapper::cancel() ==> (void) TMap::slot_downloadCancel() + (void) dlgMapper::replyFinished(QNetworkReply *) ==> (void) TMap::slot_replyFinished(QNetworkReply *) * Enhanced download progress indication to also include parsing which can take even more time than download! * Provide means to import local XML map file * Prevent trying to import/download more than one map at a time Renamed: * (void) XMLimport::readAreaNames() ==> XMLimport::readArea() - for consistency with related functions Commented out unused: * (void) XMLimport::readUnknownRoomElement() Note the movement of the map file download code to the TMap class does require making the latter a class with the Q_OBJECT macro (which removes the need for Q_DECLARE_TR_FUNCTIONS as a side-effect!) - though as another side-effect the TMap header needed a boost name specifier added to one identifier as that identifier ("property") exists in both boost and QObject classes!!! YOU MAY NEED TO RUN QMAKE ON THE PROJECT IF THE BUILD SYSTEM DOES NOT PICK UP THE ADDITION OF "Q_OBJECT" TO TMAP CLASS. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: Include missing #include, remove unused return value The absence of this was causing build errors on the Travis C.I. platform! Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: move TMap.h to mudlet_MOC_HDRS to fix CMake build issue As we have made TMap inherit from QOject - to have signal/slot functionality that class needs to be run through Qt's MOC - and to do that with the CMake project/build system it needs to be included in the files included in the projects *_MOC_HDRS {and removed from the *_HDRS} variable. Also spotted a trivial error in that specifying a const return value from method is ineffective and pointless - so removed it from: TMap::retrieveMapFileStats(QString,QString *,int *,int *,int *,int *) Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: clean up TMap initialisation/clearing actions Now restores the customEnvColors set up on initialisation but that was cleared when the map replaced with another one that is loaded {which subsequently replaces that element anyway} or imported {which merely writes over it, replacing any matching keys}. Initialises elements that when inspected on the entry to the constructor proper previously were not being set to a consistent value {booleans/ints/floats}. NOTE: This will now clear the map user data member when the map is cleared if the date is required to be saved when one map is loaded OR IMPORTED over an existing one then the data will need to be saved outside of the map - as is already need for areas and rooms user data! Also comment out or remove unused members/methods: * (void) TMap::getConnectedNodesGreaterThanX(int, int) * (void) TMap::getConnectedNodesSmallerThanX(int, int) * (void) TMap::getConnectedNodesGreaterThanY(int, int) * (void) TMap::getConnectedNodesSmallerThanY(int, int) * (void) TMap::astBreitenAnpassung(int, int) * (void) TMap::astHoehenAnpassung(int, int) * (void) TMap::exportMapToDatabase() * (void) TMap::importMapFromDatabase() * (QVector3D) TMap::span * (int) TMap::mViewArea * (QMap<QString, int>) TMap::pixNameTable * (QMap<int, QPixmap>) TMap::pixTable * (bool) TMap::isToDisplayAuditErrorsToConsole Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * ImplimentationFixes: activate a valid optimisation & remove redundant code Adding a true as a non-default 3rd argument to TRoomDB::addRoom(...) call in XMLimport::readRoom(...) enables a significant optimisation (skips a computationally expensive step when ADDING a room to new map) which dramatically reduces the time to parse an XML map file. It also pointed to the fact that the TRoomDB::entranceMap was already correctly being handled and didn't need to be regenerated in XMLimport::readRoom(...) so the code that was added in a previous commit was redundant and could be removed. A code error in TMap::slot_setDownloadProgress(...) that caused an issue that a reviewer found on test has been fixed - the total download filesize that was being sent by the Qt system signal that is connected to this slot was a -1 value (as IS DOCUMENTED) when the Qt system does NOT know the size of a QNetworkReply in advance of reaching the end of the download was incorrectly handled in a previous commit in this change set. Also found during testing that there is no need for an error message for the QNetworkReply::OperationCanceledError case in TMap::slot_replayFinished(...) as it is already handled in the TMap::slot_downloadCancel() slot. Changed the text put up onto the progress widget during the XML room parsing to be a room count - which is likely more useful and to only do it for every hundredth room - which reduces any delay "wasted" in writing to the display - combined, the effects seem satisfactory IMHO. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: provide error messages for TLuaInterpreter::loadMap(...) Errors for the XML map file importing process as initiated from the Lua command should be returned to that command rather than plastered onto the main profile console - this commit attempts to perform that effect. In testing found that there was no error handling for failure to find or open the nominated file so messages for that have been added as well. Due to the previous program logic the action of creating a mapper widget using the main toolbar button automatically loaded the "default" (the newest Mudlet Map file format file from the currently active profile's map sub-directory). Under some previous situations it looked as though a map might be loaded twice as mudlet::slot_mapper() was called both directly and via signal/slot action. These were resolved by turning that slot into a wrapper that now calls the body of code formerly within to a new method mudlet::createMapper( bool isToLoadDefaultMapFile = true ) with a the default value as an argument. This allows other usages of the body of code to be called directly with a suitable argument, which for the TConsole::loadMap() & TConsole::importMap() and the dlgProfilePreferences::downloadMap() cases is false as they are all do not want the "default" map! Also: * spotted a word "area" missing from an advisory text in TRoom::auditRooms(...). Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: fix minor bug, correct a spelling, undo a few capitalisations Under certain, unanticipated (error with no error message) conditions TLuaInterpreter::loadMap(...) would push both a nil and then a false value onto the stack for return {wrong} but only indicate one value {correct}. The textual matters were found during peer review. off-by: Stephen Lyons <slysven@virginmedia.com>
2016-10-13 09:18:48 +01:00
return;
}
// Incidentally this should address: https://bugs.launchpad.net/mudlet/+bug/852861
if (!mXmlImportMutex.tryLock(0)) {
QString warnMsg = QStringLiteral("[ WARN ] - Attempt made to download an XML map when one has already been\n"
"requested or is being imported from a local file - wait for that\n"
"operation to complete (if it cannot be canceled) before retrying!");
postMessage(warnMsg);
Enhance: fix map downloading code, add manual XML map importing (#326) * Enhance: fix map downloading code, add manual XML map importing A recent move by I.R.E. to using SSL for their public MUD map URLs broke the ability for Mudlet to download those XML format files. This commit addresses this issue (as mentioned in, but not the original problem referred to in https://bugs.launchpad.net/mudlet/+bug/1427364) the revision to the code does now use "https://www.<MUD URL>/maps/map.xml" as a default name for the I.R.E. MUDS - however the method that initiates the download which was moved to TMap class from the dlgMapper one (see below) is now: (bool) TMap::downloadMap( const QString * remoteUrl = Q_NULLPTR, const QString * localFileName = Q_NULLPTR ) which if not supplied with any arguments behaves as before. However the remoteUrl argument may be given as a full QString including the scheme (the bit of the URL at the beginning before the ':') to override that and a second argument may be used to provide a different name to use for the local file name which if is a RELATIVE pathFileName will be resolved in relation to the profile directory. At present no use is made of this additional functionality but it may be useful for use with other MUDs if they should choose to provide XML map files with other remote locations and scripts using a different local filename. As a long-standing thing that needed doing I have finally provided a means to import a map XML file that - for instance - has already been download. It had been noted that there was no way to read those I.R.E. map files even if they had been obtained from a web browser able to correctly handle https: URLs - now both the TLuaInterpreter::loadMap() and the dlgProfilePreference "loadMap" button {NOT the IRE only "map download" one} will both handle files ending in ".xml" (not case sensitive so it'll work MacOS platforms as well!} For the loadMap case it will be necessary to change the filetype filter on the File Selection dialog to select "xml" files. During testing it became clear to me that it was possible to try and read one or more XML files via several mechanisms simultaneously with "unhelpful" consequences. As well as hitting the dlgProfilePreferences IRE "map download" multiple times, the TLuaInterpreter::loadMap() does NOT block until the map has been loaded and as the import time {running of XMLinport::readPackage(...)} is of significant duration for a large map (a debug, without optimisation, build on my 1.8GHz Quad-core took over two minutes to process the current Achaea map file) it is very possible to get conditions where the same profile will try to run XMLinport::readPackage(...) asynchronously - given that a profile only supports ONE map at a time it was necessary to fit a QMutex to prevent the part of the XMLinport class relating to XML Map files being called from different places in the map related code. This means that if a map download is started further downloads and any local map imports will fail until that first download has completed or aborted. Similarly a local import will prevent a download being started. As a side effect this cures: https://bugs.launchpad.net/mudlet/+bug/852861 - "Map download button starts another download thread if one is already going" The previous XML import code was not adding the rooms that it parsed to the relevant TArea::rooms member - although this would be picked-up and fixed by TMap::audit() later on, this would be accompanied by an error message about every single room. The code now builds up this information while parsing the rooms' details and inserts it so that this does not cause report-able problems during the TMap::audit() execution - the data gathered also allows missing areas to be spotted so that if a room claimed to belong to an area that was not included in the preceding areas' data an unnamed area is created for it. As a consequence of the long time to actually parse an XML map file I have enhanced the progress dialog that was originally used to track the map file download. It is now retained until the file is completely imported and shows more information about the process - importantly it shows during the XMLimport::readRoom(...) the room id being processed - and THAT method is the time/cpu hog so seeing something happening during the time that Mudlet otherwise appears to hang is useful feedback even if it adds a few seconds to the overall duration (may be more than a minute). This dialog is now also used during the other routes that involve reading an XML file and there is now a bit of consistence with the on-screen messages. Whilst inspecting XMLimport class I found there was some uncertain initialisation which I have tidied up. In summary: Added: * (bool) TConsole::importMap(const QString & location) * (void) TRoomDB::setAreaRooms(const int areaId, const QSet<int> & roomIds) * image file mudlet_map_download.png used as icon for download/import progress dialog * (bool) TMap::importMap(QFile & file) * (bool) TMap::readXmlMapFile(QFile & file) * (void) TMap::slot_downloadError(QNetworkReply::NetworkError error) * (void) TMap::reportStringToProgressDialog(const QString text) * (void) TMap::reportProgressToProgressDialog(const int current, const int maximum) Revised: * (int)TLuaInterpreter::loadMap( lua_State * ) * Moved XML map download code from dlgMapper class to the TMap one: + (void) dlgMapper::downloadMap() ==> (bool) TMap::downloadMap(const QString * remoteUrl, const QString * localFileName) + (void) dlgMapper::setDownloadProgress(qint64, qint64) ==> (void) TMap::slot_setDownloadProgress(qint64,qint64) + (void) dlgMapper::cancel() ==> (void) TMap::slot_downloadCancel() + (void) dlgMapper::replyFinished(QNetworkReply *) ==> (void) TMap::slot_replyFinished(QNetworkReply *) * Enhanced download progress indication to also include parsing which can take even more time than download! * Provide means to import local XML map file * Prevent trying to import/download more than one map at a time Renamed: * (void) XMLimport::readAreaNames() ==> XMLimport::readArea() - for consistency with related functions Commented out unused: * (void) XMLimport::readUnknownRoomElement() Note the movement of the map file download code to the TMap class does require making the latter a class with the Q_OBJECT macro (which removes the need for Q_DECLARE_TR_FUNCTIONS as a side-effect!) - though as another side-effect the TMap header needed a boost name specifier added to one identifier as that identifier ("property") exists in both boost and QObject classes!!! YOU MAY NEED TO RUN QMAKE ON THE PROJECT IF THE BUILD SYSTEM DOES NOT PICK UP THE ADDITION OF "Q_OBJECT" TO TMAP CLASS. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: Include missing #include, remove unused return value The absence of this was causing build errors on the Travis C.I. platform! Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: move TMap.h to mudlet_MOC_HDRS to fix CMake build issue As we have made TMap inherit from QOject - to have signal/slot functionality that class needs to be run through Qt's MOC - and to do that with the CMake project/build system it needs to be included in the files included in the projects *_MOC_HDRS {and removed from the *_HDRS} variable. Also spotted a trivial error in that specifying a const return value from method is ineffective and pointless - so removed it from: TMap::retrieveMapFileStats(QString,QString *,int *,int *,int *,int *) Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: clean up TMap initialisation/clearing actions Now restores the customEnvColors set up on initialisation but that was cleared when the map replaced with another one that is loaded {which subsequently replaces that element anyway} or imported {which merely writes over it, replacing any matching keys}. Initialises elements that when inspected on the entry to the constructor proper previously were not being set to a consistent value {booleans/ints/floats}. NOTE: This will now clear the map user data member when the map is cleared if the date is required to be saved when one map is loaded OR IMPORTED over an existing one then the data will need to be saved outside of the map - as is already need for areas and rooms user data! Also comment out or remove unused members/methods: * (void) TMap::getConnectedNodesGreaterThanX(int, int) * (void) TMap::getConnectedNodesSmallerThanX(int, int) * (void) TMap::getConnectedNodesGreaterThanY(int, int) * (void) TMap::getConnectedNodesSmallerThanY(int, int) * (void) TMap::astBreitenAnpassung(int, int) * (void) TMap::astHoehenAnpassung(int, int) * (void) TMap::exportMapToDatabase() * (void) TMap::importMapFromDatabase() * (QVector3D) TMap::span * (int) TMap::mViewArea * (QMap<QString, int>) TMap::pixNameTable * (QMap<int, QPixmap>) TMap::pixTable * (bool) TMap::isToDisplayAuditErrorsToConsole Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * ImplimentationFixes: activate a valid optimisation & remove redundant code Adding a true as a non-default 3rd argument to TRoomDB::addRoom(...) call in XMLimport::readRoom(...) enables a significant optimisation (skips a computationally expensive step when ADDING a room to new map) which dramatically reduces the time to parse an XML map file. It also pointed to the fact that the TRoomDB::entranceMap was already correctly being handled and didn't need to be regenerated in XMLimport::readRoom(...) so the code that was added in a previous commit was redundant and could be removed. A code error in TMap::slot_setDownloadProgress(...) that caused an issue that a reviewer found on test has been fixed - the total download filesize that was being sent by the Qt system signal that is connected to this slot was a -1 value (as IS DOCUMENTED) when the Qt system does NOT know the size of a QNetworkReply in advance of reaching the end of the download was incorrectly handled in a previous commit in this change set. Also found during testing that there is no need for an error message for the QNetworkReply::OperationCanceledError case in TMap::slot_replayFinished(...) as it is already handled in the TMap::slot_downloadCancel() slot. Changed the text put up onto the progress widget during the XML room parsing to be a room count - which is likely more useful and to only do it for every hundredth room - which reduces any delay "wasted" in writing to the display - combined, the effects seem satisfactory IMHO. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: provide error messages for TLuaInterpreter::loadMap(...) Errors for the XML map file importing process as initiated from the Lua command should be returned to that command rather than plastered onto the main profile console - this commit attempts to perform that effect. In testing found that there was no error handling for failure to find or open the nominated file so messages for that have been added as well. Due to the previous program logic the action of creating a mapper widget using the main toolbar button automatically loaded the "default" (the newest Mudlet Map file format file from the currently active profile's map sub-directory). Under some previous situations it looked as though a map might be loaded twice as mudlet::slot_mapper() was called both directly and via signal/slot action. These were resolved by turning that slot into a wrapper that now calls the body of code formerly within to a new method mudlet::createMapper( bool isToLoadDefaultMapFile = true ) with a the default value as an argument. This allows other usages of the body of code to be called directly with a suitable argument, which for the TConsole::loadMap() & TConsole::importMap() and the dlgProfilePreferences::downloadMap() cases is false as they are all do not want the "default" map! Also: * spotted a word "area" missing from an advisory text in TRoom::auditRooms(...). Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: fix minor bug, correct a spelling, undo a few capitalisations Under certain, unanticipated (error with no error message) conditions TLuaInterpreter::loadMap(...) would push both a nil and then a false value onto the stack for return {wrong} but only indicate one value {correct}. The textual matters were found during peer review. off-by: Stephen Lyons <slysven@virginmedia.com>
2016-10-13 09:18:48 +01:00
return;
}
// We have the mutex locked - MUST unlock it when done under ALL circumstances
QUrl url;
if (remoteUrl.isEmpty()) {
Enhance: fix map downloading code, add manual XML map importing (#326) * Enhance: fix map downloading code, add manual XML map importing A recent move by I.R.E. to using SSL for their public MUD map URLs broke the ability for Mudlet to download those XML format files. This commit addresses this issue (as mentioned in, but not the original problem referred to in https://bugs.launchpad.net/mudlet/+bug/1427364) the revision to the code does now use "https://www.<MUD URL>/maps/map.xml" as a default name for the I.R.E. MUDS - however the method that initiates the download which was moved to TMap class from the dlgMapper one (see below) is now: (bool) TMap::downloadMap( const QString * remoteUrl = Q_NULLPTR, const QString * localFileName = Q_NULLPTR ) which if not supplied with any arguments behaves as before. However the remoteUrl argument may be given as a full QString including the scheme (the bit of the URL at the beginning before the ':') to override that and a second argument may be used to provide a different name to use for the local file name which if is a RELATIVE pathFileName will be resolved in relation to the profile directory. At present no use is made of this additional functionality but it may be useful for use with other MUDs if they should choose to provide XML map files with other remote locations and scripts using a different local filename. As a long-standing thing that needed doing I have finally provided a means to import a map XML file that - for instance - has already been download. It had been noted that there was no way to read those I.R.E. map files even if they had been obtained from a web browser able to correctly handle https: URLs - now both the TLuaInterpreter::loadMap() and the dlgProfilePreference "loadMap" button {NOT the IRE only "map download" one} will both handle files ending in ".xml" (not case sensitive so it'll work MacOS platforms as well!} For the loadMap case it will be necessary to change the filetype filter on the File Selection dialog to select "xml" files. During testing it became clear to me that it was possible to try and read one or more XML files via several mechanisms simultaneously with "unhelpful" consequences. As well as hitting the dlgProfilePreferences IRE "map download" multiple times, the TLuaInterpreter::loadMap() does NOT block until the map has been loaded and as the import time {running of XMLinport::readPackage(...)} is of significant duration for a large map (a debug, without optimisation, build on my 1.8GHz Quad-core took over two minutes to process the current Achaea map file) it is very possible to get conditions where the same profile will try to run XMLinport::readPackage(...) asynchronously - given that a profile only supports ONE map at a time it was necessary to fit a QMutex to prevent the part of the XMLinport class relating to XML Map files being called from different places in the map related code. This means that if a map download is started further downloads and any local map imports will fail until that first download has completed or aborted. Similarly a local import will prevent a download being started. As a side effect this cures: https://bugs.launchpad.net/mudlet/+bug/852861 - "Map download button starts another download thread if one is already going" The previous XML import code was not adding the rooms that it parsed to the relevant TArea::rooms member - although this would be picked-up and fixed by TMap::audit() later on, this would be accompanied by an error message about every single room. The code now builds up this information while parsing the rooms' details and inserts it so that this does not cause report-able problems during the TMap::audit() execution - the data gathered also allows missing areas to be spotted so that if a room claimed to belong to an area that was not included in the preceding areas' data an unnamed area is created for it. As a consequence of the long time to actually parse an XML map file I have enhanced the progress dialog that was originally used to track the map file download. It is now retained until the file is completely imported and shows more information about the process - importantly it shows during the XMLimport::readRoom(...) the room id being processed - and THAT method is the time/cpu hog so seeing something happening during the time that Mudlet otherwise appears to hang is useful feedback even if it adds a few seconds to the overall duration (may be more than a minute). This dialog is now also used during the other routes that involve reading an XML file and there is now a bit of consistence with the on-screen messages. Whilst inspecting XMLimport class I found there was some uncertain initialisation which I have tidied up. In summary: Added: * (bool) TConsole::importMap(const QString & location) * (void) TRoomDB::setAreaRooms(const int areaId, const QSet<int> & roomIds) * image file mudlet_map_download.png used as icon for download/import progress dialog * (bool) TMap::importMap(QFile & file) * (bool) TMap::readXmlMapFile(QFile & file) * (void) TMap::slot_downloadError(QNetworkReply::NetworkError error) * (void) TMap::reportStringToProgressDialog(const QString text) * (void) TMap::reportProgressToProgressDialog(const int current, const int maximum) Revised: * (int)TLuaInterpreter::loadMap( lua_State * ) * Moved XML map download code from dlgMapper class to the TMap one: + (void) dlgMapper::downloadMap() ==> (bool) TMap::downloadMap(const QString * remoteUrl, const QString * localFileName) + (void) dlgMapper::setDownloadProgress(qint64, qint64) ==> (void) TMap::slot_setDownloadProgress(qint64,qint64) + (void) dlgMapper::cancel() ==> (void) TMap::slot_downloadCancel() + (void) dlgMapper::replyFinished(QNetworkReply *) ==> (void) TMap::slot_replyFinished(QNetworkReply *) * Enhanced download progress indication to also include parsing which can take even more time than download! * Provide means to import local XML map file * Prevent trying to import/download more than one map at a time Renamed: * (void) XMLimport::readAreaNames() ==> XMLimport::readArea() - for consistency with related functions Commented out unused: * (void) XMLimport::readUnknownRoomElement() Note the movement of the map file download code to the TMap class does require making the latter a class with the Q_OBJECT macro (which removes the need for Q_DECLARE_TR_FUNCTIONS as a side-effect!) - though as another side-effect the TMap header needed a boost name specifier added to one identifier as that identifier ("property") exists in both boost and QObject classes!!! YOU MAY NEED TO RUN QMAKE ON THE PROJECT IF THE BUILD SYSTEM DOES NOT PICK UP THE ADDITION OF "Q_OBJECT" TO TMAP CLASS. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: Include missing #include, remove unused return value The absence of this was causing build errors on the Travis C.I. platform! Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: move TMap.h to mudlet_MOC_HDRS to fix CMake build issue As we have made TMap inherit from QOject - to have signal/slot functionality that class needs to be run through Qt's MOC - and to do that with the CMake project/build system it needs to be included in the files included in the projects *_MOC_HDRS {and removed from the *_HDRS} variable. Also spotted a trivial error in that specifying a const return value from method is ineffective and pointless - so removed it from: TMap::retrieveMapFileStats(QString,QString *,int *,int *,int *,int *) Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: clean up TMap initialisation/clearing actions Now restores the customEnvColors set up on initialisation but that was cleared when the map replaced with another one that is loaded {which subsequently replaces that element anyway} or imported {which merely writes over it, replacing any matching keys}. Initialises elements that when inspected on the entry to the constructor proper previously were not being set to a consistent value {booleans/ints/floats}. NOTE: This will now clear the map user data member when the map is cleared if the date is required to be saved when one map is loaded OR IMPORTED over an existing one then the data will need to be saved outside of the map - as is already need for areas and rooms user data! Also comment out or remove unused members/methods: * (void) TMap::getConnectedNodesGreaterThanX(int, int) * (void) TMap::getConnectedNodesSmallerThanX(int, int) * (void) TMap::getConnectedNodesGreaterThanY(int, int) * (void) TMap::getConnectedNodesSmallerThanY(int, int) * (void) TMap::astBreitenAnpassung(int, int) * (void) TMap::astHoehenAnpassung(int, int) * (void) TMap::exportMapToDatabase() * (void) TMap::importMapFromDatabase() * (QVector3D) TMap::span * (int) TMap::mViewArea * (QMap<QString, int>) TMap::pixNameTable * (QMap<int, QPixmap>) TMap::pixTable * (bool) TMap::isToDisplayAuditErrorsToConsole Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * ImplimentationFixes: activate a valid optimisation & remove redundant code Adding a true as a non-default 3rd argument to TRoomDB::addRoom(...) call in XMLimport::readRoom(...) enables a significant optimisation (skips a computationally expensive step when ADDING a room to new map) which dramatically reduces the time to parse an XML map file. It also pointed to the fact that the TRoomDB::entranceMap was already correctly being handled and didn't need to be regenerated in XMLimport::readRoom(...) so the code that was added in a previous commit was redundant and could be removed. A code error in TMap::slot_setDownloadProgress(...) that caused an issue that a reviewer found on test has been fixed - the total download filesize that was being sent by the Qt system signal that is connected to this slot was a -1 value (as IS DOCUMENTED) when the Qt system does NOT know the size of a QNetworkReply in advance of reaching the end of the download was incorrectly handled in a previous commit in this change set. Also found during testing that there is no need for an error message for the QNetworkReply::OperationCanceledError case in TMap::slot_replayFinished(...) as it is already handled in the TMap::slot_downloadCancel() slot. Changed the text put up onto the progress widget during the XML room parsing to be a room count - which is likely more useful and to only do it for every hundredth room - which reduces any delay "wasted" in writing to the display - combined, the effects seem satisfactory IMHO. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: provide error messages for TLuaInterpreter::loadMap(...) Errors for the XML map file importing process as initiated from the Lua command should be returned to that command rather than plastered onto the main profile console - this commit attempts to perform that effect. In testing found that there was no error handling for failure to find or open the nominated file so messages for that have been added as well. Due to the previous program logic the action of creating a mapper widget using the main toolbar button automatically loaded the "default" (the newest Mudlet Map file format file from the currently active profile's map sub-directory). Under some previous situations it looked as though a map might be loaded twice as mudlet::slot_mapper() was called both directly and via signal/slot action. These were resolved by turning that slot into a wrapper that now calls the body of code formerly within to a new method mudlet::createMapper( bool isToLoadDefaultMapFile = true ) with a the default value as an argument. This allows other usages of the body of code to be called directly with a suitable argument, which for the TConsole::loadMap() & TConsole::importMap() and the dlgProfilePreferences::downloadMap() cases is false as they are all do not want the "default" map! Also: * spotted a word "area" missing from an advisory text in TRoom::auditRooms(...). Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: fix minor bug, correct a spelling, undo a few capitalisations Under certain, unanticipated (error with no error message) conditions TLuaInterpreter::loadMap(...) would push both a nil and then a false value onto the stack for return {wrong} but only indicate one value {correct}. The textual matters were found during peer review. off-by: Stephen Lyons <slysven@virginmedia.com>
2016-10-13 09:18:48 +01:00
// TODO: Provide a per profile means to specify a "user settable" default Url...
url = QUrl::fromUserInput(QStringLiteral("https://www.%1/maps/map.xml").arg(pHost->mUrl));
} else {
url = QUrl::fromUserInput(remoteUrl);
Enhance: fix map downloading code, add manual XML map importing (#326) * Enhance: fix map downloading code, add manual XML map importing A recent move by I.R.E. to using SSL for their public MUD map URLs broke the ability for Mudlet to download those XML format files. This commit addresses this issue (as mentioned in, but not the original problem referred to in https://bugs.launchpad.net/mudlet/+bug/1427364) the revision to the code does now use "https://www.<MUD URL>/maps/map.xml" as a default name for the I.R.E. MUDS - however the method that initiates the download which was moved to TMap class from the dlgMapper one (see below) is now: (bool) TMap::downloadMap( const QString * remoteUrl = Q_NULLPTR, const QString * localFileName = Q_NULLPTR ) which if not supplied with any arguments behaves as before. However the remoteUrl argument may be given as a full QString including the scheme (the bit of the URL at the beginning before the ':') to override that and a second argument may be used to provide a different name to use for the local file name which if is a RELATIVE pathFileName will be resolved in relation to the profile directory. At present no use is made of this additional functionality but it may be useful for use with other MUDs if they should choose to provide XML map files with other remote locations and scripts using a different local filename. As a long-standing thing that needed doing I have finally provided a means to import a map XML file that - for instance - has already been download. It had been noted that there was no way to read those I.R.E. map files even if they had been obtained from a web browser able to correctly handle https: URLs - now both the TLuaInterpreter::loadMap() and the dlgProfilePreference "loadMap" button {NOT the IRE only "map download" one} will both handle files ending in ".xml" (not case sensitive so it'll work MacOS platforms as well!} For the loadMap case it will be necessary to change the filetype filter on the File Selection dialog to select "xml" files. During testing it became clear to me that it was possible to try and read one or more XML files via several mechanisms simultaneously with "unhelpful" consequences. As well as hitting the dlgProfilePreferences IRE "map download" multiple times, the TLuaInterpreter::loadMap() does NOT block until the map has been loaded and as the import time {running of XMLinport::readPackage(...)} is of significant duration for a large map (a debug, without optimisation, build on my 1.8GHz Quad-core took over two minutes to process the current Achaea map file) it is very possible to get conditions where the same profile will try to run XMLinport::readPackage(...) asynchronously - given that a profile only supports ONE map at a time it was necessary to fit a QMutex to prevent the part of the XMLinport class relating to XML Map files being called from different places in the map related code. This means that if a map download is started further downloads and any local map imports will fail until that first download has completed or aborted. Similarly a local import will prevent a download being started. As a side effect this cures: https://bugs.launchpad.net/mudlet/+bug/852861 - "Map download button starts another download thread if one is already going" The previous XML import code was not adding the rooms that it parsed to the relevant TArea::rooms member - although this would be picked-up and fixed by TMap::audit() later on, this would be accompanied by an error message about every single room. The code now builds up this information while parsing the rooms' details and inserts it so that this does not cause report-able problems during the TMap::audit() execution - the data gathered also allows missing areas to be spotted so that if a room claimed to belong to an area that was not included in the preceding areas' data an unnamed area is created for it. As a consequence of the long time to actually parse an XML map file I have enhanced the progress dialog that was originally used to track the map file download. It is now retained until the file is completely imported and shows more information about the process - importantly it shows during the XMLimport::readRoom(...) the room id being processed - and THAT method is the time/cpu hog so seeing something happening during the time that Mudlet otherwise appears to hang is useful feedback even if it adds a few seconds to the overall duration (may be more than a minute). This dialog is now also used during the other routes that involve reading an XML file and there is now a bit of consistence with the on-screen messages. Whilst inspecting XMLimport class I found there was some uncertain initialisation which I have tidied up. In summary: Added: * (bool) TConsole::importMap(const QString & location) * (void) TRoomDB::setAreaRooms(const int areaId, const QSet<int> & roomIds) * image file mudlet_map_download.png used as icon for download/import progress dialog * (bool) TMap::importMap(QFile & file) * (bool) TMap::readXmlMapFile(QFile & file) * (void) TMap::slot_downloadError(QNetworkReply::NetworkError error) * (void) TMap::reportStringToProgressDialog(const QString text) * (void) TMap::reportProgressToProgressDialog(const int current, const int maximum) Revised: * (int)TLuaInterpreter::loadMap( lua_State * ) * Moved XML map download code from dlgMapper class to the TMap one: + (void) dlgMapper::downloadMap() ==> (bool) TMap::downloadMap(const QString * remoteUrl, const QString * localFileName) + (void) dlgMapper::setDownloadProgress(qint64, qint64) ==> (void) TMap::slot_setDownloadProgress(qint64,qint64) + (void) dlgMapper::cancel() ==> (void) TMap::slot_downloadCancel() + (void) dlgMapper::replyFinished(QNetworkReply *) ==> (void) TMap::slot_replyFinished(QNetworkReply *) * Enhanced download progress indication to also include parsing which can take even more time than download! * Provide means to import local XML map file * Prevent trying to import/download more than one map at a time Renamed: * (void) XMLimport::readAreaNames() ==> XMLimport::readArea() - for consistency with related functions Commented out unused: * (void) XMLimport::readUnknownRoomElement() Note the movement of the map file download code to the TMap class does require making the latter a class with the Q_OBJECT macro (which removes the need for Q_DECLARE_TR_FUNCTIONS as a side-effect!) - though as another side-effect the TMap header needed a boost name specifier added to one identifier as that identifier ("property") exists in both boost and QObject classes!!! YOU MAY NEED TO RUN QMAKE ON THE PROJECT IF THE BUILD SYSTEM DOES NOT PICK UP THE ADDITION OF "Q_OBJECT" TO TMAP CLASS. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: Include missing #include, remove unused return value The absence of this was causing build errors on the Travis C.I. platform! Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: move TMap.h to mudlet_MOC_HDRS to fix CMake build issue As we have made TMap inherit from QOject - to have signal/slot functionality that class needs to be run through Qt's MOC - and to do that with the CMake project/build system it needs to be included in the files included in the projects *_MOC_HDRS {and removed from the *_HDRS} variable. Also spotted a trivial error in that specifying a const return value from method is ineffective and pointless - so removed it from: TMap::retrieveMapFileStats(QString,QString *,int *,int *,int *,int *) Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: clean up TMap initialisation/clearing actions Now restores the customEnvColors set up on initialisation but that was cleared when the map replaced with another one that is loaded {which subsequently replaces that element anyway} or imported {which merely writes over it, replacing any matching keys}. Initialises elements that when inspected on the entry to the constructor proper previously were not being set to a consistent value {booleans/ints/floats}. NOTE: This will now clear the map user data member when the map is cleared if the date is required to be saved when one map is loaded OR IMPORTED over an existing one then the data will need to be saved outside of the map - as is already need for areas and rooms user data! Also comment out or remove unused members/methods: * (void) TMap::getConnectedNodesGreaterThanX(int, int) * (void) TMap::getConnectedNodesSmallerThanX(int, int) * (void) TMap::getConnectedNodesGreaterThanY(int, int) * (void) TMap::getConnectedNodesSmallerThanY(int, int) * (void) TMap::astBreitenAnpassung(int, int) * (void) TMap::astHoehenAnpassung(int, int) * (void) TMap::exportMapToDatabase() * (void) TMap::importMapFromDatabase() * (QVector3D) TMap::span * (int) TMap::mViewArea * (QMap<QString, int>) TMap::pixNameTable * (QMap<int, QPixmap>) TMap::pixTable * (bool) TMap::isToDisplayAuditErrorsToConsole Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * ImplimentationFixes: activate a valid optimisation & remove redundant code Adding a true as a non-default 3rd argument to TRoomDB::addRoom(...) call in XMLimport::readRoom(...) enables a significant optimisation (skips a computationally expensive step when ADDING a room to new map) which dramatically reduces the time to parse an XML map file. It also pointed to the fact that the TRoomDB::entranceMap was already correctly being handled and didn't need to be regenerated in XMLimport::readRoom(...) so the code that was added in a previous commit was redundant and could be removed. A code error in TMap::slot_setDownloadProgress(...) that caused an issue that a reviewer found on test has been fixed - the total download filesize that was being sent by the Qt system signal that is connected to this slot was a -1 value (as IS DOCUMENTED) when the Qt system does NOT know the size of a QNetworkReply in advance of reaching the end of the download was incorrectly handled in a previous commit in this change set. Also found during testing that there is no need for an error message for the QNetworkReply::OperationCanceledError case in TMap::slot_replayFinished(...) as it is already handled in the TMap::slot_downloadCancel() slot. Changed the text put up onto the progress widget during the XML room parsing to be a room count - which is likely more useful and to only do it for every hundredth room - which reduces any delay "wasted" in writing to the display - combined, the effects seem satisfactory IMHO. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: provide error messages for TLuaInterpreter::loadMap(...) Errors for the XML map file importing process as initiated from the Lua command should be returned to that command rather than plastered onto the main profile console - this commit attempts to perform that effect. In testing found that there was no error handling for failure to find or open the nominated file so messages for that have been added as well. Due to the previous program logic the action of creating a mapper widget using the main toolbar button automatically loaded the "default" (the newest Mudlet Map file format file from the currently active profile's map sub-directory). Under some previous situations it looked as though a map might be loaded twice as mudlet::slot_mapper() was called both directly and via signal/slot action. These were resolved by turning that slot into a wrapper that now calls the body of code formerly within to a new method mudlet::createMapper( bool isToLoadDefaultMapFile = true ) with a the default value as an argument. This allows other usages of the body of code to be called directly with a suitable argument, which for the TConsole::loadMap() & TConsole::importMap() and the dlgProfilePreferences::downloadMap() cases is false as they are all do not want the "default" map! Also: * spotted a word "area" missing from an advisory text in TRoom::auditRooms(...). Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: fix minor bug, correct a spelling, undo a few capitalisations Under certain, unanticipated (error with no error message) conditions TLuaInterpreter::loadMap(...) would push both a nil and then a false value onto the stack for return {wrong} but only indicate one value {correct}. The textual matters were found during peer review. off-by: Stephen Lyons <slysven@virginmedia.com>
2016-10-13 09:18:48 +01:00
}
if (!url.isValid()) {
QString errMsg = QStringLiteral("[ WARN ] - Attempt made to download an XML from an invalid URL. The URL was:\n"
"%1\n"
"and the error message (may contain technical details) was:"
"\"%2\".")
.arg(url.toString(), url.errorString());
postMessage(errMsg);
Enhance: fix map downloading code, add manual XML map importing (#326) * Enhance: fix map downloading code, add manual XML map importing A recent move by I.R.E. to using SSL for their public MUD map URLs broke the ability for Mudlet to download those XML format files. This commit addresses this issue (as mentioned in, but not the original problem referred to in https://bugs.launchpad.net/mudlet/+bug/1427364) the revision to the code does now use "https://www.<MUD URL>/maps/map.xml" as a default name for the I.R.E. MUDS - however the method that initiates the download which was moved to TMap class from the dlgMapper one (see below) is now: (bool) TMap::downloadMap( const QString * remoteUrl = Q_NULLPTR, const QString * localFileName = Q_NULLPTR ) which if not supplied with any arguments behaves as before. However the remoteUrl argument may be given as a full QString including the scheme (the bit of the URL at the beginning before the ':') to override that and a second argument may be used to provide a different name to use for the local file name which if is a RELATIVE pathFileName will be resolved in relation to the profile directory. At present no use is made of this additional functionality but it may be useful for use with other MUDs if they should choose to provide XML map files with other remote locations and scripts using a different local filename. As a long-standing thing that needed doing I have finally provided a means to import a map XML file that - for instance - has already been download. It had been noted that there was no way to read those I.R.E. map files even if they had been obtained from a web browser able to correctly handle https: URLs - now both the TLuaInterpreter::loadMap() and the dlgProfilePreference "loadMap" button {NOT the IRE only "map download" one} will both handle files ending in ".xml" (not case sensitive so it'll work MacOS platforms as well!} For the loadMap case it will be necessary to change the filetype filter on the File Selection dialog to select "xml" files. During testing it became clear to me that it was possible to try and read one or more XML files via several mechanisms simultaneously with "unhelpful" consequences. As well as hitting the dlgProfilePreferences IRE "map download" multiple times, the TLuaInterpreter::loadMap() does NOT block until the map has been loaded and as the import time {running of XMLinport::readPackage(...)} is of significant duration for a large map (a debug, without optimisation, build on my 1.8GHz Quad-core took over two minutes to process the current Achaea map file) it is very possible to get conditions where the same profile will try to run XMLinport::readPackage(...) asynchronously - given that a profile only supports ONE map at a time it was necessary to fit a QMutex to prevent the part of the XMLinport class relating to XML Map files being called from different places in the map related code. This means that if a map download is started further downloads and any local map imports will fail until that first download has completed or aborted. Similarly a local import will prevent a download being started. As a side effect this cures: https://bugs.launchpad.net/mudlet/+bug/852861 - "Map download button starts another download thread if one is already going" The previous XML import code was not adding the rooms that it parsed to the relevant TArea::rooms member - although this would be picked-up and fixed by TMap::audit() later on, this would be accompanied by an error message about every single room. The code now builds up this information while parsing the rooms' details and inserts it so that this does not cause report-able problems during the TMap::audit() execution - the data gathered also allows missing areas to be spotted so that if a room claimed to belong to an area that was not included in the preceding areas' data an unnamed area is created for it. As a consequence of the long time to actually parse an XML map file I have enhanced the progress dialog that was originally used to track the map file download. It is now retained until the file is completely imported and shows more information about the process - importantly it shows during the XMLimport::readRoom(...) the room id being processed - and THAT method is the time/cpu hog so seeing something happening during the time that Mudlet otherwise appears to hang is useful feedback even if it adds a few seconds to the overall duration (may be more than a minute). This dialog is now also used during the other routes that involve reading an XML file and there is now a bit of consistence with the on-screen messages. Whilst inspecting XMLimport class I found there was some uncertain initialisation which I have tidied up. In summary: Added: * (bool) TConsole::importMap(const QString & location) * (void) TRoomDB::setAreaRooms(const int areaId, const QSet<int> & roomIds) * image file mudlet_map_download.png used as icon for download/import progress dialog * (bool) TMap::importMap(QFile & file) * (bool) TMap::readXmlMapFile(QFile & file) * (void) TMap::slot_downloadError(QNetworkReply::NetworkError error) * (void) TMap::reportStringToProgressDialog(const QString text) * (void) TMap::reportProgressToProgressDialog(const int current, const int maximum) Revised: * (int)TLuaInterpreter::loadMap( lua_State * ) * Moved XML map download code from dlgMapper class to the TMap one: + (void) dlgMapper::downloadMap() ==> (bool) TMap::downloadMap(const QString * remoteUrl, const QString * localFileName) + (void) dlgMapper::setDownloadProgress(qint64, qint64) ==> (void) TMap::slot_setDownloadProgress(qint64,qint64) + (void) dlgMapper::cancel() ==> (void) TMap::slot_downloadCancel() + (void) dlgMapper::replyFinished(QNetworkReply *) ==> (void) TMap::slot_replyFinished(QNetworkReply *) * Enhanced download progress indication to also include parsing which can take even more time than download! * Provide means to import local XML map file * Prevent trying to import/download more than one map at a time Renamed: * (void) XMLimport::readAreaNames() ==> XMLimport::readArea() - for consistency with related functions Commented out unused: * (void) XMLimport::readUnknownRoomElement() Note the movement of the map file download code to the TMap class does require making the latter a class with the Q_OBJECT macro (which removes the need for Q_DECLARE_TR_FUNCTIONS as a side-effect!) - though as another side-effect the TMap header needed a boost name specifier added to one identifier as that identifier ("property") exists in both boost and QObject classes!!! YOU MAY NEED TO RUN QMAKE ON THE PROJECT IF THE BUILD SYSTEM DOES NOT PICK UP THE ADDITION OF "Q_OBJECT" TO TMAP CLASS. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: Include missing #include, remove unused return value The absence of this was causing build errors on the Travis C.I. platform! Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: move TMap.h to mudlet_MOC_HDRS to fix CMake build issue As we have made TMap inherit from QOject - to have signal/slot functionality that class needs to be run through Qt's MOC - and to do that with the CMake project/build system it needs to be included in the files included in the projects *_MOC_HDRS {and removed from the *_HDRS} variable. Also spotted a trivial error in that specifying a const return value from method is ineffective and pointless - so removed it from: TMap::retrieveMapFileStats(QString,QString *,int *,int *,int *,int *) Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: clean up TMap initialisation/clearing actions Now restores the customEnvColors set up on initialisation but that was cleared when the map replaced with another one that is loaded {which subsequently replaces that element anyway} or imported {which merely writes over it, replacing any matching keys}. Initialises elements that when inspected on the entry to the constructor proper previously were not being set to a consistent value {booleans/ints/floats}. NOTE: This will now clear the map user data member when the map is cleared if the date is required to be saved when one map is loaded OR IMPORTED over an existing one then the data will need to be saved outside of the map - as is already need for areas and rooms user data! Also comment out or remove unused members/methods: * (void) TMap::getConnectedNodesGreaterThanX(int, int) * (void) TMap::getConnectedNodesSmallerThanX(int, int) * (void) TMap::getConnectedNodesGreaterThanY(int, int) * (void) TMap::getConnectedNodesSmallerThanY(int, int) * (void) TMap::astBreitenAnpassung(int, int) * (void) TMap::astHoehenAnpassung(int, int) * (void) TMap::exportMapToDatabase() * (void) TMap::importMapFromDatabase() * (QVector3D) TMap::span * (int) TMap::mViewArea * (QMap<QString, int>) TMap::pixNameTable * (QMap<int, QPixmap>) TMap::pixTable * (bool) TMap::isToDisplayAuditErrorsToConsole Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * ImplimentationFixes: activate a valid optimisation & remove redundant code Adding a true as a non-default 3rd argument to TRoomDB::addRoom(...) call in XMLimport::readRoom(...) enables a significant optimisation (skips a computationally expensive step when ADDING a room to new map) which dramatically reduces the time to parse an XML map file. It also pointed to the fact that the TRoomDB::entranceMap was already correctly being handled and didn't need to be regenerated in XMLimport::readRoom(...) so the code that was added in a previous commit was redundant and could be removed. A code error in TMap::slot_setDownloadProgress(...) that caused an issue that a reviewer found on test has been fixed - the total download filesize that was being sent by the Qt system signal that is connected to this slot was a -1 value (as IS DOCUMENTED) when the Qt system does NOT know the size of a QNetworkReply in advance of reaching the end of the download was incorrectly handled in a previous commit in this change set. Also found during testing that there is no need for an error message for the QNetworkReply::OperationCanceledError case in TMap::slot_replayFinished(...) as it is already handled in the TMap::slot_downloadCancel() slot. Changed the text put up onto the progress widget during the XML room parsing to be a room count - which is likely more useful and to only do it for every hundredth room - which reduces any delay "wasted" in writing to the display - combined, the effects seem satisfactory IMHO. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: provide error messages for TLuaInterpreter::loadMap(...) Errors for the XML map file importing process as initiated from the Lua command should be returned to that command rather than plastered onto the main profile console - this commit attempts to perform that effect. In testing found that there was no error handling for failure to find or open the nominated file so messages for that have been added as well. Due to the previous program logic the action of creating a mapper widget using the main toolbar button automatically loaded the "default" (the newest Mudlet Map file format file from the currently active profile's map sub-directory). Under some previous situations it looked as though a map might be loaded twice as mudlet::slot_mapper() was called both directly and via signal/slot action. These were resolved by turning that slot into a wrapper that now calls the body of code formerly within to a new method mudlet::createMapper( bool isToLoadDefaultMapFile = true ) with a the default value as an argument. This allows other usages of the body of code to be called directly with a suitable argument, which for the TConsole::loadMap() & TConsole::importMap() and the dlgProfilePreferences::downloadMap() cases is false as they are all do not want the "default" map! Also: * spotted a word "area" missing from an advisory text in TRoom::auditRooms(...). Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: fix minor bug, correct a spelling, undo a few capitalisations Under certain, unanticipated (error with no error message) conditions TLuaInterpreter::loadMap(...) would push both a nil and then a false value onto the stack for return {wrong} but only indicate one value {correct}. The textual matters were found during peer review. off-by: Stephen Lyons <slysven@virginmedia.com>
2016-10-13 09:18:48 +01:00
mXmlImportMutex.unlock();
return;
}
if (localFileName.isEmpty()) {
Refactor: reduce use of raw string literals for directories and file paths Using a static method means that we can centralise the generation of strings used to access parts of the file system used to hold Mudlet user data - which may be useful if we change them for - say running from a thumb-drive or just to use an OS specific location for them. {Using a ".config/mudlet" sub-directory on Windows is not quite how that OS expects things to be done...!} This also reduces the number of raw strings that will have to be wrapped in QStringLiteral(...) and the like for forthcoming I18n work. Also: * The use of "mudlet-data" as a windows symlink sub-directory to ".config/mudlet" in the user home directory may not work because the Qt Documentation suggests that a ".lnk" extension is required - this commit adds that FOR THAT OS ONLY. * Previous code placed (only some - for an unexplained reason not all the files were being copied) the DejaVu fonts that we include in the resources directly into the main mudlet user data folder - but the included documentation including the COPYRIGHT.TXT and other files ONLY relate to those font files and NOT to Mudlet as a whole. I have taken the liberty of moving and loading them from a ./fonts/ subdirectory which makes more sense. I have noted that, at least, the Debian Linux packager actually removes the font files from their configuration because they already include a shared system wide copy of the same fonts and in a much newer (2.37 at present) version compared to the 1.10 that we bundle - perhaps our code needs to check for the existence/availability of the fonts before we try to load ours into the Mudlet application at run-time! Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2017-09-18 16:23:57 +01:00
mLocalMapFileName = mudlet::getMudletPath(mudlet::profileXmlMapPathFileName, pHost->getName());
} else {
mLocalMapFileName = localFileName;
Enhance: fix map downloading code, add manual XML map importing (#326) * Enhance: fix map downloading code, add manual XML map importing A recent move by I.R.E. to using SSL for their public MUD map URLs broke the ability for Mudlet to download those XML format files. This commit addresses this issue (as mentioned in, but not the original problem referred to in https://bugs.launchpad.net/mudlet/+bug/1427364) the revision to the code does now use "https://www.<MUD URL>/maps/map.xml" as a default name for the I.R.E. MUDS - however the method that initiates the download which was moved to TMap class from the dlgMapper one (see below) is now: (bool) TMap::downloadMap( const QString * remoteUrl = Q_NULLPTR, const QString * localFileName = Q_NULLPTR ) which if not supplied with any arguments behaves as before. However the remoteUrl argument may be given as a full QString including the scheme (the bit of the URL at the beginning before the ':') to override that and a second argument may be used to provide a different name to use for the local file name which if is a RELATIVE pathFileName will be resolved in relation to the profile directory. At present no use is made of this additional functionality but it may be useful for use with other MUDs if they should choose to provide XML map files with other remote locations and scripts using a different local filename. As a long-standing thing that needed doing I have finally provided a means to import a map XML file that - for instance - has already been download. It had been noted that there was no way to read those I.R.E. map files even if they had been obtained from a web browser able to correctly handle https: URLs - now both the TLuaInterpreter::loadMap() and the dlgProfilePreference "loadMap" button {NOT the IRE only "map download" one} will both handle files ending in ".xml" (not case sensitive so it'll work MacOS platforms as well!} For the loadMap case it will be necessary to change the filetype filter on the File Selection dialog to select "xml" files. During testing it became clear to me that it was possible to try and read one or more XML files via several mechanisms simultaneously with "unhelpful" consequences. As well as hitting the dlgProfilePreferences IRE "map download" multiple times, the TLuaInterpreter::loadMap() does NOT block until the map has been loaded and as the import time {running of XMLinport::readPackage(...)} is of significant duration for a large map (a debug, without optimisation, build on my 1.8GHz Quad-core took over two minutes to process the current Achaea map file) it is very possible to get conditions where the same profile will try to run XMLinport::readPackage(...) asynchronously - given that a profile only supports ONE map at a time it was necessary to fit a QMutex to prevent the part of the XMLinport class relating to XML Map files being called from different places in the map related code. This means that if a map download is started further downloads and any local map imports will fail until that first download has completed or aborted. Similarly a local import will prevent a download being started. As a side effect this cures: https://bugs.launchpad.net/mudlet/+bug/852861 - "Map download button starts another download thread if one is already going" The previous XML import code was not adding the rooms that it parsed to the relevant TArea::rooms member - although this would be picked-up and fixed by TMap::audit() later on, this would be accompanied by an error message about every single room. The code now builds up this information while parsing the rooms' details and inserts it so that this does not cause report-able problems during the TMap::audit() execution - the data gathered also allows missing areas to be spotted so that if a room claimed to belong to an area that was not included in the preceding areas' data an unnamed area is created for it. As a consequence of the long time to actually parse an XML map file I have enhanced the progress dialog that was originally used to track the map file download. It is now retained until the file is completely imported and shows more information about the process - importantly it shows during the XMLimport::readRoom(...) the room id being processed - and THAT method is the time/cpu hog so seeing something happening during the time that Mudlet otherwise appears to hang is useful feedback even if it adds a few seconds to the overall duration (may be more than a minute). This dialog is now also used during the other routes that involve reading an XML file and there is now a bit of consistence with the on-screen messages. Whilst inspecting XMLimport class I found there was some uncertain initialisation which I have tidied up. In summary: Added: * (bool) TConsole::importMap(const QString & location) * (void) TRoomDB::setAreaRooms(const int areaId, const QSet<int> & roomIds) * image file mudlet_map_download.png used as icon for download/import progress dialog * (bool) TMap::importMap(QFile & file) * (bool) TMap::readXmlMapFile(QFile & file) * (void) TMap::slot_downloadError(QNetworkReply::NetworkError error) * (void) TMap::reportStringToProgressDialog(const QString text) * (void) TMap::reportProgressToProgressDialog(const int current, const int maximum) Revised: * (int)TLuaInterpreter::loadMap( lua_State * ) * Moved XML map download code from dlgMapper class to the TMap one: + (void) dlgMapper::downloadMap() ==> (bool) TMap::downloadMap(const QString * remoteUrl, const QString * localFileName) + (void) dlgMapper::setDownloadProgress(qint64, qint64) ==> (void) TMap::slot_setDownloadProgress(qint64,qint64) + (void) dlgMapper::cancel() ==> (void) TMap::slot_downloadCancel() + (void) dlgMapper::replyFinished(QNetworkReply *) ==> (void) TMap::slot_replyFinished(QNetworkReply *) * Enhanced download progress indication to also include parsing which can take even more time than download! * Provide means to import local XML map file * Prevent trying to import/download more than one map at a time Renamed: * (void) XMLimport::readAreaNames() ==> XMLimport::readArea() - for consistency with related functions Commented out unused: * (void) XMLimport::readUnknownRoomElement() Note the movement of the map file download code to the TMap class does require making the latter a class with the Q_OBJECT macro (which removes the need for Q_DECLARE_TR_FUNCTIONS as a side-effect!) - though as another side-effect the TMap header needed a boost name specifier added to one identifier as that identifier ("property") exists in both boost and QObject classes!!! YOU MAY NEED TO RUN QMAKE ON THE PROJECT IF THE BUILD SYSTEM DOES NOT PICK UP THE ADDITION OF "Q_OBJECT" TO TMAP CLASS. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: Include missing #include, remove unused return value The absence of this was causing build errors on the Travis C.I. platform! Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: move TMap.h to mudlet_MOC_HDRS to fix CMake build issue As we have made TMap inherit from QOject - to have signal/slot functionality that class needs to be run through Qt's MOC - and to do that with the CMake project/build system it needs to be included in the files included in the projects *_MOC_HDRS {and removed from the *_HDRS} variable. Also spotted a trivial error in that specifying a const return value from method is ineffective and pointless - so removed it from: TMap::retrieveMapFileStats(QString,QString *,int *,int *,int *,int *) Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: clean up TMap initialisation/clearing actions Now restores the customEnvColors set up on initialisation but that was cleared when the map replaced with another one that is loaded {which subsequently replaces that element anyway} or imported {which merely writes over it, replacing any matching keys}. Initialises elements that when inspected on the entry to the constructor proper previously were not being set to a consistent value {booleans/ints/floats}. NOTE: This will now clear the map user data member when the map is cleared if the date is required to be saved when one map is loaded OR IMPORTED over an existing one then the data will need to be saved outside of the map - as is already need for areas and rooms user data! Also comment out or remove unused members/methods: * (void) TMap::getConnectedNodesGreaterThanX(int, int) * (void) TMap::getConnectedNodesSmallerThanX(int, int) * (void) TMap::getConnectedNodesGreaterThanY(int, int) * (void) TMap::getConnectedNodesSmallerThanY(int, int) * (void) TMap::astBreitenAnpassung(int, int) * (void) TMap::astHoehenAnpassung(int, int) * (void) TMap::exportMapToDatabase() * (void) TMap::importMapFromDatabase() * (QVector3D) TMap::span * (int) TMap::mViewArea * (QMap<QString, int>) TMap::pixNameTable * (QMap<int, QPixmap>) TMap::pixTable * (bool) TMap::isToDisplayAuditErrorsToConsole Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * ImplimentationFixes: activate a valid optimisation & remove redundant code Adding a true as a non-default 3rd argument to TRoomDB::addRoom(...) call in XMLimport::readRoom(...) enables a significant optimisation (skips a computationally expensive step when ADDING a room to new map) which dramatically reduces the time to parse an XML map file. It also pointed to the fact that the TRoomDB::entranceMap was already correctly being handled and didn't need to be regenerated in XMLimport::readRoom(...) so the code that was added in a previous commit was redundant and could be removed. A code error in TMap::slot_setDownloadProgress(...) that caused an issue that a reviewer found on test has been fixed - the total download filesize that was being sent by the Qt system signal that is connected to this slot was a -1 value (as IS DOCUMENTED) when the Qt system does NOT know the size of a QNetworkReply in advance of reaching the end of the download was incorrectly handled in a previous commit in this change set. Also found during testing that there is no need for an error message for the QNetworkReply::OperationCanceledError case in TMap::slot_replayFinished(...) as it is already handled in the TMap::slot_downloadCancel() slot. Changed the text put up onto the progress widget during the XML room parsing to be a room count - which is likely more useful and to only do it for every hundredth room - which reduces any delay "wasted" in writing to the display - combined, the effects seem satisfactory IMHO. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: provide error messages for TLuaInterpreter::loadMap(...) Errors for the XML map file importing process as initiated from the Lua command should be returned to that command rather than plastered onto the main profile console - this commit attempts to perform that effect. In testing found that there was no error handling for failure to find or open the nominated file so messages for that have been added as well. Due to the previous program logic the action of creating a mapper widget using the main toolbar button automatically loaded the "default" (the newest Mudlet Map file format file from the currently active profile's map sub-directory). Under some previous situations it looked as though a map might be loaded twice as mudlet::slot_mapper() was called both directly and via signal/slot action. These were resolved by turning that slot into a wrapper that now calls the body of code formerly within to a new method mudlet::createMapper( bool isToLoadDefaultMapFile = true ) with a the default value as an argument. This allows other usages of the body of code to be called directly with a suitable argument, which for the TConsole::loadMap() & TConsole::importMap() and the dlgProfilePreferences::downloadMap() cases is false as they are all do not want the "default" map! Also: * spotted a word "area" missing from an advisory text in TRoom::auditRooms(...). Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: fix minor bug, correct a spelling, undo a few capitalisations Under certain, unanticipated (error with no error message) conditions TLuaInterpreter::loadMap(...) would push both a nil and then a false value onto the stack for return {wrong} but only indicate one value {correct}. The textual matters were found during peer review. off-by: Stephen Lyons <slysven@virginmedia.com>
2016-10-13 09:18:48 +01:00
}
QNetworkRequest request = QNetworkRequest(url);
Enhance: fix map downloading code, add manual XML map importing (#326) * Enhance: fix map downloading code, add manual XML map importing A recent move by I.R.E. to using SSL for their public MUD map URLs broke the ability for Mudlet to download those XML format files. This commit addresses this issue (as mentioned in, but not the original problem referred to in https://bugs.launchpad.net/mudlet/+bug/1427364) the revision to the code does now use "https://www.<MUD URL>/maps/map.xml" as a default name for the I.R.E. MUDS - however the method that initiates the download which was moved to TMap class from the dlgMapper one (see below) is now: (bool) TMap::downloadMap( const QString * remoteUrl = Q_NULLPTR, const QString * localFileName = Q_NULLPTR ) which if not supplied with any arguments behaves as before. However the remoteUrl argument may be given as a full QString including the scheme (the bit of the URL at the beginning before the ':') to override that and a second argument may be used to provide a different name to use for the local file name which if is a RELATIVE pathFileName will be resolved in relation to the profile directory. At present no use is made of this additional functionality but it may be useful for use with other MUDs if they should choose to provide XML map files with other remote locations and scripts using a different local filename. As a long-standing thing that needed doing I have finally provided a means to import a map XML file that - for instance - has already been download. It had been noted that there was no way to read those I.R.E. map files even if they had been obtained from a web browser able to correctly handle https: URLs - now both the TLuaInterpreter::loadMap() and the dlgProfilePreference "loadMap" button {NOT the IRE only "map download" one} will both handle files ending in ".xml" (not case sensitive so it'll work MacOS platforms as well!} For the loadMap case it will be necessary to change the filetype filter on the File Selection dialog to select "xml" files. During testing it became clear to me that it was possible to try and read one or more XML files via several mechanisms simultaneously with "unhelpful" consequences. As well as hitting the dlgProfilePreferences IRE "map download" multiple times, the TLuaInterpreter::loadMap() does NOT block until the map has been loaded and as the import time {running of XMLinport::readPackage(...)} is of significant duration for a large map (a debug, without optimisation, build on my 1.8GHz Quad-core took over two minutes to process the current Achaea map file) it is very possible to get conditions where the same profile will try to run XMLinport::readPackage(...) asynchronously - given that a profile only supports ONE map at a time it was necessary to fit a QMutex to prevent the part of the XMLinport class relating to XML Map files being called from different places in the map related code. This means that if a map download is started further downloads and any local map imports will fail until that first download has completed or aborted. Similarly a local import will prevent a download being started. As a side effect this cures: https://bugs.launchpad.net/mudlet/+bug/852861 - "Map download button starts another download thread if one is already going" The previous XML import code was not adding the rooms that it parsed to the relevant TArea::rooms member - although this would be picked-up and fixed by TMap::audit() later on, this would be accompanied by an error message about every single room. The code now builds up this information while parsing the rooms' details and inserts it so that this does not cause report-able problems during the TMap::audit() execution - the data gathered also allows missing areas to be spotted so that if a room claimed to belong to an area that was not included in the preceding areas' data an unnamed area is created for it. As a consequence of the long time to actually parse an XML map file I have enhanced the progress dialog that was originally used to track the map file download. It is now retained until the file is completely imported and shows more information about the process - importantly it shows during the XMLimport::readRoom(...) the room id being processed - and THAT method is the time/cpu hog so seeing something happening during the time that Mudlet otherwise appears to hang is useful feedback even if it adds a few seconds to the overall duration (may be more than a minute). This dialog is now also used during the other routes that involve reading an XML file and there is now a bit of consistence with the on-screen messages. Whilst inspecting XMLimport class I found there was some uncertain initialisation which I have tidied up. In summary: Added: * (bool) TConsole::importMap(const QString & location) * (void) TRoomDB::setAreaRooms(const int areaId, const QSet<int> & roomIds) * image file mudlet_map_download.png used as icon for download/import progress dialog * (bool) TMap::importMap(QFile & file) * (bool) TMap::readXmlMapFile(QFile & file) * (void) TMap::slot_downloadError(QNetworkReply::NetworkError error) * (void) TMap::reportStringToProgressDialog(const QString text) * (void) TMap::reportProgressToProgressDialog(const int current, const int maximum) Revised: * (int)TLuaInterpreter::loadMap( lua_State * ) * Moved XML map download code from dlgMapper class to the TMap one: + (void) dlgMapper::downloadMap() ==> (bool) TMap::downloadMap(const QString * remoteUrl, const QString * localFileName) + (void) dlgMapper::setDownloadProgress(qint64, qint64) ==> (void) TMap::slot_setDownloadProgress(qint64,qint64) + (void) dlgMapper::cancel() ==> (void) TMap::slot_downloadCancel() + (void) dlgMapper::replyFinished(QNetworkReply *) ==> (void) TMap::slot_replyFinished(QNetworkReply *) * Enhanced download progress indication to also include parsing which can take even more time than download! * Provide means to import local XML map file * Prevent trying to import/download more than one map at a time Renamed: * (void) XMLimport::readAreaNames() ==> XMLimport::readArea() - for consistency with related functions Commented out unused: * (void) XMLimport::readUnknownRoomElement() Note the movement of the map file download code to the TMap class does require making the latter a class with the Q_OBJECT macro (which removes the need for Q_DECLARE_TR_FUNCTIONS as a side-effect!) - though as another side-effect the TMap header needed a boost name specifier added to one identifier as that identifier ("property") exists in both boost and QObject classes!!! YOU MAY NEED TO RUN QMAKE ON THE PROJECT IF THE BUILD SYSTEM DOES NOT PICK UP THE ADDITION OF "Q_OBJECT" TO TMAP CLASS. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: Include missing #include, remove unused return value The absence of this was causing build errors on the Travis C.I. platform! Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: move TMap.h to mudlet_MOC_HDRS to fix CMake build issue As we have made TMap inherit from QOject - to have signal/slot functionality that class needs to be run through Qt's MOC - and to do that with the CMake project/build system it needs to be included in the files included in the projects *_MOC_HDRS {and removed from the *_HDRS} variable. Also spotted a trivial error in that specifying a const return value from method is ineffective and pointless - so removed it from: TMap::retrieveMapFileStats(QString,QString *,int *,int *,int *,int *) Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: clean up TMap initialisation/clearing actions Now restores the customEnvColors set up on initialisation but that was cleared when the map replaced with another one that is loaded {which subsequently replaces that element anyway} or imported {which merely writes over it, replacing any matching keys}. Initialises elements that when inspected on the entry to the constructor proper previously were not being set to a consistent value {booleans/ints/floats}. NOTE: This will now clear the map user data member when the map is cleared if the date is required to be saved when one map is loaded OR IMPORTED over an existing one then the data will need to be saved outside of the map - as is already need for areas and rooms user data! Also comment out or remove unused members/methods: * (void) TMap::getConnectedNodesGreaterThanX(int, int) * (void) TMap::getConnectedNodesSmallerThanX(int, int) * (void) TMap::getConnectedNodesGreaterThanY(int, int) * (void) TMap::getConnectedNodesSmallerThanY(int, int) * (void) TMap::astBreitenAnpassung(int, int) * (void) TMap::astHoehenAnpassung(int, int) * (void) TMap::exportMapToDatabase() * (void) TMap::importMapFromDatabase() * (QVector3D) TMap::span * (int) TMap::mViewArea * (QMap<QString, int>) TMap::pixNameTable * (QMap<int, QPixmap>) TMap::pixTable * (bool) TMap::isToDisplayAuditErrorsToConsole Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * ImplimentationFixes: activate a valid optimisation & remove redundant code Adding a true as a non-default 3rd argument to TRoomDB::addRoom(...) call in XMLimport::readRoom(...) enables a significant optimisation (skips a computationally expensive step when ADDING a room to new map) which dramatically reduces the time to parse an XML map file. It also pointed to the fact that the TRoomDB::entranceMap was already correctly being handled and didn't need to be regenerated in XMLimport::readRoom(...) so the code that was added in a previous commit was redundant and could be removed. A code error in TMap::slot_setDownloadProgress(...) that caused an issue that a reviewer found on test has been fixed - the total download filesize that was being sent by the Qt system signal that is connected to this slot was a -1 value (as IS DOCUMENTED) when the Qt system does NOT know the size of a QNetworkReply in advance of reaching the end of the download was incorrectly handled in a previous commit in this change set. Also found during testing that there is no need for an error message for the QNetworkReply::OperationCanceledError case in TMap::slot_replayFinished(...) as it is already handled in the TMap::slot_downloadCancel() slot. Changed the text put up onto the progress widget during the XML room parsing to be a room count - which is likely more useful and to only do it for every hundredth room - which reduces any delay "wasted" in writing to the display - combined, the effects seem satisfactory IMHO. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: provide error messages for TLuaInterpreter::loadMap(...) Errors for the XML map file importing process as initiated from the Lua command should be returned to that command rather than plastered onto the main profile console - this commit attempts to perform that effect. In testing found that there was no error handling for failure to find or open the nominated file so messages for that have been added as well. Due to the previous program logic the action of creating a mapper widget using the main toolbar button automatically loaded the "default" (the newest Mudlet Map file format file from the currently active profile's map sub-directory). Under some previous situations it looked as though a map might be loaded twice as mudlet::slot_mapper() was called both directly and via signal/slot action. These were resolved by turning that slot into a wrapper that now calls the body of code formerly within to a new method mudlet::createMapper( bool isToLoadDefaultMapFile = true ) with a the default value as an argument. This allows other usages of the body of code to be called directly with a suitable argument, which for the TConsole::loadMap() & TConsole::importMap() and the dlgProfilePreferences::downloadMap() cases is false as they are all do not want the "default" map! Also: * spotted a word "area" missing from an advisory text in TRoom::auditRooms(...). Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: fix minor bug, correct a spelling, undo a few capitalisations Under certain, unanticipated (error with no error message) conditions TLuaInterpreter::loadMap(...) would push both a nil and then a false value onto the stack for return {wrong} but only indicate one value {correct}. The textual matters were found during peer review. off-by: Stephen Lyons <slysven@virginmedia.com>
2016-10-13 09:18:48 +01:00
// This should prevent similar problems to those mentioned in:
// https://bugs.launchpad.net/mudlet/+bug/1366781 although the fix for THAT
// is elsewhere and is to be inserted separately to the changeset that
// placed this code here:
request.setRawHeader(QByteArray("User-Agent"), QByteArray(QStringLiteral("Mozilla/5.0 (Mudlet/%1%2)").arg(APP_VERSION, APP_BUILD).toUtf8().constData()));
Enhance: fix map downloading code, add manual XML map importing (#326) * Enhance: fix map downloading code, add manual XML map importing A recent move by I.R.E. to using SSL for their public MUD map URLs broke the ability for Mudlet to download those XML format files. This commit addresses this issue (as mentioned in, but not the original problem referred to in https://bugs.launchpad.net/mudlet/+bug/1427364) the revision to the code does now use "https://www.<MUD URL>/maps/map.xml" as a default name for the I.R.E. MUDS - however the method that initiates the download which was moved to TMap class from the dlgMapper one (see below) is now: (bool) TMap::downloadMap( const QString * remoteUrl = Q_NULLPTR, const QString * localFileName = Q_NULLPTR ) which if not supplied with any arguments behaves as before. However the remoteUrl argument may be given as a full QString including the scheme (the bit of the URL at the beginning before the ':') to override that and a second argument may be used to provide a different name to use for the local file name which if is a RELATIVE pathFileName will be resolved in relation to the profile directory. At present no use is made of this additional functionality but it may be useful for use with other MUDs if they should choose to provide XML map files with other remote locations and scripts using a different local filename. As a long-standing thing that needed doing I have finally provided a means to import a map XML file that - for instance - has already been download. It had been noted that there was no way to read those I.R.E. map files even if they had been obtained from a web browser able to correctly handle https: URLs - now both the TLuaInterpreter::loadMap() and the dlgProfilePreference "loadMap" button {NOT the IRE only "map download" one} will both handle files ending in ".xml" (not case sensitive so it'll work MacOS platforms as well!} For the loadMap case it will be necessary to change the filetype filter on the File Selection dialog to select "xml" files. During testing it became clear to me that it was possible to try and read one or more XML files via several mechanisms simultaneously with "unhelpful" consequences. As well as hitting the dlgProfilePreferences IRE "map download" multiple times, the TLuaInterpreter::loadMap() does NOT block until the map has been loaded and as the import time {running of XMLinport::readPackage(...)} is of significant duration for a large map (a debug, without optimisation, build on my 1.8GHz Quad-core took over two minutes to process the current Achaea map file) it is very possible to get conditions where the same profile will try to run XMLinport::readPackage(...) asynchronously - given that a profile only supports ONE map at a time it was necessary to fit a QMutex to prevent the part of the XMLinport class relating to XML Map files being called from different places in the map related code. This means that if a map download is started further downloads and any local map imports will fail until that first download has completed or aborted. Similarly a local import will prevent a download being started. As a side effect this cures: https://bugs.launchpad.net/mudlet/+bug/852861 - "Map download button starts another download thread if one is already going" The previous XML import code was not adding the rooms that it parsed to the relevant TArea::rooms member - although this would be picked-up and fixed by TMap::audit() later on, this would be accompanied by an error message about every single room. The code now builds up this information while parsing the rooms' details and inserts it so that this does not cause report-able problems during the TMap::audit() execution - the data gathered also allows missing areas to be spotted so that if a room claimed to belong to an area that was not included in the preceding areas' data an unnamed area is created for it. As a consequence of the long time to actually parse an XML map file I have enhanced the progress dialog that was originally used to track the map file download. It is now retained until the file is completely imported and shows more information about the process - importantly it shows during the XMLimport::readRoom(...) the room id being processed - and THAT method is the time/cpu hog so seeing something happening during the time that Mudlet otherwise appears to hang is useful feedback even if it adds a few seconds to the overall duration (may be more than a minute). This dialog is now also used during the other routes that involve reading an XML file and there is now a bit of consistence with the on-screen messages. Whilst inspecting XMLimport class I found there was some uncertain initialisation which I have tidied up. In summary: Added: * (bool) TConsole::importMap(const QString & location) * (void) TRoomDB::setAreaRooms(const int areaId, const QSet<int> & roomIds) * image file mudlet_map_download.png used as icon for download/import progress dialog * (bool) TMap::importMap(QFile & file) * (bool) TMap::readXmlMapFile(QFile & file) * (void) TMap::slot_downloadError(QNetworkReply::NetworkError error) * (void) TMap::reportStringToProgressDialog(const QString text) * (void) TMap::reportProgressToProgressDialog(const int current, const int maximum) Revised: * (int)TLuaInterpreter::loadMap( lua_State * ) * Moved XML map download code from dlgMapper class to the TMap one: + (void) dlgMapper::downloadMap() ==> (bool) TMap::downloadMap(const QString * remoteUrl, const QString * localFileName) + (void) dlgMapper::setDownloadProgress(qint64, qint64) ==> (void) TMap::slot_setDownloadProgress(qint64,qint64) + (void) dlgMapper::cancel() ==> (void) TMap::slot_downloadCancel() + (void) dlgMapper::replyFinished(QNetworkReply *) ==> (void) TMap::slot_replyFinished(QNetworkReply *) * Enhanced download progress indication to also include parsing which can take even more time than download! * Provide means to import local XML map file * Prevent trying to import/download more than one map at a time Renamed: * (void) XMLimport::readAreaNames() ==> XMLimport::readArea() - for consistency with related functions Commented out unused: * (void) XMLimport::readUnknownRoomElement() Note the movement of the map file download code to the TMap class does require making the latter a class with the Q_OBJECT macro (which removes the need for Q_DECLARE_TR_FUNCTIONS as a side-effect!) - though as another side-effect the TMap header needed a boost name specifier added to one identifier as that identifier ("property") exists in both boost and QObject classes!!! YOU MAY NEED TO RUN QMAKE ON THE PROJECT IF THE BUILD SYSTEM DOES NOT PICK UP THE ADDITION OF "Q_OBJECT" TO TMAP CLASS. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: Include missing #include, remove unused return value The absence of this was causing build errors on the Travis C.I. platform! Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: move TMap.h to mudlet_MOC_HDRS to fix CMake build issue As we have made TMap inherit from QOject - to have signal/slot functionality that class needs to be run through Qt's MOC - and to do that with the CMake project/build system it needs to be included in the files included in the projects *_MOC_HDRS {and removed from the *_HDRS} variable. Also spotted a trivial error in that specifying a const return value from method is ineffective and pointless - so removed it from: TMap::retrieveMapFileStats(QString,QString *,int *,int *,int *,int *) Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: clean up TMap initialisation/clearing actions Now restores the customEnvColors set up on initialisation but that was cleared when the map replaced with another one that is loaded {which subsequently replaces that element anyway} or imported {which merely writes over it, replacing any matching keys}. Initialises elements that when inspected on the entry to the constructor proper previously were not being set to a consistent value {booleans/ints/floats}. NOTE: This will now clear the map user data member when the map is cleared if the date is required to be saved when one map is loaded OR IMPORTED over an existing one then the data will need to be saved outside of the map - as is already need for areas and rooms user data! Also comment out or remove unused members/methods: * (void) TMap::getConnectedNodesGreaterThanX(int, int) * (void) TMap::getConnectedNodesSmallerThanX(int, int) * (void) TMap::getConnectedNodesGreaterThanY(int, int) * (void) TMap::getConnectedNodesSmallerThanY(int, int) * (void) TMap::astBreitenAnpassung(int, int) * (void) TMap::astHoehenAnpassung(int, int) * (void) TMap::exportMapToDatabase() * (void) TMap::importMapFromDatabase() * (QVector3D) TMap::span * (int) TMap::mViewArea * (QMap<QString, int>) TMap::pixNameTable * (QMap<int, QPixmap>) TMap::pixTable * (bool) TMap::isToDisplayAuditErrorsToConsole Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * ImplimentationFixes: activate a valid optimisation & remove redundant code Adding a true as a non-default 3rd argument to TRoomDB::addRoom(...) call in XMLimport::readRoom(...) enables a significant optimisation (skips a computationally expensive step when ADDING a room to new map) which dramatically reduces the time to parse an XML map file. It also pointed to the fact that the TRoomDB::entranceMap was already correctly being handled and didn't need to be regenerated in XMLimport::readRoom(...) so the code that was added in a previous commit was redundant and could be removed. A code error in TMap::slot_setDownloadProgress(...) that caused an issue that a reviewer found on test has been fixed - the total download filesize that was being sent by the Qt system signal that is connected to this slot was a -1 value (as IS DOCUMENTED) when the Qt system does NOT know the size of a QNetworkReply in advance of reaching the end of the download was incorrectly handled in a previous commit in this change set. Also found during testing that there is no need for an error message for the QNetworkReply::OperationCanceledError case in TMap::slot_replayFinished(...) as it is already handled in the TMap::slot_downloadCancel() slot. Changed the text put up onto the progress widget during the XML room parsing to be a room count - which is likely more useful and to only do it for every hundredth room - which reduces any delay "wasted" in writing to the display - combined, the effects seem satisfactory IMHO. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: provide error messages for TLuaInterpreter::loadMap(...) Errors for the XML map file importing process as initiated from the Lua command should be returned to that command rather than plastered onto the main profile console - this commit attempts to perform that effect. In testing found that there was no error handling for failure to find or open the nominated file so messages for that have been added as well. Due to the previous program logic the action of creating a mapper widget using the main toolbar button automatically loaded the "default" (the newest Mudlet Map file format file from the currently active profile's map sub-directory). Under some previous situations it looked as though a map might be loaded twice as mudlet::slot_mapper() was called both directly and via signal/slot action. These were resolved by turning that slot into a wrapper that now calls the body of code formerly within to a new method mudlet::createMapper( bool isToLoadDefaultMapFile = true ) with a the default value as an argument. This allows other usages of the body of code to be called directly with a suitable argument, which for the TConsole::loadMap() & TConsole::importMap() and the dlgProfilePreferences::downloadMap() cases is false as they are all do not want the "default" map! Also: * spotted a word "area" missing from an advisory text in TRoom::auditRooms(...). Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: fix minor bug, correct a spelling, undo a few capitalisations Under certain, unanticipated (error with no error message) conditions TLuaInterpreter::loadMap(...) would push both a nil and then a false value onto the stack for return {wrong} but only indicate one value {correct}. The textual matters were found during peer review. off-by: Stephen Lyons <slysven@virginmedia.com>
2016-10-13 09:18:48 +01:00
#ifndef QT_NO_OPENSSL
if (url.scheme() == QStringLiteral("https")) {
QSslConfiguration config(QSslConfiguration::defaultConfiguration());
request.setSslConfiguration(config);
Enhance: fix map downloading code, add manual XML map importing (#326) * Enhance: fix map downloading code, add manual XML map importing A recent move by I.R.E. to using SSL for their public MUD map URLs broke the ability for Mudlet to download those XML format files. This commit addresses this issue (as mentioned in, but not the original problem referred to in https://bugs.launchpad.net/mudlet/+bug/1427364) the revision to the code does now use "https://www.<MUD URL>/maps/map.xml" as a default name for the I.R.E. MUDS - however the method that initiates the download which was moved to TMap class from the dlgMapper one (see below) is now: (bool) TMap::downloadMap( const QString * remoteUrl = Q_NULLPTR, const QString * localFileName = Q_NULLPTR ) which if not supplied with any arguments behaves as before. However the remoteUrl argument may be given as a full QString including the scheme (the bit of the URL at the beginning before the ':') to override that and a second argument may be used to provide a different name to use for the local file name which if is a RELATIVE pathFileName will be resolved in relation to the profile directory. At present no use is made of this additional functionality but it may be useful for use with other MUDs if they should choose to provide XML map files with other remote locations and scripts using a different local filename. As a long-standing thing that needed doing I have finally provided a means to import a map XML file that - for instance - has already been download. It had been noted that there was no way to read those I.R.E. map files even if they had been obtained from a web browser able to correctly handle https: URLs - now both the TLuaInterpreter::loadMap() and the dlgProfilePreference "loadMap" button {NOT the IRE only "map download" one} will both handle files ending in ".xml" (not case sensitive so it'll work MacOS platforms as well!} For the loadMap case it will be necessary to change the filetype filter on the File Selection dialog to select "xml" files. During testing it became clear to me that it was possible to try and read one or more XML files via several mechanisms simultaneously with "unhelpful" consequences. As well as hitting the dlgProfilePreferences IRE "map download" multiple times, the TLuaInterpreter::loadMap() does NOT block until the map has been loaded and as the import time {running of XMLinport::readPackage(...)} is of significant duration for a large map (a debug, without optimisation, build on my 1.8GHz Quad-core took over two minutes to process the current Achaea map file) it is very possible to get conditions where the same profile will try to run XMLinport::readPackage(...) asynchronously - given that a profile only supports ONE map at a time it was necessary to fit a QMutex to prevent the part of the XMLinport class relating to XML Map files being called from different places in the map related code. This means that if a map download is started further downloads and any local map imports will fail until that first download has completed or aborted. Similarly a local import will prevent a download being started. As a side effect this cures: https://bugs.launchpad.net/mudlet/+bug/852861 - "Map download button starts another download thread if one is already going" The previous XML import code was not adding the rooms that it parsed to the relevant TArea::rooms member - although this would be picked-up and fixed by TMap::audit() later on, this would be accompanied by an error message about every single room. The code now builds up this information while parsing the rooms' details and inserts it so that this does not cause report-able problems during the TMap::audit() execution - the data gathered also allows missing areas to be spotted so that if a room claimed to belong to an area that was not included in the preceding areas' data an unnamed area is created for it. As a consequence of the long time to actually parse an XML map file I have enhanced the progress dialog that was originally used to track the map file download. It is now retained until the file is completely imported and shows more information about the process - importantly it shows during the XMLimport::readRoom(...) the room id being processed - and THAT method is the time/cpu hog so seeing something happening during the time that Mudlet otherwise appears to hang is useful feedback even if it adds a few seconds to the overall duration (may be more than a minute). This dialog is now also used during the other routes that involve reading an XML file and there is now a bit of consistence with the on-screen messages. Whilst inspecting XMLimport class I found there was some uncertain initialisation which I have tidied up. In summary: Added: * (bool) TConsole::importMap(const QString & location) * (void) TRoomDB::setAreaRooms(const int areaId, const QSet<int> & roomIds) * image file mudlet_map_download.png used as icon for download/import progress dialog * (bool) TMap::importMap(QFile & file) * (bool) TMap::readXmlMapFile(QFile & file) * (void) TMap::slot_downloadError(QNetworkReply::NetworkError error) * (void) TMap::reportStringToProgressDialog(const QString text) * (void) TMap::reportProgressToProgressDialog(const int current, const int maximum) Revised: * (int)TLuaInterpreter::loadMap( lua_State * ) * Moved XML map download code from dlgMapper class to the TMap one: + (void) dlgMapper::downloadMap() ==> (bool) TMap::downloadMap(const QString * remoteUrl, const QString * localFileName) + (void) dlgMapper::setDownloadProgress(qint64, qint64) ==> (void) TMap::slot_setDownloadProgress(qint64,qint64) + (void) dlgMapper::cancel() ==> (void) TMap::slot_downloadCancel() + (void) dlgMapper::replyFinished(QNetworkReply *) ==> (void) TMap::slot_replyFinished(QNetworkReply *) * Enhanced download progress indication to also include parsing which can take even more time than download! * Provide means to import local XML map file * Prevent trying to import/download more than one map at a time Renamed: * (void) XMLimport::readAreaNames() ==> XMLimport::readArea() - for consistency with related functions Commented out unused: * (void) XMLimport::readUnknownRoomElement() Note the movement of the map file download code to the TMap class does require making the latter a class with the Q_OBJECT macro (which removes the need for Q_DECLARE_TR_FUNCTIONS as a side-effect!) - though as another side-effect the TMap header needed a boost name specifier added to one identifier as that identifier ("property") exists in both boost and QObject classes!!! YOU MAY NEED TO RUN QMAKE ON THE PROJECT IF THE BUILD SYSTEM DOES NOT PICK UP THE ADDITION OF "Q_OBJECT" TO TMAP CLASS. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: Include missing #include, remove unused return value The absence of this was causing build errors on the Travis C.I. platform! Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: move TMap.h to mudlet_MOC_HDRS to fix CMake build issue As we have made TMap inherit from QOject - to have signal/slot functionality that class needs to be run through Qt's MOC - and to do that with the CMake project/build system it needs to be included in the files included in the projects *_MOC_HDRS {and removed from the *_HDRS} variable. Also spotted a trivial error in that specifying a const return value from method is ineffective and pointless - so removed it from: TMap::retrieveMapFileStats(QString,QString *,int *,int *,int *,int *) Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: clean up TMap initialisation/clearing actions Now restores the customEnvColors set up on initialisation but that was cleared when the map replaced with another one that is loaded {which subsequently replaces that element anyway} or imported {which merely writes over it, replacing any matching keys}. Initialises elements that when inspected on the entry to the constructor proper previously were not being set to a consistent value {booleans/ints/floats}. NOTE: This will now clear the map user data member when the map is cleared if the date is required to be saved when one map is loaded OR IMPORTED over an existing one then the data will need to be saved outside of the map - as is already need for areas and rooms user data! Also comment out or remove unused members/methods: * (void) TMap::getConnectedNodesGreaterThanX(int, int) * (void) TMap::getConnectedNodesSmallerThanX(int, int) * (void) TMap::getConnectedNodesGreaterThanY(int, int) * (void) TMap::getConnectedNodesSmallerThanY(int, int) * (void) TMap::astBreitenAnpassung(int, int) * (void) TMap::astHoehenAnpassung(int, int) * (void) TMap::exportMapToDatabase() * (void) TMap::importMapFromDatabase() * (QVector3D) TMap::span * (int) TMap::mViewArea * (QMap<QString, int>) TMap::pixNameTable * (QMap<int, QPixmap>) TMap::pixTable * (bool) TMap::isToDisplayAuditErrorsToConsole Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * ImplimentationFixes: activate a valid optimisation & remove redundant code Adding a true as a non-default 3rd argument to TRoomDB::addRoom(...) call in XMLimport::readRoom(...) enables a significant optimisation (skips a computationally expensive step when ADDING a room to new map) which dramatically reduces the time to parse an XML map file. It also pointed to the fact that the TRoomDB::entranceMap was already correctly being handled and didn't need to be regenerated in XMLimport::readRoom(...) so the code that was added in a previous commit was redundant and could be removed. A code error in TMap::slot_setDownloadProgress(...) that caused an issue that a reviewer found on test has been fixed - the total download filesize that was being sent by the Qt system signal that is connected to this slot was a -1 value (as IS DOCUMENTED) when the Qt system does NOT know the size of a QNetworkReply in advance of reaching the end of the download was incorrectly handled in a previous commit in this change set. Also found during testing that there is no need for an error message for the QNetworkReply::OperationCanceledError case in TMap::slot_replayFinished(...) as it is already handled in the TMap::slot_downloadCancel() slot. Changed the text put up onto the progress widget during the XML room parsing to be a room count - which is likely more useful and to only do it for every hundredth room - which reduces any delay "wasted" in writing to the display - combined, the effects seem satisfactory IMHO. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: provide error messages for TLuaInterpreter::loadMap(...) Errors for the XML map file importing process as initiated from the Lua command should be returned to that command rather than plastered onto the main profile console - this commit attempts to perform that effect. In testing found that there was no error handling for failure to find or open the nominated file so messages for that have been added as well. Due to the previous program logic the action of creating a mapper widget using the main toolbar button automatically loaded the "default" (the newest Mudlet Map file format file from the currently active profile's map sub-directory). Under some previous situations it looked as though a map might be loaded twice as mudlet::slot_mapper() was called both directly and via signal/slot action. These were resolved by turning that slot into a wrapper that now calls the body of code formerly within to a new method mudlet::createMapper( bool isToLoadDefaultMapFile = true ) with a the default value as an argument. This allows other usages of the body of code to be called directly with a suitable argument, which for the TConsole::loadMap() & TConsole::importMap() and the dlgProfilePreferences::downloadMap() cases is false as they are all do not want the "default" map! Also: * spotted a word "area" missing from an advisory text in TRoom::auditRooms(...). Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: fix minor bug, correct a spelling, undo a few capitalisations Under certain, unanticipated (error with no error message) conditions TLuaInterpreter::loadMap(...) would push both a nil and then a false value onto the stack for return {wrong} but only indicate one value {correct}. The textual matters were found during peer review. off-by: Stephen Lyons <slysven@virginmedia.com>
2016-10-13 09:18:48 +01:00
}
#endif
// Unfortunately we do not seem to get a file size from the IRE servers so
// estimate it from current figures + 10% as of now (2016/10) - using previous
// 4M that was used before for other cases:
mExpectedFileSize = 4000000;
if (url.toString().contains(QStringLiteral("achaea.com"), Qt::CaseInsensitive)) {
mExpectedFileSize = qRound(1.1f * 4706442);
} else if (url.toString().contains(QStringLiteral("aetolia.com"), Qt::CaseInsensitive)) {
mExpectedFileSize = qRound(1.1f * 5695407);
} else if (url.toString().contains(QStringLiteral("imperian.com"), Qt::CaseInsensitive)) {
mExpectedFileSize = qRound(1.1f * 4997166);
} else if (url.toString().contains(QStringLiteral("lusternia.com"), Qt::CaseInsensitive)) {
mExpectedFileSize = qRound(1.1f * 4842063);
}
QString infoMsg = tr("[ INFO ] - Map download initiated, please wait...");
postMessage(infoMsg);
Enhance: fix map downloading code, add manual XML map importing (#326) * Enhance: fix map downloading code, add manual XML map importing A recent move by I.R.E. to using SSL for their public MUD map URLs broke the ability for Mudlet to download those XML format files. This commit addresses this issue (as mentioned in, but not the original problem referred to in https://bugs.launchpad.net/mudlet/+bug/1427364) the revision to the code does now use "https://www.<MUD URL>/maps/map.xml" as a default name for the I.R.E. MUDS - however the method that initiates the download which was moved to TMap class from the dlgMapper one (see below) is now: (bool) TMap::downloadMap( const QString * remoteUrl = Q_NULLPTR, const QString * localFileName = Q_NULLPTR ) which if not supplied with any arguments behaves as before. However the remoteUrl argument may be given as a full QString including the scheme (the bit of the URL at the beginning before the ':') to override that and a second argument may be used to provide a different name to use for the local file name which if is a RELATIVE pathFileName will be resolved in relation to the profile directory. At present no use is made of this additional functionality but it may be useful for use with other MUDs if they should choose to provide XML map files with other remote locations and scripts using a different local filename. As a long-standing thing that needed doing I have finally provided a means to import a map XML file that - for instance - has already been download. It had been noted that there was no way to read those I.R.E. map files even if they had been obtained from a web browser able to correctly handle https: URLs - now both the TLuaInterpreter::loadMap() and the dlgProfilePreference "loadMap" button {NOT the IRE only "map download" one} will both handle files ending in ".xml" (not case sensitive so it'll work MacOS platforms as well!} For the loadMap case it will be necessary to change the filetype filter on the File Selection dialog to select "xml" files. During testing it became clear to me that it was possible to try and read one or more XML files via several mechanisms simultaneously with "unhelpful" consequences. As well as hitting the dlgProfilePreferences IRE "map download" multiple times, the TLuaInterpreter::loadMap() does NOT block until the map has been loaded and as the import time {running of XMLinport::readPackage(...)} is of significant duration for a large map (a debug, without optimisation, build on my 1.8GHz Quad-core took over two minutes to process the current Achaea map file) it is very possible to get conditions where the same profile will try to run XMLinport::readPackage(...) asynchronously - given that a profile only supports ONE map at a time it was necessary to fit a QMutex to prevent the part of the XMLinport class relating to XML Map files being called from different places in the map related code. This means that if a map download is started further downloads and any local map imports will fail until that first download has completed or aborted. Similarly a local import will prevent a download being started. As a side effect this cures: https://bugs.launchpad.net/mudlet/+bug/852861 - "Map download button starts another download thread if one is already going" The previous XML import code was not adding the rooms that it parsed to the relevant TArea::rooms member - although this would be picked-up and fixed by TMap::audit() later on, this would be accompanied by an error message about every single room. The code now builds up this information while parsing the rooms' details and inserts it so that this does not cause report-able problems during the TMap::audit() execution - the data gathered also allows missing areas to be spotted so that if a room claimed to belong to an area that was not included in the preceding areas' data an unnamed area is created for it. As a consequence of the long time to actually parse an XML map file I have enhanced the progress dialog that was originally used to track the map file download. It is now retained until the file is completely imported and shows more information about the process - importantly it shows during the XMLimport::readRoom(...) the room id being processed - and THAT method is the time/cpu hog so seeing something happening during the time that Mudlet otherwise appears to hang is useful feedback even if it adds a few seconds to the overall duration (may be more than a minute). This dialog is now also used during the other routes that involve reading an XML file and there is now a bit of consistence with the on-screen messages. Whilst inspecting XMLimport class I found there was some uncertain initialisation which I have tidied up. In summary: Added: * (bool) TConsole::importMap(const QString & location) * (void) TRoomDB::setAreaRooms(const int areaId, const QSet<int> & roomIds) * image file mudlet_map_download.png used as icon for download/import progress dialog * (bool) TMap::importMap(QFile & file) * (bool) TMap::readXmlMapFile(QFile & file) * (void) TMap::slot_downloadError(QNetworkReply::NetworkError error) * (void) TMap::reportStringToProgressDialog(const QString text) * (void) TMap::reportProgressToProgressDialog(const int current, const int maximum) Revised: * (int)TLuaInterpreter::loadMap( lua_State * ) * Moved XML map download code from dlgMapper class to the TMap one: + (void) dlgMapper::downloadMap() ==> (bool) TMap::downloadMap(const QString * remoteUrl, const QString * localFileName) + (void) dlgMapper::setDownloadProgress(qint64, qint64) ==> (void) TMap::slot_setDownloadProgress(qint64,qint64) + (void) dlgMapper::cancel() ==> (void) TMap::slot_downloadCancel() + (void) dlgMapper::replyFinished(QNetworkReply *) ==> (void) TMap::slot_replyFinished(QNetworkReply *) * Enhanced download progress indication to also include parsing which can take even more time than download! * Provide means to import local XML map file * Prevent trying to import/download more than one map at a time Renamed: * (void) XMLimport::readAreaNames() ==> XMLimport::readArea() - for consistency with related functions Commented out unused: * (void) XMLimport::readUnknownRoomElement() Note the movement of the map file download code to the TMap class does require making the latter a class with the Q_OBJECT macro (which removes the need for Q_DECLARE_TR_FUNCTIONS as a side-effect!) - though as another side-effect the TMap header needed a boost name specifier added to one identifier as that identifier ("property") exists in both boost and QObject classes!!! YOU MAY NEED TO RUN QMAKE ON THE PROJECT IF THE BUILD SYSTEM DOES NOT PICK UP THE ADDITION OF "Q_OBJECT" TO TMAP CLASS. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: Include missing #include, remove unused return value The absence of this was causing build errors on the Travis C.I. platform! Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: move TMap.h to mudlet_MOC_HDRS to fix CMake build issue As we have made TMap inherit from QOject - to have signal/slot functionality that class needs to be run through Qt's MOC - and to do that with the CMake project/build system it needs to be included in the files included in the projects *_MOC_HDRS {and removed from the *_HDRS} variable. Also spotted a trivial error in that specifying a const return value from method is ineffective and pointless - so removed it from: TMap::retrieveMapFileStats(QString,QString *,int *,int *,int *,int *) Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: clean up TMap initialisation/clearing actions Now restores the customEnvColors set up on initialisation but that was cleared when the map replaced with another one that is loaded {which subsequently replaces that element anyway} or imported {which merely writes over it, replacing any matching keys}. Initialises elements that when inspected on the entry to the constructor proper previously were not being set to a consistent value {booleans/ints/floats}. NOTE: This will now clear the map user data member when the map is cleared if the date is required to be saved when one map is loaded OR IMPORTED over an existing one then the data will need to be saved outside of the map - as is already need for areas and rooms user data! Also comment out or remove unused members/methods: * (void) TMap::getConnectedNodesGreaterThanX(int, int) * (void) TMap::getConnectedNodesSmallerThanX(int, int) * (void) TMap::getConnectedNodesGreaterThanY(int, int) * (void) TMap::getConnectedNodesSmallerThanY(int, int) * (void) TMap::astBreitenAnpassung(int, int) * (void) TMap::astHoehenAnpassung(int, int) * (void) TMap::exportMapToDatabase() * (void) TMap::importMapFromDatabase() * (QVector3D) TMap::span * (int) TMap::mViewArea * (QMap<QString, int>) TMap::pixNameTable * (QMap<int, QPixmap>) TMap::pixTable * (bool) TMap::isToDisplayAuditErrorsToConsole Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * ImplimentationFixes: activate a valid optimisation & remove redundant code Adding a true as a non-default 3rd argument to TRoomDB::addRoom(...) call in XMLimport::readRoom(...) enables a significant optimisation (skips a computationally expensive step when ADDING a room to new map) which dramatically reduces the time to parse an XML map file. It also pointed to the fact that the TRoomDB::entranceMap was already correctly being handled and didn't need to be regenerated in XMLimport::readRoom(...) so the code that was added in a previous commit was redundant and could be removed. A code error in TMap::slot_setDownloadProgress(...) that caused an issue that a reviewer found on test has been fixed - the total download filesize that was being sent by the Qt system signal that is connected to this slot was a -1 value (as IS DOCUMENTED) when the Qt system does NOT know the size of a QNetworkReply in advance of reaching the end of the download was incorrectly handled in a previous commit in this change set. Also found during testing that there is no need for an error message for the QNetworkReply::OperationCanceledError case in TMap::slot_replayFinished(...) as it is already handled in the TMap::slot_downloadCancel() slot. Changed the text put up onto the progress widget during the XML room parsing to be a room count - which is likely more useful and to only do it for every hundredth room - which reduces any delay "wasted" in writing to the display - combined, the effects seem satisfactory IMHO. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: provide error messages for TLuaInterpreter::loadMap(...) Errors for the XML map file importing process as initiated from the Lua command should be returned to that command rather than plastered onto the main profile console - this commit attempts to perform that effect. In testing found that there was no error handling for failure to find or open the nominated file so messages for that have been added as well. Due to the previous program logic the action of creating a mapper widget using the main toolbar button automatically loaded the "default" (the newest Mudlet Map file format file from the currently active profile's map sub-directory). Under some previous situations it looked as though a map might be loaded twice as mudlet::slot_mapper() was called both directly and via signal/slot action. These were resolved by turning that slot into a wrapper that now calls the body of code formerly within to a new method mudlet::createMapper( bool isToLoadDefaultMapFile = true ) with a the default value as an argument. This allows other usages of the body of code to be called directly with a suitable argument, which for the TConsole::loadMap() & TConsole::importMap() and the dlgProfilePreferences::downloadMap() cases is false as they are all do not want the "default" map! Also: * spotted a word "area" missing from an advisory text in TRoom::auditRooms(...). Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: fix minor bug, correct a spelling, undo a few capitalisations Under certain, unanticipated (error with no error message) conditions TLuaInterpreter::loadMap(...) would push both a nil and then a false value onto the stack for return {wrong} but only indicate one value {correct}. The textual matters were found during peer review. off-by: Stephen Lyons <slysven@virginmedia.com>
2016-10-13 09:18:48 +01:00
qApp->processEvents();
// Attempts to ensure INFO message gets shown before download is initiated!
mpNetworkReply = mpNetworkAccessManager->get(QNetworkRequest(QUrl(url)));
Enhance: fix map downloading code, add manual XML map importing (#326) * Enhance: fix map downloading code, add manual XML map importing A recent move by I.R.E. to using SSL for their public MUD map URLs broke the ability for Mudlet to download those XML format files. This commit addresses this issue (as mentioned in, but not the original problem referred to in https://bugs.launchpad.net/mudlet/+bug/1427364) the revision to the code does now use "https://www.<MUD URL>/maps/map.xml" as a default name for the I.R.E. MUDS - however the method that initiates the download which was moved to TMap class from the dlgMapper one (see below) is now: (bool) TMap::downloadMap( const QString * remoteUrl = Q_NULLPTR, const QString * localFileName = Q_NULLPTR ) which if not supplied with any arguments behaves as before. However the remoteUrl argument may be given as a full QString including the scheme (the bit of the URL at the beginning before the ':') to override that and a second argument may be used to provide a different name to use for the local file name which if is a RELATIVE pathFileName will be resolved in relation to the profile directory. At present no use is made of this additional functionality but it may be useful for use with other MUDs if they should choose to provide XML map files with other remote locations and scripts using a different local filename. As a long-standing thing that needed doing I have finally provided a means to import a map XML file that - for instance - has already been download. It had been noted that there was no way to read those I.R.E. map files even if they had been obtained from a web browser able to correctly handle https: URLs - now both the TLuaInterpreter::loadMap() and the dlgProfilePreference "loadMap" button {NOT the IRE only "map download" one} will both handle files ending in ".xml" (not case sensitive so it'll work MacOS platforms as well!} For the loadMap case it will be necessary to change the filetype filter on the File Selection dialog to select "xml" files. During testing it became clear to me that it was possible to try and read one or more XML files via several mechanisms simultaneously with "unhelpful" consequences. As well as hitting the dlgProfilePreferences IRE "map download" multiple times, the TLuaInterpreter::loadMap() does NOT block until the map has been loaded and as the import time {running of XMLinport::readPackage(...)} is of significant duration for a large map (a debug, without optimisation, build on my 1.8GHz Quad-core took over two minutes to process the current Achaea map file) it is very possible to get conditions where the same profile will try to run XMLinport::readPackage(...) asynchronously - given that a profile only supports ONE map at a time it was necessary to fit a QMutex to prevent the part of the XMLinport class relating to XML Map files being called from different places in the map related code. This means that if a map download is started further downloads and any local map imports will fail until that first download has completed or aborted. Similarly a local import will prevent a download being started. As a side effect this cures: https://bugs.launchpad.net/mudlet/+bug/852861 - "Map download button starts another download thread if one is already going" The previous XML import code was not adding the rooms that it parsed to the relevant TArea::rooms member - although this would be picked-up and fixed by TMap::audit() later on, this would be accompanied by an error message about every single room. The code now builds up this information while parsing the rooms' details and inserts it so that this does not cause report-able problems during the TMap::audit() execution - the data gathered also allows missing areas to be spotted so that if a room claimed to belong to an area that was not included in the preceding areas' data an unnamed area is created for it. As a consequence of the long time to actually parse an XML map file I have enhanced the progress dialog that was originally used to track the map file download. It is now retained until the file is completely imported and shows more information about the process - importantly it shows during the XMLimport::readRoom(...) the room id being processed - and THAT method is the time/cpu hog so seeing something happening during the time that Mudlet otherwise appears to hang is useful feedback even if it adds a few seconds to the overall duration (may be more than a minute). This dialog is now also used during the other routes that involve reading an XML file and there is now a bit of consistence with the on-screen messages. Whilst inspecting XMLimport class I found there was some uncertain initialisation which I have tidied up. In summary: Added: * (bool) TConsole::importMap(const QString & location) * (void) TRoomDB::setAreaRooms(const int areaId, const QSet<int> & roomIds) * image file mudlet_map_download.png used as icon for download/import progress dialog * (bool) TMap::importMap(QFile & file) * (bool) TMap::readXmlMapFile(QFile & file) * (void) TMap::slot_downloadError(QNetworkReply::NetworkError error) * (void) TMap::reportStringToProgressDialog(const QString text) * (void) TMap::reportProgressToProgressDialog(const int current, const int maximum) Revised: * (int)TLuaInterpreter::loadMap( lua_State * ) * Moved XML map download code from dlgMapper class to the TMap one: + (void) dlgMapper::downloadMap() ==> (bool) TMap::downloadMap(const QString * remoteUrl, const QString * localFileName) + (void) dlgMapper::setDownloadProgress(qint64, qint64) ==> (void) TMap::slot_setDownloadProgress(qint64,qint64) + (void) dlgMapper::cancel() ==> (void) TMap::slot_downloadCancel() + (void) dlgMapper::replyFinished(QNetworkReply *) ==> (void) TMap::slot_replyFinished(QNetworkReply *) * Enhanced download progress indication to also include parsing which can take even more time than download! * Provide means to import local XML map file * Prevent trying to import/download more than one map at a time Renamed: * (void) XMLimport::readAreaNames() ==> XMLimport::readArea() - for consistency with related functions Commented out unused: * (void) XMLimport::readUnknownRoomElement() Note the movement of the map file download code to the TMap class does require making the latter a class with the Q_OBJECT macro (which removes the need for Q_DECLARE_TR_FUNCTIONS as a side-effect!) - though as another side-effect the TMap header needed a boost name specifier added to one identifier as that identifier ("property") exists in both boost and QObject classes!!! YOU MAY NEED TO RUN QMAKE ON THE PROJECT IF THE BUILD SYSTEM DOES NOT PICK UP THE ADDITION OF "Q_OBJECT" TO TMAP CLASS. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: Include missing #include, remove unused return value The absence of this was causing build errors on the Travis C.I. platform! Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: move TMap.h to mudlet_MOC_HDRS to fix CMake build issue As we have made TMap inherit from QOject - to have signal/slot functionality that class needs to be run through Qt's MOC - and to do that with the CMake project/build system it needs to be included in the files included in the projects *_MOC_HDRS {and removed from the *_HDRS} variable. Also spotted a trivial error in that specifying a const return value from method is ineffective and pointless - so removed it from: TMap::retrieveMapFileStats(QString,QString *,int *,int *,int *,int *) Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: clean up TMap initialisation/clearing actions Now restores the customEnvColors set up on initialisation but that was cleared when the map replaced with another one that is loaded {which subsequently replaces that element anyway} or imported {which merely writes over it, replacing any matching keys}. Initialises elements that when inspected on the entry to the constructor proper previously were not being set to a consistent value {booleans/ints/floats}. NOTE: This will now clear the map user data member when the map is cleared if the date is required to be saved when one map is loaded OR IMPORTED over an existing one then the data will need to be saved outside of the map - as is already need for areas and rooms user data! Also comment out or remove unused members/methods: * (void) TMap::getConnectedNodesGreaterThanX(int, int) * (void) TMap::getConnectedNodesSmallerThanX(int, int) * (void) TMap::getConnectedNodesGreaterThanY(int, int) * (void) TMap::getConnectedNodesSmallerThanY(int, int) * (void) TMap::astBreitenAnpassung(int, int) * (void) TMap::astHoehenAnpassung(int, int) * (void) TMap::exportMapToDatabase() * (void) TMap::importMapFromDatabase() * (QVector3D) TMap::span * (int) TMap::mViewArea * (QMap<QString, int>) TMap::pixNameTable * (QMap<int, QPixmap>) TMap::pixTable * (bool) TMap::isToDisplayAuditErrorsToConsole Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * ImplimentationFixes: activate a valid optimisation & remove redundant code Adding a true as a non-default 3rd argument to TRoomDB::addRoom(...) call in XMLimport::readRoom(...) enables a significant optimisation (skips a computationally expensive step when ADDING a room to new map) which dramatically reduces the time to parse an XML map file. It also pointed to the fact that the TRoomDB::entranceMap was already correctly being handled and didn't need to be regenerated in XMLimport::readRoom(...) so the code that was added in a previous commit was redundant and could be removed. A code error in TMap::slot_setDownloadProgress(...) that caused an issue that a reviewer found on test has been fixed - the total download filesize that was being sent by the Qt system signal that is connected to this slot was a -1 value (as IS DOCUMENTED) when the Qt system does NOT know the size of a QNetworkReply in advance of reaching the end of the download was incorrectly handled in a previous commit in this change set. Also found during testing that there is no need for an error message for the QNetworkReply::OperationCanceledError case in TMap::slot_replayFinished(...) as it is already handled in the TMap::slot_downloadCancel() slot. Changed the text put up onto the progress widget during the XML room parsing to be a room count - which is likely more useful and to only do it for every hundredth room - which reduces any delay "wasted" in writing to the display - combined, the effects seem satisfactory IMHO. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: provide error messages for TLuaInterpreter::loadMap(...) Errors for the XML map file importing process as initiated from the Lua command should be returned to that command rather than plastered onto the main profile console - this commit attempts to perform that effect. In testing found that there was no error handling for failure to find or open the nominated file so messages for that have been added as well. Due to the previous program logic the action of creating a mapper widget using the main toolbar button automatically loaded the "default" (the newest Mudlet Map file format file from the currently active profile's map sub-directory). Under some previous situations it looked as though a map might be loaded twice as mudlet::slot_mapper() was called both directly and via signal/slot action. These were resolved by turning that slot into a wrapper that now calls the body of code formerly within to a new method mudlet::createMapper( bool isToLoadDefaultMapFile = true ) with a the default value as an argument. This allows other usages of the body of code to be called directly with a suitable argument, which for the TConsole::loadMap() & TConsole::importMap() and the dlgProfilePreferences::downloadMap() cases is false as they are all do not want the "default" map! Also: * spotted a word "area" missing from an advisory text in TRoom::auditRooms(...). Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: fix minor bug, correct a spelling, undo a few capitalisations Under certain, unanticipated (error with no error message) conditions TLuaInterpreter::loadMap(...) would push both a nil and then a false value onto the stack for return {wrong} but only indicate one value {correct}. The textual matters were found during peer review. off-by: Stephen Lyons <slysven@virginmedia.com>
2016-10-13 09:18:48 +01:00
// Using zero for both min and max values should cause the bar to oscillate
// until the first update
mpProgressDialog = new QProgressDialog(tr("Downloading XML map file for use in %1...").arg(pHost->getName()), tr("Abort"), 0, 0);
mpProgressDialog->setWindowTitle(tr("Map download"));
mpProgressDialog->setWindowIcon(QIcon(QStringLiteral(":/icons/mudlet_map_download.png")));
mpProgressDialog->setMinimumWidth(300);
mpProgressDialog->setAutoClose(false);
mpProgressDialog->setAutoReset(false);
mpProgressDialog->setMinimumDuration(0); // Normally waits for 4 seconds before showing
connect(mpNetworkReply, &QNetworkReply::downloadProgress, this, &TMap::slot_setDownloadProgress);
// Not used: connect(mpNetworkReply, SIGNAL( readyRead() ), this, SLOT( slot_readyRead() ) );
connect(mpNetworkReply, qOverload<QNetworkReply::NetworkError>(&QNetworkReply::error), this, &TMap::slot_downloadError);
// Not used: connect(mpNetworkReply, SIGNAL( sslErrors( QList<QSslError> ) ), this, SLOT( slot_sslErrors( QList<QSslError> ) ) );
connect(mpProgressDialog, &QProgressDialog::canceled, this, &TMap::slot_downloadCancel);
Enhance: fix map downloading code, add manual XML map importing (#326) * Enhance: fix map downloading code, add manual XML map importing A recent move by I.R.E. to using SSL for their public MUD map URLs broke the ability for Mudlet to download those XML format files. This commit addresses this issue (as mentioned in, but not the original problem referred to in https://bugs.launchpad.net/mudlet/+bug/1427364) the revision to the code does now use "https://www.<MUD URL>/maps/map.xml" as a default name for the I.R.E. MUDS - however the method that initiates the download which was moved to TMap class from the dlgMapper one (see below) is now: (bool) TMap::downloadMap( const QString * remoteUrl = Q_NULLPTR, const QString * localFileName = Q_NULLPTR ) which if not supplied with any arguments behaves as before. However the remoteUrl argument may be given as a full QString including the scheme (the bit of the URL at the beginning before the ':') to override that and a second argument may be used to provide a different name to use for the local file name which if is a RELATIVE pathFileName will be resolved in relation to the profile directory. At present no use is made of this additional functionality but it may be useful for use with other MUDs if they should choose to provide XML map files with other remote locations and scripts using a different local filename. As a long-standing thing that needed doing I have finally provided a means to import a map XML file that - for instance - has already been download. It had been noted that there was no way to read those I.R.E. map files even if they had been obtained from a web browser able to correctly handle https: URLs - now both the TLuaInterpreter::loadMap() and the dlgProfilePreference "loadMap" button {NOT the IRE only "map download" one} will both handle files ending in ".xml" (not case sensitive so it'll work MacOS platforms as well!} For the loadMap case it will be necessary to change the filetype filter on the File Selection dialog to select "xml" files. During testing it became clear to me that it was possible to try and read one or more XML files via several mechanisms simultaneously with "unhelpful" consequences. As well as hitting the dlgProfilePreferences IRE "map download" multiple times, the TLuaInterpreter::loadMap() does NOT block until the map has been loaded and as the import time {running of XMLinport::readPackage(...)} is of significant duration for a large map (a debug, without optimisation, build on my 1.8GHz Quad-core took over two minutes to process the current Achaea map file) it is very possible to get conditions where the same profile will try to run XMLinport::readPackage(...) asynchronously - given that a profile only supports ONE map at a time it was necessary to fit a QMutex to prevent the part of the XMLinport class relating to XML Map files being called from different places in the map related code. This means that if a map download is started further downloads and any local map imports will fail until that first download has completed or aborted. Similarly a local import will prevent a download being started. As a side effect this cures: https://bugs.launchpad.net/mudlet/+bug/852861 - "Map download button starts another download thread if one is already going" The previous XML import code was not adding the rooms that it parsed to the relevant TArea::rooms member - although this would be picked-up and fixed by TMap::audit() later on, this would be accompanied by an error message about every single room. The code now builds up this information while parsing the rooms' details and inserts it so that this does not cause report-able problems during the TMap::audit() execution - the data gathered also allows missing areas to be spotted so that if a room claimed to belong to an area that was not included in the preceding areas' data an unnamed area is created for it. As a consequence of the long time to actually parse an XML map file I have enhanced the progress dialog that was originally used to track the map file download. It is now retained until the file is completely imported and shows more information about the process - importantly it shows during the XMLimport::readRoom(...) the room id being processed - and THAT method is the time/cpu hog so seeing something happening during the time that Mudlet otherwise appears to hang is useful feedback even if it adds a few seconds to the overall duration (may be more than a minute). This dialog is now also used during the other routes that involve reading an XML file and there is now a bit of consistence with the on-screen messages. Whilst inspecting XMLimport class I found there was some uncertain initialisation which I have tidied up. In summary: Added: * (bool) TConsole::importMap(const QString & location) * (void) TRoomDB::setAreaRooms(const int areaId, const QSet<int> & roomIds) * image file mudlet_map_download.png used as icon for download/import progress dialog * (bool) TMap::importMap(QFile & file) * (bool) TMap::readXmlMapFile(QFile & file) * (void) TMap::slot_downloadError(QNetworkReply::NetworkError error) * (void) TMap::reportStringToProgressDialog(const QString text) * (void) TMap::reportProgressToProgressDialog(const int current, const int maximum) Revised: * (int)TLuaInterpreter::loadMap( lua_State * ) * Moved XML map download code from dlgMapper class to the TMap one: + (void) dlgMapper::downloadMap() ==> (bool) TMap::downloadMap(const QString * remoteUrl, const QString * localFileName) + (void) dlgMapper::setDownloadProgress(qint64, qint64) ==> (void) TMap::slot_setDownloadProgress(qint64,qint64) + (void) dlgMapper::cancel() ==> (void) TMap::slot_downloadCancel() + (void) dlgMapper::replyFinished(QNetworkReply *) ==> (void) TMap::slot_replyFinished(QNetworkReply *) * Enhanced download progress indication to also include parsing which can take even more time than download! * Provide means to import local XML map file * Prevent trying to import/download more than one map at a time Renamed: * (void) XMLimport::readAreaNames() ==> XMLimport::readArea() - for consistency with related functions Commented out unused: * (void) XMLimport::readUnknownRoomElement() Note the movement of the map file download code to the TMap class does require making the latter a class with the Q_OBJECT macro (which removes the need for Q_DECLARE_TR_FUNCTIONS as a side-effect!) - though as another side-effect the TMap header needed a boost name specifier added to one identifier as that identifier ("property") exists in both boost and QObject classes!!! YOU MAY NEED TO RUN QMAKE ON THE PROJECT IF THE BUILD SYSTEM DOES NOT PICK UP THE ADDITION OF "Q_OBJECT" TO TMAP CLASS. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: Include missing #include, remove unused return value The absence of this was causing build errors on the Travis C.I. platform! Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: move TMap.h to mudlet_MOC_HDRS to fix CMake build issue As we have made TMap inherit from QOject - to have signal/slot functionality that class needs to be run through Qt's MOC - and to do that with the CMake project/build system it needs to be included in the files included in the projects *_MOC_HDRS {and removed from the *_HDRS} variable. Also spotted a trivial error in that specifying a const return value from method is ineffective and pointless - so removed it from: TMap::retrieveMapFileStats(QString,QString *,int *,int *,int *,int *) Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: clean up TMap initialisation/clearing actions Now restores the customEnvColors set up on initialisation but that was cleared when the map replaced with another one that is loaded {which subsequently replaces that element anyway} or imported {which merely writes over it, replacing any matching keys}. Initialises elements that when inspected on the entry to the constructor proper previously were not being set to a consistent value {booleans/ints/floats}. NOTE: This will now clear the map user data member when the map is cleared if the date is required to be saved when one map is loaded OR IMPORTED over an existing one then the data will need to be saved outside of the map - as is already need for areas and rooms user data! Also comment out or remove unused members/methods: * (void) TMap::getConnectedNodesGreaterThanX(int, int) * (void) TMap::getConnectedNodesSmallerThanX(int, int) * (void) TMap::getConnectedNodesGreaterThanY(int, int) * (void) TMap::getConnectedNodesSmallerThanY(int, int) * (void) TMap::astBreitenAnpassung(int, int) * (void) TMap::astHoehenAnpassung(int, int) * (void) TMap::exportMapToDatabase() * (void) TMap::importMapFromDatabase() * (QVector3D) TMap::span * (int) TMap::mViewArea * (QMap<QString, int>) TMap::pixNameTable * (QMap<int, QPixmap>) TMap::pixTable * (bool) TMap::isToDisplayAuditErrorsToConsole Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * ImplimentationFixes: activate a valid optimisation & remove redundant code Adding a true as a non-default 3rd argument to TRoomDB::addRoom(...) call in XMLimport::readRoom(...) enables a significant optimisation (skips a computationally expensive step when ADDING a room to new map) which dramatically reduces the time to parse an XML map file. It also pointed to the fact that the TRoomDB::entranceMap was already correctly being handled and didn't need to be regenerated in XMLimport::readRoom(...) so the code that was added in a previous commit was redundant and could be removed. A code error in TMap::slot_setDownloadProgress(...) that caused an issue that a reviewer found on test has been fixed - the total download filesize that was being sent by the Qt system signal that is connected to this slot was a -1 value (as IS DOCUMENTED) when the Qt system does NOT know the size of a QNetworkReply in advance of reaching the end of the download was incorrectly handled in a previous commit in this change set. Also found during testing that there is no need for an error message for the QNetworkReply::OperationCanceledError case in TMap::slot_replayFinished(...) as it is already handled in the TMap::slot_downloadCancel() slot. Changed the text put up onto the progress widget during the XML room parsing to be a room count - which is likely more useful and to only do it for every hundredth room - which reduces any delay "wasted" in writing to the display - combined, the effects seem satisfactory IMHO. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: provide error messages for TLuaInterpreter::loadMap(...) Errors for the XML map file importing process as initiated from the Lua command should be returned to that command rather than plastered onto the main profile console - this commit attempts to perform that effect. In testing found that there was no error handling for failure to find or open the nominated file so messages for that have been added as well. Due to the previous program logic the action of creating a mapper widget using the main toolbar button automatically loaded the "default" (the newest Mudlet Map file format file from the currently active profile's map sub-directory). Under some previous situations it looked as though a map might be loaded twice as mudlet::slot_mapper() was called both directly and via signal/slot action. These were resolved by turning that slot into a wrapper that now calls the body of code formerly within to a new method mudlet::createMapper( bool isToLoadDefaultMapFile = true ) with a the default value as an argument. This allows other usages of the body of code to be called directly with a suitable argument, which for the TConsole::loadMap() & TConsole::importMap() and the dlgProfilePreferences::downloadMap() cases is false as they are all do not want the "default" map! Also: * spotted a word "area" missing from an advisory text in TRoom::auditRooms(...). Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: fix minor bug, correct a spelling, undo a few capitalisations Under certain, unanticipated (error with no error message) conditions TLuaInterpreter::loadMap(...) would push both a nil and then a false value onto the stack for return {wrong} but only indicate one value {correct}. The textual matters were found during peer review. off-by: Stephen Lyons <slysven@virginmedia.com>
2016-10-13 09:18:48 +01:00
mpProgressDialog->show();
}
// Called from TLuaInterpreter::loadFile() or dlgProfilePreferences's "loadMap"
// both via TConsole::importMap( QFile & ) - it is intended to prevent
// readXmlMapFile( QFile & ) from being used more than once at a time and to
// prevent the above callers from using that when a map download is in progress!
// errMsg if, non-null is for a suitable structured error message to return to
// the TLuaInterpreter::loadFile(...) usage and is also needed to suppress the
// error message to the console
bool TMap::importMap(QFile& file, QString* errMsg)
Enhance: fix map downloading code, add manual XML map importing (#326) * Enhance: fix map downloading code, add manual XML map importing A recent move by I.R.E. to using SSL for their public MUD map URLs broke the ability for Mudlet to download those XML format files. This commit addresses this issue (as mentioned in, but not the original problem referred to in https://bugs.launchpad.net/mudlet/+bug/1427364) the revision to the code does now use "https://www.<MUD URL>/maps/map.xml" as a default name for the I.R.E. MUDS - however the method that initiates the download which was moved to TMap class from the dlgMapper one (see below) is now: (bool) TMap::downloadMap( const QString * remoteUrl = Q_NULLPTR, const QString * localFileName = Q_NULLPTR ) which if not supplied with any arguments behaves as before. However the remoteUrl argument may be given as a full QString including the scheme (the bit of the URL at the beginning before the ':') to override that and a second argument may be used to provide a different name to use for the local file name which if is a RELATIVE pathFileName will be resolved in relation to the profile directory. At present no use is made of this additional functionality but it may be useful for use with other MUDs if they should choose to provide XML map files with other remote locations and scripts using a different local filename. As a long-standing thing that needed doing I have finally provided a means to import a map XML file that - for instance - has already been download. It had been noted that there was no way to read those I.R.E. map files even if they had been obtained from a web browser able to correctly handle https: URLs - now both the TLuaInterpreter::loadMap() and the dlgProfilePreference "loadMap" button {NOT the IRE only "map download" one} will both handle files ending in ".xml" (not case sensitive so it'll work MacOS platforms as well!} For the loadMap case it will be necessary to change the filetype filter on the File Selection dialog to select "xml" files. During testing it became clear to me that it was possible to try and read one or more XML files via several mechanisms simultaneously with "unhelpful" consequences. As well as hitting the dlgProfilePreferences IRE "map download" multiple times, the TLuaInterpreter::loadMap() does NOT block until the map has been loaded and as the import time {running of XMLinport::readPackage(...)} is of significant duration for a large map (a debug, without optimisation, build on my 1.8GHz Quad-core took over two minutes to process the current Achaea map file) it is very possible to get conditions where the same profile will try to run XMLinport::readPackage(...) asynchronously - given that a profile only supports ONE map at a time it was necessary to fit a QMutex to prevent the part of the XMLinport class relating to XML Map files being called from different places in the map related code. This means that if a map download is started further downloads and any local map imports will fail until that first download has completed or aborted. Similarly a local import will prevent a download being started. As a side effect this cures: https://bugs.launchpad.net/mudlet/+bug/852861 - "Map download button starts another download thread if one is already going" The previous XML import code was not adding the rooms that it parsed to the relevant TArea::rooms member - although this would be picked-up and fixed by TMap::audit() later on, this would be accompanied by an error message about every single room. The code now builds up this information while parsing the rooms' details and inserts it so that this does not cause report-able problems during the TMap::audit() execution - the data gathered also allows missing areas to be spotted so that if a room claimed to belong to an area that was not included in the preceding areas' data an unnamed area is created for it. As a consequence of the long time to actually parse an XML map file I have enhanced the progress dialog that was originally used to track the map file download. It is now retained until the file is completely imported and shows more information about the process - importantly it shows during the XMLimport::readRoom(...) the room id being processed - and THAT method is the time/cpu hog so seeing something happening during the time that Mudlet otherwise appears to hang is useful feedback even if it adds a few seconds to the overall duration (may be more than a minute). This dialog is now also used during the other routes that involve reading an XML file and there is now a bit of consistence with the on-screen messages. Whilst inspecting XMLimport class I found there was some uncertain initialisation which I have tidied up. In summary: Added: * (bool) TConsole::importMap(const QString & location) * (void) TRoomDB::setAreaRooms(const int areaId, const QSet<int> & roomIds) * image file mudlet_map_download.png used as icon for download/import progress dialog * (bool) TMap::importMap(QFile & file) * (bool) TMap::readXmlMapFile(QFile & file) * (void) TMap::slot_downloadError(QNetworkReply::NetworkError error) * (void) TMap::reportStringToProgressDialog(const QString text) * (void) TMap::reportProgressToProgressDialog(const int current, const int maximum) Revised: * (int)TLuaInterpreter::loadMap( lua_State * ) * Moved XML map download code from dlgMapper class to the TMap one: + (void) dlgMapper::downloadMap() ==> (bool) TMap::downloadMap(const QString * remoteUrl, const QString * localFileName) + (void) dlgMapper::setDownloadProgress(qint64, qint64) ==> (void) TMap::slot_setDownloadProgress(qint64,qint64) + (void) dlgMapper::cancel() ==> (void) TMap::slot_downloadCancel() + (void) dlgMapper::replyFinished(QNetworkReply *) ==> (void) TMap::slot_replyFinished(QNetworkReply *) * Enhanced download progress indication to also include parsing which can take even more time than download! * Provide means to import local XML map file * Prevent trying to import/download more than one map at a time Renamed: * (void) XMLimport::readAreaNames() ==> XMLimport::readArea() - for consistency with related functions Commented out unused: * (void) XMLimport::readUnknownRoomElement() Note the movement of the map file download code to the TMap class does require making the latter a class with the Q_OBJECT macro (which removes the need for Q_DECLARE_TR_FUNCTIONS as a side-effect!) - though as another side-effect the TMap header needed a boost name specifier added to one identifier as that identifier ("property") exists in both boost and QObject classes!!! YOU MAY NEED TO RUN QMAKE ON THE PROJECT IF THE BUILD SYSTEM DOES NOT PICK UP THE ADDITION OF "Q_OBJECT" TO TMAP CLASS. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: Include missing #include, remove unused return value The absence of this was causing build errors on the Travis C.I. platform! Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: move TMap.h to mudlet_MOC_HDRS to fix CMake build issue As we have made TMap inherit from QOject - to have signal/slot functionality that class needs to be run through Qt's MOC - and to do that with the CMake project/build system it needs to be included in the files included in the projects *_MOC_HDRS {and removed from the *_HDRS} variable. Also spotted a trivial error in that specifying a const return value from method is ineffective and pointless - so removed it from: TMap::retrieveMapFileStats(QString,QString *,int *,int *,int *,int *) Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: clean up TMap initialisation/clearing actions Now restores the customEnvColors set up on initialisation but that was cleared when the map replaced with another one that is loaded {which subsequently replaces that element anyway} or imported {which merely writes over it, replacing any matching keys}. Initialises elements that when inspected on the entry to the constructor proper previously were not being set to a consistent value {booleans/ints/floats}. NOTE: This will now clear the map user data member when the map is cleared if the date is required to be saved when one map is loaded OR IMPORTED over an existing one then the data will need to be saved outside of the map - as is already need for areas and rooms user data! Also comment out or remove unused members/methods: * (void) TMap::getConnectedNodesGreaterThanX(int, int) * (void) TMap::getConnectedNodesSmallerThanX(int, int) * (void) TMap::getConnectedNodesGreaterThanY(int, int) * (void) TMap::getConnectedNodesSmallerThanY(int, int) * (void) TMap::astBreitenAnpassung(int, int) * (void) TMap::astHoehenAnpassung(int, int) * (void) TMap::exportMapToDatabase() * (void) TMap::importMapFromDatabase() * (QVector3D) TMap::span * (int) TMap::mViewArea * (QMap<QString, int>) TMap::pixNameTable * (QMap<int, QPixmap>) TMap::pixTable * (bool) TMap::isToDisplayAuditErrorsToConsole Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * ImplimentationFixes: activate a valid optimisation & remove redundant code Adding a true as a non-default 3rd argument to TRoomDB::addRoom(...) call in XMLimport::readRoom(...) enables a significant optimisation (skips a computationally expensive step when ADDING a room to new map) which dramatically reduces the time to parse an XML map file. It also pointed to the fact that the TRoomDB::entranceMap was already correctly being handled and didn't need to be regenerated in XMLimport::readRoom(...) so the code that was added in a previous commit was redundant and could be removed. A code error in TMap::slot_setDownloadProgress(...) that caused an issue that a reviewer found on test has been fixed - the total download filesize that was being sent by the Qt system signal that is connected to this slot was a -1 value (as IS DOCUMENTED) when the Qt system does NOT know the size of a QNetworkReply in advance of reaching the end of the download was incorrectly handled in a previous commit in this change set. Also found during testing that there is no need for an error message for the QNetworkReply::OperationCanceledError case in TMap::slot_replayFinished(...) as it is already handled in the TMap::slot_downloadCancel() slot. Changed the text put up onto the progress widget during the XML room parsing to be a room count - which is likely more useful and to only do it for every hundredth room - which reduces any delay "wasted" in writing to the display - combined, the effects seem satisfactory IMHO. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: provide error messages for TLuaInterpreter::loadMap(...) Errors for the XML map file importing process as initiated from the Lua command should be returned to that command rather than plastered onto the main profile console - this commit attempts to perform that effect. In testing found that there was no error handling for failure to find or open the nominated file so messages for that have been added as well. Due to the previous program logic the action of creating a mapper widget using the main toolbar button automatically loaded the "default" (the newest Mudlet Map file format file from the currently active profile's map sub-directory). Under some previous situations it looked as though a map might be loaded twice as mudlet::slot_mapper() was called both directly and via signal/slot action. These were resolved by turning that slot into a wrapper that now calls the body of code formerly within to a new method mudlet::createMapper( bool isToLoadDefaultMapFile = true ) with a the default value as an argument. This allows other usages of the body of code to be called directly with a suitable argument, which for the TConsole::loadMap() & TConsole::importMap() and the dlgProfilePreferences::downloadMap() cases is false as they are all do not want the "default" map! Also: * spotted a word "area" missing from an advisory text in TRoom::auditRooms(...). Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: fix minor bug, correct a spelling, undo a few capitalisations Under certain, unanticipated (error with no error message) conditions TLuaInterpreter::loadMap(...) would push both a nil and then a false value onto the stack for return {wrong} but only indicate one value {correct}. The textual matters were found during peer review. off-by: Stephen Lyons <slysven@virginmedia.com>
2016-10-13 09:18:48 +01:00
{
if (!mXmlImportMutex.tryLock(0)) {
if (errMsg) {
*errMsg = tr("loadMap: unable to perform request, a map is already being downloaded or\n"
"imported at user request.");
} else {
QString warnMsg = QStringLiteral("[ WARN ] - Attempt made to import an XML map when one is already being\n"
"downloaded or is being imported from a local file - wait for that\n"
"operation to complete (if it cannot be canceled) before retrying!");
postMessage(warnMsg);
Enhance: fix map downloading code, add manual XML map importing (#326) * Enhance: fix map downloading code, add manual XML map importing A recent move by I.R.E. to using SSL for their public MUD map URLs broke the ability for Mudlet to download those XML format files. This commit addresses this issue (as mentioned in, but not the original problem referred to in https://bugs.launchpad.net/mudlet/+bug/1427364) the revision to the code does now use "https://www.<MUD URL>/maps/map.xml" as a default name for the I.R.E. MUDS - however the method that initiates the download which was moved to TMap class from the dlgMapper one (see below) is now: (bool) TMap::downloadMap( const QString * remoteUrl = Q_NULLPTR, const QString * localFileName = Q_NULLPTR ) which if not supplied with any arguments behaves as before. However the remoteUrl argument may be given as a full QString including the scheme (the bit of the URL at the beginning before the ':') to override that and a second argument may be used to provide a different name to use for the local file name which if is a RELATIVE pathFileName will be resolved in relation to the profile directory. At present no use is made of this additional functionality but it may be useful for use with other MUDs if they should choose to provide XML map files with other remote locations and scripts using a different local filename. As a long-standing thing that needed doing I have finally provided a means to import a map XML file that - for instance - has already been download. It had been noted that there was no way to read those I.R.E. map files even if they had been obtained from a web browser able to correctly handle https: URLs - now both the TLuaInterpreter::loadMap() and the dlgProfilePreference "loadMap" button {NOT the IRE only "map download" one} will both handle files ending in ".xml" (not case sensitive so it'll work MacOS platforms as well!} For the loadMap case it will be necessary to change the filetype filter on the File Selection dialog to select "xml" files. During testing it became clear to me that it was possible to try and read one or more XML files via several mechanisms simultaneously with "unhelpful" consequences. As well as hitting the dlgProfilePreferences IRE "map download" multiple times, the TLuaInterpreter::loadMap() does NOT block until the map has been loaded and as the import time {running of XMLinport::readPackage(...)} is of significant duration for a large map (a debug, without optimisation, build on my 1.8GHz Quad-core took over two minutes to process the current Achaea map file) it is very possible to get conditions where the same profile will try to run XMLinport::readPackage(...) asynchronously - given that a profile only supports ONE map at a time it was necessary to fit a QMutex to prevent the part of the XMLinport class relating to XML Map files being called from different places in the map related code. This means that if a map download is started further downloads and any local map imports will fail until that first download has completed or aborted. Similarly a local import will prevent a download being started. As a side effect this cures: https://bugs.launchpad.net/mudlet/+bug/852861 - "Map download button starts another download thread if one is already going" The previous XML import code was not adding the rooms that it parsed to the relevant TArea::rooms member - although this would be picked-up and fixed by TMap::audit() later on, this would be accompanied by an error message about every single room. The code now builds up this information while parsing the rooms' details and inserts it so that this does not cause report-able problems during the TMap::audit() execution - the data gathered also allows missing areas to be spotted so that if a room claimed to belong to an area that was not included in the preceding areas' data an unnamed area is created for it. As a consequence of the long time to actually parse an XML map file I have enhanced the progress dialog that was originally used to track the map file download. It is now retained until the file is completely imported and shows more information about the process - importantly it shows during the XMLimport::readRoom(...) the room id being processed - and THAT method is the time/cpu hog so seeing something happening during the time that Mudlet otherwise appears to hang is useful feedback even if it adds a few seconds to the overall duration (may be more than a minute). This dialog is now also used during the other routes that involve reading an XML file and there is now a bit of consistence with the on-screen messages. Whilst inspecting XMLimport class I found there was some uncertain initialisation which I have tidied up. In summary: Added: * (bool) TConsole::importMap(const QString & location) * (void) TRoomDB::setAreaRooms(const int areaId, const QSet<int> & roomIds) * image file mudlet_map_download.png used as icon for download/import progress dialog * (bool) TMap::importMap(QFile & file) * (bool) TMap::readXmlMapFile(QFile & file) * (void) TMap::slot_downloadError(QNetworkReply::NetworkError error) * (void) TMap::reportStringToProgressDialog(const QString text) * (void) TMap::reportProgressToProgressDialog(const int current, const int maximum) Revised: * (int)TLuaInterpreter::loadMap( lua_State * ) * Moved XML map download code from dlgMapper class to the TMap one: + (void) dlgMapper::downloadMap() ==> (bool) TMap::downloadMap(const QString * remoteUrl, const QString * localFileName) + (void) dlgMapper::setDownloadProgress(qint64, qint64) ==> (void) TMap::slot_setDownloadProgress(qint64,qint64) + (void) dlgMapper::cancel() ==> (void) TMap::slot_downloadCancel() + (void) dlgMapper::replyFinished(QNetworkReply *) ==> (void) TMap::slot_replyFinished(QNetworkReply *) * Enhanced download progress indication to also include parsing which can take even more time than download! * Provide means to import local XML map file * Prevent trying to import/download more than one map at a time Renamed: * (void) XMLimport::readAreaNames() ==> XMLimport::readArea() - for consistency with related functions Commented out unused: * (void) XMLimport::readUnknownRoomElement() Note the movement of the map file download code to the TMap class does require making the latter a class with the Q_OBJECT macro (which removes the need for Q_DECLARE_TR_FUNCTIONS as a side-effect!) - though as another side-effect the TMap header needed a boost name specifier added to one identifier as that identifier ("property") exists in both boost and QObject classes!!! YOU MAY NEED TO RUN QMAKE ON THE PROJECT IF THE BUILD SYSTEM DOES NOT PICK UP THE ADDITION OF "Q_OBJECT" TO TMAP CLASS. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: Include missing #include, remove unused return value The absence of this was causing build errors on the Travis C.I. platform! Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: move TMap.h to mudlet_MOC_HDRS to fix CMake build issue As we have made TMap inherit from QOject - to have signal/slot functionality that class needs to be run through Qt's MOC - and to do that with the CMake project/build system it needs to be included in the files included in the projects *_MOC_HDRS {and removed from the *_HDRS} variable. Also spotted a trivial error in that specifying a const return value from method is ineffective and pointless - so removed it from: TMap::retrieveMapFileStats(QString,QString *,int *,int *,int *,int *) Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: clean up TMap initialisation/clearing actions Now restores the customEnvColors set up on initialisation but that was cleared when the map replaced with another one that is loaded {which subsequently replaces that element anyway} or imported {which merely writes over it, replacing any matching keys}. Initialises elements that when inspected on the entry to the constructor proper previously were not being set to a consistent value {booleans/ints/floats}. NOTE: This will now clear the map user data member when the map is cleared if the date is required to be saved when one map is loaded OR IMPORTED over an existing one then the data will need to be saved outside of the map - as is already need for areas and rooms user data! Also comment out or remove unused members/methods: * (void) TMap::getConnectedNodesGreaterThanX(int, int) * (void) TMap::getConnectedNodesSmallerThanX(int, int) * (void) TMap::getConnectedNodesGreaterThanY(int, int) * (void) TMap::getConnectedNodesSmallerThanY(int, int) * (void) TMap::astBreitenAnpassung(int, int) * (void) TMap::astHoehenAnpassung(int, int) * (void) TMap::exportMapToDatabase() * (void) TMap::importMapFromDatabase() * (QVector3D) TMap::span * (int) TMap::mViewArea * (QMap<QString, int>) TMap::pixNameTable * (QMap<int, QPixmap>) TMap::pixTable * (bool) TMap::isToDisplayAuditErrorsToConsole Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * ImplimentationFixes: activate a valid optimisation & remove redundant code Adding a true as a non-default 3rd argument to TRoomDB::addRoom(...) call in XMLimport::readRoom(...) enables a significant optimisation (skips a computationally expensive step when ADDING a room to new map) which dramatically reduces the time to parse an XML map file. It also pointed to the fact that the TRoomDB::entranceMap was already correctly being handled and didn't need to be regenerated in XMLimport::readRoom(...) so the code that was added in a previous commit was redundant and could be removed. A code error in TMap::slot_setDownloadProgress(...) that caused an issue that a reviewer found on test has been fixed - the total download filesize that was being sent by the Qt system signal that is connected to this slot was a -1 value (as IS DOCUMENTED) when the Qt system does NOT know the size of a QNetworkReply in advance of reaching the end of the download was incorrectly handled in a previous commit in this change set. Also found during testing that there is no need for an error message for the QNetworkReply::OperationCanceledError case in TMap::slot_replayFinished(...) as it is already handled in the TMap::slot_downloadCancel() slot. Changed the text put up onto the progress widget during the XML room parsing to be a room count - which is likely more useful and to only do it for every hundredth room - which reduces any delay "wasted" in writing to the display - combined, the effects seem satisfactory IMHO. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: provide error messages for TLuaInterpreter::loadMap(...) Errors for the XML map file importing process as initiated from the Lua command should be returned to that command rather than plastered onto the main profile console - this commit attempts to perform that effect. In testing found that there was no error handling for failure to find or open the nominated file so messages for that have been added as well. Due to the previous program logic the action of creating a mapper widget using the main toolbar button automatically loaded the "default" (the newest Mudlet Map file format file from the currently active profile's map sub-directory). Under some previous situations it looked as though a map might be loaded twice as mudlet::slot_mapper() was called both directly and via signal/slot action. These were resolved by turning that slot into a wrapper that now calls the body of code formerly within to a new method mudlet::createMapper( bool isToLoadDefaultMapFile = true ) with a the default value as an argument. This allows other usages of the body of code to be called directly with a suitable argument, which for the TConsole::loadMap() & TConsole::importMap() and the dlgProfilePreferences::downloadMap() cases is false as they are all do not want the "default" map! Also: * spotted a word "area" missing from an advisory text in TRoom::auditRooms(...). Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: fix minor bug, correct a spelling, undo a few capitalisations Under certain, unanticipated (error with no error message) conditions TLuaInterpreter::loadMap(...) would push both a nil and then a false value onto the stack for return {wrong} but only indicate one value {correct}. The textual matters were found during peer review. off-by: Stephen Lyons <slysven@virginmedia.com>
2016-10-13 09:18:48 +01:00
}
return false;
}
// We have the mutex and MUST unlock it when we are done
bool result = readXmlMapFile(file, errMsg);
Enhance: fix map downloading code, add manual XML map importing (#326) * Enhance: fix map downloading code, add manual XML map importing A recent move by I.R.E. to using SSL for their public MUD map URLs broke the ability for Mudlet to download those XML format files. This commit addresses this issue (as mentioned in, but not the original problem referred to in https://bugs.launchpad.net/mudlet/+bug/1427364) the revision to the code does now use "https://www.<MUD URL>/maps/map.xml" as a default name for the I.R.E. MUDS - however the method that initiates the download which was moved to TMap class from the dlgMapper one (see below) is now: (bool) TMap::downloadMap( const QString * remoteUrl = Q_NULLPTR, const QString * localFileName = Q_NULLPTR ) which if not supplied with any arguments behaves as before. However the remoteUrl argument may be given as a full QString including the scheme (the bit of the URL at the beginning before the ':') to override that and a second argument may be used to provide a different name to use for the local file name which if is a RELATIVE pathFileName will be resolved in relation to the profile directory. At present no use is made of this additional functionality but it may be useful for use with other MUDs if they should choose to provide XML map files with other remote locations and scripts using a different local filename. As a long-standing thing that needed doing I have finally provided a means to import a map XML file that - for instance - has already been download. It had been noted that there was no way to read those I.R.E. map files even if they had been obtained from a web browser able to correctly handle https: URLs - now both the TLuaInterpreter::loadMap() and the dlgProfilePreference "loadMap" button {NOT the IRE only "map download" one} will both handle files ending in ".xml" (not case sensitive so it'll work MacOS platforms as well!} For the loadMap case it will be necessary to change the filetype filter on the File Selection dialog to select "xml" files. During testing it became clear to me that it was possible to try and read one or more XML files via several mechanisms simultaneously with "unhelpful" consequences. As well as hitting the dlgProfilePreferences IRE "map download" multiple times, the TLuaInterpreter::loadMap() does NOT block until the map has been loaded and as the import time {running of XMLinport::readPackage(...)} is of significant duration for a large map (a debug, without optimisation, build on my 1.8GHz Quad-core took over two minutes to process the current Achaea map file) it is very possible to get conditions where the same profile will try to run XMLinport::readPackage(...) asynchronously - given that a profile only supports ONE map at a time it was necessary to fit a QMutex to prevent the part of the XMLinport class relating to XML Map files being called from different places in the map related code. This means that if a map download is started further downloads and any local map imports will fail until that first download has completed or aborted. Similarly a local import will prevent a download being started. As a side effect this cures: https://bugs.launchpad.net/mudlet/+bug/852861 - "Map download button starts another download thread if one is already going" The previous XML import code was not adding the rooms that it parsed to the relevant TArea::rooms member - although this would be picked-up and fixed by TMap::audit() later on, this would be accompanied by an error message about every single room. The code now builds up this information while parsing the rooms' details and inserts it so that this does not cause report-able problems during the TMap::audit() execution - the data gathered also allows missing areas to be spotted so that if a room claimed to belong to an area that was not included in the preceding areas' data an unnamed area is created for it. As a consequence of the long time to actually parse an XML map file I have enhanced the progress dialog that was originally used to track the map file download. It is now retained until the file is completely imported and shows more information about the process - importantly it shows during the XMLimport::readRoom(...) the room id being processed - and THAT method is the time/cpu hog so seeing something happening during the time that Mudlet otherwise appears to hang is useful feedback even if it adds a few seconds to the overall duration (may be more than a minute). This dialog is now also used during the other routes that involve reading an XML file and there is now a bit of consistence with the on-screen messages. Whilst inspecting XMLimport class I found there was some uncertain initialisation which I have tidied up. In summary: Added: * (bool) TConsole::importMap(const QString & location) * (void) TRoomDB::setAreaRooms(const int areaId, const QSet<int> & roomIds) * image file mudlet_map_download.png used as icon for download/import progress dialog * (bool) TMap::importMap(QFile & file) * (bool) TMap::readXmlMapFile(QFile & file) * (void) TMap::slot_downloadError(QNetworkReply::NetworkError error) * (void) TMap::reportStringToProgressDialog(const QString text) * (void) TMap::reportProgressToProgressDialog(const int current, const int maximum) Revised: * (int)TLuaInterpreter::loadMap( lua_State * ) * Moved XML map download code from dlgMapper class to the TMap one: + (void) dlgMapper::downloadMap() ==> (bool) TMap::downloadMap(const QString * remoteUrl, const QString * localFileName) + (void) dlgMapper::setDownloadProgress(qint64, qint64) ==> (void) TMap::slot_setDownloadProgress(qint64,qint64) + (void) dlgMapper::cancel() ==> (void) TMap::slot_downloadCancel() + (void) dlgMapper::replyFinished(QNetworkReply *) ==> (void) TMap::slot_replyFinished(QNetworkReply *) * Enhanced download progress indication to also include parsing which can take even more time than download! * Provide means to import local XML map file * Prevent trying to import/download more than one map at a time Renamed: * (void) XMLimport::readAreaNames() ==> XMLimport::readArea() - for consistency with related functions Commented out unused: * (void) XMLimport::readUnknownRoomElement() Note the movement of the map file download code to the TMap class does require making the latter a class with the Q_OBJECT macro (which removes the need for Q_DECLARE_TR_FUNCTIONS as a side-effect!) - though as another side-effect the TMap header needed a boost name specifier added to one identifier as that identifier ("property") exists in both boost and QObject classes!!! YOU MAY NEED TO RUN QMAKE ON THE PROJECT IF THE BUILD SYSTEM DOES NOT PICK UP THE ADDITION OF "Q_OBJECT" TO TMAP CLASS. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: Include missing #include, remove unused return value The absence of this was causing build errors on the Travis C.I. platform! Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: move TMap.h to mudlet_MOC_HDRS to fix CMake build issue As we have made TMap inherit from QOject - to have signal/slot functionality that class needs to be run through Qt's MOC - and to do that with the CMake project/build system it needs to be included in the files included in the projects *_MOC_HDRS {and removed from the *_HDRS} variable. Also spotted a trivial error in that specifying a const return value from method is ineffective and pointless - so removed it from: TMap::retrieveMapFileStats(QString,QString *,int *,int *,int *,int *) Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: clean up TMap initialisation/clearing actions Now restores the customEnvColors set up on initialisation but that was cleared when the map replaced with another one that is loaded {which subsequently replaces that element anyway} or imported {which merely writes over it, replacing any matching keys}. Initialises elements that when inspected on the entry to the constructor proper previously were not being set to a consistent value {booleans/ints/floats}. NOTE: This will now clear the map user data member when the map is cleared if the date is required to be saved when one map is loaded OR IMPORTED over an existing one then the data will need to be saved outside of the map - as is already need for areas and rooms user data! Also comment out or remove unused members/methods: * (void) TMap::getConnectedNodesGreaterThanX(int, int) * (void) TMap::getConnectedNodesSmallerThanX(int, int) * (void) TMap::getConnectedNodesGreaterThanY(int, int) * (void) TMap::getConnectedNodesSmallerThanY(int, int) * (void) TMap::astBreitenAnpassung(int, int) * (void) TMap::astHoehenAnpassung(int, int) * (void) TMap::exportMapToDatabase() * (void) TMap::importMapFromDatabase() * (QVector3D) TMap::span * (int) TMap::mViewArea * (QMap<QString, int>) TMap::pixNameTable * (QMap<int, QPixmap>) TMap::pixTable * (bool) TMap::isToDisplayAuditErrorsToConsole Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * ImplimentationFixes: activate a valid optimisation & remove redundant code Adding a true as a non-default 3rd argument to TRoomDB::addRoom(...) call in XMLimport::readRoom(...) enables a significant optimisation (skips a computationally expensive step when ADDING a room to new map) which dramatically reduces the time to parse an XML map file. It also pointed to the fact that the TRoomDB::entranceMap was already correctly being handled and didn't need to be regenerated in XMLimport::readRoom(...) so the code that was added in a previous commit was redundant and could be removed. A code error in TMap::slot_setDownloadProgress(...) that caused an issue that a reviewer found on test has been fixed - the total download filesize that was being sent by the Qt system signal that is connected to this slot was a -1 value (as IS DOCUMENTED) when the Qt system does NOT know the size of a QNetworkReply in advance of reaching the end of the download was incorrectly handled in a previous commit in this change set. Also found during testing that there is no need for an error message for the QNetworkReply::OperationCanceledError case in TMap::slot_replayFinished(...) as it is already handled in the TMap::slot_downloadCancel() slot. Changed the text put up onto the progress widget during the XML room parsing to be a room count - which is likely more useful and to only do it for every hundredth room - which reduces any delay "wasted" in writing to the display - combined, the effects seem satisfactory IMHO. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: provide error messages for TLuaInterpreter::loadMap(...) Errors for the XML map file importing process as initiated from the Lua command should be returned to that command rather than plastered onto the main profile console - this commit attempts to perform that effect. In testing found that there was no error handling for failure to find or open the nominated file so messages for that have been added as well. Due to the previous program logic the action of creating a mapper widget using the main toolbar button automatically loaded the "default" (the newest Mudlet Map file format file from the currently active profile's map sub-directory). Under some previous situations it looked as though a map might be loaded twice as mudlet::slot_mapper() was called both directly and via signal/slot action. These were resolved by turning that slot into a wrapper that now calls the body of code formerly within to a new method mudlet::createMapper( bool isToLoadDefaultMapFile = true ) with a the default value as an argument. This allows other usages of the body of code to be called directly with a suitable argument, which for the TConsole::loadMap() & TConsole::importMap() and the dlgProfilePreferences::downloadMap() cases is false as they are all do not want the "default" map! Also: * spotted a word "area" missing from an advisory text in TRoom::auditRooms(...). Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: fix minor bug, correct a spelling, undo a few capitalisations Under certain, unanticipated (error with no error message) conditions TLuaInterpreter::loadMap(...) would push both a nil and then a false value onto the stack for return {wrong} but only indicate one value {correct}. The textual matters were found during peer review. off-by: Stephen Lyons <slysven@virginmedia.com>
2016-10-13 09:18:48 +01:00
// Finally release the lock on the XMLimporter
mXmlImportMutex.unlock();
return result;
}
bool TMap::readXmlMapFile(QFile& file, QString* errMsg)
Enhance: fix map downloading code, add manual XML map importing (#326) * Enhance: fix map downloading code, add manual XML map importing A recent move by I.R.E. to using SSL for their public MUD map URLs broke the ability for Mudlet to download those XML format files. This commit addresses this issue (as mentioned in, but not the original problem referred to in https://bugs.launchpad.net/mudlet/+bug/1427364) the revision to the code does now use "https://www.<MUD URL>/maps/map.xml" as a default name for the I.R.E. MUDS - however the method that initiates the download which was moved to TMap class from the dlgMapper one (see below) is now: (bool) TMap::downloadMap( const QString * remoteUrl = Q_NULLPTR, const QString * localFileName = Q_NULLPTR ) which if not supplied with any arguments behaves as before. However the remoteUrl argument may be given as a full QString including the scheme (the bit of the URL at the beginning before the ':') to override that and a second argument may be used to provide a different name to use for the local file name which if is a RELATIVE pathFileName will be resolved in relation to the profile directory. At present no use is made of this additional functionality but it may be useful for use with other MUDs if they should choose to provide XML map files with other remote locations and scripts using a different local filename. As a long-standing thing that needed doing I have finally provided a means to import a map XML file that - for instance - has already been download. It had been noted that there was no way to read those I.R.E. map files even if they had been obtained from a web browser able to correctly handle https: URLs - now both the TLuaInterpreter::loadMap() and the dlgProfilePreference "loadMap" button {NOT the IRE only "map download" one} will both handle files ending in ".xml" (not case sensitive so it'll work MacOS platforms as well!} For the loadMap case it will be necessary to change the filetype filter on the File Selection dialog to select "xml" files. During testing it became clear to me that it was possible to try and read one or more XML files via several mechanisms simultaneously with "unhelpful" consequences. As well as hitting the dlgProfilePreferences IRE "map download" multiple times, the TLuaInterpreter::loadMap() does NOT block until the map has been loaded and as the import time {running of XMLinport::readPackage(...)} is of significant duration for a large map (a debug, without optimisation, build on my 1.8GHz Quad-core took over two minutes to process the current Achaea map file) it is very possible to get conditions where the same profile will try to run XMLinport::readPackage(...) asynchronously - given that a profile only supports ONE map at a time it was necessary to fit a QMutex to prevent the part of the XMLinport class relating to XML Map files being called from different places in the map related code. This means that if a map download is started further downloads and any local map imports will fail until that first download has completed or aborted. Similarly a local import will prevent a download being started. As a side effect this cures: https://bugs.launchpad.net/mudlet/+bug/852861 - "Map download button starts another download thread if one is already going" The previous XML import code was not adding the rooms that it parsed to the relevant TArea::rooms member - although this would be picked-up and fixed by TMap::audit() later on, this would be accompanied by an error message about every single room. The code now builds up this information while parsing the rooms' details and inserts it so that this does not cause report-able problems during the TMap::audit() execution - the data gathered also allows missing areas to be spotted so that if a room claimed to belong to an area that was not included in the preceding areas' data an unnamed area is created for it. As a consequence of the long time to actually parse an XML map file I have enhanced the progress dialog that was originally used to track the map file download. It is now retained until the file is completely imported and shows more information about the process - importantly it shows during the XMLimport::readRoom(...) the room id being processed - and THAT method is the time/cpu hog so seeing something happening during the time that Mudlet otherwise appears to hang is useful feedback even if it adds a few seconds to the overall duration (may be more than a minute). This dialog is now also used during the other routes that involve reading an XML file and there is now a bit of consistence with the on-screen messages. Whilst inspecting XMLimport class I found there was some uncertain initialisation which I have tidied up. In summary: Added: * (bool) TConsole::importMap(const QString & location) * (void) TRoomDB::setAreaRooms(const int areaId, const QSet<int> & roomIds) * image file mudlet_map_download.png used as icon for download/import progress dialog * (bool) TMap::importMap(QFile & file) * (bool) TMap::readXmlMapFile(QFile & file) * (void) TMap::slot_downloadError(QNetworkReply::NetworkError error) * (void) TMap::reportStringToProgressDialog(const QString text) * (void) TMap::reportProgressToProgressDialog(const int current, const int maximum) Revised: * (int)TLuaInterpreter::loadMap( lua_State * ) * Moved XML map download code from dlgMapper class to the TMap one: + (void) dlgMapper::downloadMap() ==> (bool) TMap::downloadMap(const QString * remoteUrl, const QString * localFileName) + (void) dlgMapper::setDownloadProgress(qint64, qint64) ==> (void) TMap::slot_setDownloadProgress(qint64,qint64) + (void) dlgMapper::cancel() ==> (void) TMap::slot_downloadCancel() + (void) dlgMapper::replyFinished(QNetworkReply *) ==> (void) TMap::slot_replyFinished(QNetworkReply *) * Enhanced download progress indication to also include parsing which can take even more time than download! * Provide means to import local XML map file * Prevent trying to import/download more than one map at a time Renamed: * (void) XMLimport::readAreaNames() ==> XMLimport::readArea() - for consistency with related functions Commented out unused: * (void) XMLimport::readUnknownRoomElement() Note the movement of the map file download code to the TMap class does require making the latter a class with the Q_OBJECT macro (which removes the need for Q_DECLARE_TR_FUNCTIONS as a side-effect!) - though as another side-effect the TMap header needed a boost name specifier added to one identifier as that identifier ("property") exists in both boost and QObject classes!!! YOU MAY NEED TO RUN QMAKE ON THE PROJECT IF THE BUILD SYSTEM DOES NOT PICK UP THE ADDITION OF "Q_OBJECT" TO TMAP CLASS. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: Include missing #include, remove unused return value The absence of this was causing build errors on the Travis C.I. platform! Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: move TMap.h to mudlet_MOC_HDRS to fix CMake build issue As we have made TMap inherit from QOject - to have signal/slot functionality that class needs to be run through Qt's MOC - and to do that with the CMake project/build system it needs to be included in the files included in the projects *_MOC_HDRS {and removed from the *_HDRS} variable. Also spotted a trivial error in that specifying a const return value from method is ineffective and pointless - so removed it from: TMap::retrieveMapFileStats(QString,QString *,int *,int *,int *,int *) Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: clean up TMap initialisation/clearing actions Now restores the customEnvColors set up on initialisation but that was cleared when the map replaced with another one that is loaded {which subsequently replaces that element anyway} or imported {which merely writes over it, replacing any matching keys}. Initialises elements that when inspected on the entry to the constructor proper previously were not being set to a consistent value {booleans/ints/floats}. NOTE: This will now clear the map user data member when the map is cleared if the date is required to be saved when one map is loaded OR IMPORTED over an existing one then the data will need to be saved outside of the map - as is already need for areas and rooms user data! Also comment out or remove unused members/methods: * (void) TMap::getConnectedNodesGreaterThanX(int, int) * (void) TMap::getConnectedNodesSmallerThanX(int, int) * (void) TMap::getConnectedNodesGreaterThanY(int, int) * (void) TMap::getConnectedNodesSmallerThanY(int, int) * (void) TMap::astBreitenAnpassung(int, int) * (void) TMap::astHoehenAnpassung(int, int) * (void) TMap::exportMapToDatabase() * (void) TMap::importMapFromDatabase() * (QVector3D) TMap::span * (int) TMap::mViewArea * (QMap<QString, int>) TMap::pixNameTable * (QMap<int, QPixmap>) TMap::pixTable * (bool) TMap::isToDisplayAuditErrorsToConsole Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * ImplimentationFixes: activate a valid optimisation & remove redundant code Adding a true as a non-default 3rd argument to TRoomDB::addRoom(...) call in XMLimport::readRoom(...) enables a significant optimisation (skips a computationally expensive step when ADDING a room to new map) which dramatically reduces the time to parse an XML map file. It also pointed to the fact that the TRoomDB::entranceMap was already correctly being handled and didn't need to be regenerated in XMLimport::readRoom(...) so the code that was added in a previous commit was redundant and could be removed. A code error in TMap::slot_setDownloadProgress(...) that caused an issue that a reviewer found on test has been fixed - the total download filesize that was being sent by the Qt system signal that is connected to this slot was a -1 value (as IS DOCUMENTED) when the Qt system does NOT know the size of a QNetworkReply in advance of reaching the end of the download was incorrectly handled in a previous commit in this change set. Also found during testing that there is no need for an error message for the QNetworkReply::OperationCanceledError case in TMap::slot_replayFinished(...) as it is already handled in the TMap::slot_downloadCancel() slot. Changed the text put up onto the progress widget during the XML room parsing to be a room count - which is likely more useful and to only do it for every hundredth room - which reduces any delay "wasted" in writing to the display - combined, the effects seem satisfactory IMHO. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: provide error messages for TLuaInterpreter::loadMap(...) Errors for the XML map file importing process as initiated from the Lua command should be returned to that command rather than plastered onto the main profile console - this commit attempts to perform that effect. In testing found that there was no error handling for failure to find or open the nominated file so messages for that have been added as well. Due to the previous program logic the action of creating a mapper widget using the main toolbar button automatically loaded the "default" (the newest Mudlet Map file format file from the currently active profile's map sub-directory). Under some previous situations it looked as though a map might be loaded twice as mudlet::slot_mapper() was called both directly and via signal/slot action. These were resolved by turning that slot into a wrapper that now calls the body of code formerly within to a new method mudlet::createMapper( bool isToLoadDefaultMapFile = true ) with a the default value as an argument. This allows other usages of the body of code to be called directly with a suitable argument, which for the TConsole::loadMap() & TConsole::importMap() and the dlgProfilePreferences::downloadMap() cases is false as they are all do not want the "default" map! Also: * spotted a word "area" missing from an advisory text in TRoom::auditRooms(...). Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: fix minor bug, correct a spelling, undo a few capitalisations Under certain, unanticipated (error with no error message) conditions TLuaInterpreter::loadMap(...) would push both a nil and then a false value onto the stack for return {wrong} but only indicate one value {correct}. The textual matters were found during peer review. off-by: Stephen Lyons <slysven@virginmedia.com>
2016-10-13 09:18:48 +01:00
{
Host* pHost = mpHost;
Enhance: fix map downloading code, add manual XML map importing (#326) * Enhance: fix map downloading code, add manual XML map importing A recent move by I.R.E. to using SSL for their public MUD map URLs broke the ability for Mudlet to download those XML format files. This commit addresses this issue (as mentioned in, but not the original problem referred to in https://bugs.launchpad.net/mudlet/+bug/1427364) the revision to the code does now use "https://www.<MUD URL>/maps/map.xml" as a default name for the I.R.E. MUDS - however the method that initiates the download which was moved to TMap class from the dlgMapper one (see below) is now: (bool) TMap::downloadMap( const QString * remoteUrl = Q_NULLPTR, const QString * localFileName = Q_NULLPTR ) which if not supplied with any arguments behaves as before. However the remoteUrl argument may be given as a full QString including the scheme (the bit of the URL at the beginning before the ':') to override that and a second argument may be used to provide a different name to use for the local file name which if is a RELATIVE pathFileName will be resolved in relation to the profile directory. At present no use is made of this additional functionality but it may be useful for use with other MUDs if they should choose to provide XML map files with other remote locations and scripts using a different local filename. As a long-standing thing that needed doing I have finally provided a means to import a map XML file that - for instance - has already been download. It had been noted that there was no way to read those I.R.E. map files even if they had been obtained from a web browser able to correctly handle https: URLs - now both the TLuaInterpreter::loadMap() and the dlgProfilePreference "loadMap" button {NOT the IRE only "map download" one} will both handle files ending in ".xml" (not case sensitive so it'll work MacOS platforms as well!} For the loadMap case it will be necessary to change the filetype filter on the File Selection dialog to select "xml" files. During testing it became clear to me that it was possible to try and read one or more XML files via several mechanisms simultaneously with "unhelpful" consequences. As well as hitting the dlgProfilePreferences IRE "map download" multiple times, the TLuaInterpreter::loadMap() does NOT block until the map has been loaded and as the import time {running of XMLinport::readPackage(...)} is of significant duration for a large map (a debug, without optimisation, build on my 1.8GHz Quad-core took over two minutes to process the current Achaea map file) it is very possible to get conditions where the same profile will try to run XMLinport::readPackage(...) asynchronously - given that a profile only supports ONE map at a time it was necessary to fit a QMutex to prevent the part of the XMLinport class relating to XML Map files being called from different places in the map related code. This means that if a map download is started further downloads and any local map imports will fail until that first download has completed or aborted. Similarly a local import will prevent a download being started. As a side effect this cures: https://bugs.launchpad.net/mudlet/+bug/852861 - "Map download button starts another download thread if one is already going" The previous XML import code was not adding the rooms that it parsed to the relevant TArea::rooms member - although this would be picked-up and fixed by TMap::audit() later on, this would be accompanied by an error message about every single room. The code now builds up this information while parsing the rooms' details and inserts it so that this does not cause report-able problems during the TMap::audit() execution - the data gathered also allows missing areas to be spotted so that if a room claimed to belong to an area that was not included in the preceding areas' data an unnamed area is created for it. As a consequence of the long time to actually parse an XML map file I have enhanced the progress dialog that was originally used to track the map file download. It is now retained until the file is completely imported and shows more information about the process - importantly it shows during the XMLimport::readRoom(...) the room id being processed - and THAT method is the time/cpu hog so seeing something happening during the time that Mudlet otherwise appears to hang is useful feedback even if it adds a few seconds to the overall duration (may be more than a minute). This dialog is now also used during the other routes that involve reading an XML file and there is now a bit of consistence with the on-screen messages. Whilst inspecting XMLimport class I found there was some uncertain initialisation which I have tidied up. In summary: Added: * (bool) TConsole::importMap(const QString & location) * (void) TRoomDB::setAreaRooms(const int areaId, const QSet<int> & roomIds) * image file mudlet_map_download.png used as icon for download/import progress dialog * (bool) TMap::importMap(QFile & file) * (bool) TMap::readXmlMapFile(QFile & file) * (void) TMap::slot_downloadError(QNetworkReply::NetworkError error) * (void) TMap::reportStringToProgressDialog(const QString text) * (void) TMap::reportProgressToProgressDialog(const int current, const int maximum) Revised: * (int)TLuaInterpreter::loadMap( lua_State * ) * Moved XML map download code from dlgMapper class to the TMap one: + (void) dlgMapper::downloadMap() ==> (bool) TMap::downloadMap(const QString * remoteUrl, const QString * localFileName) + (void) dlgMapper::setDownloadProgress(qint64, qint64) ==> (void) TMap::slot_setDownloadProgress(qint64,qint64) + (void) dlgMapper::cancel() ==> (void) TMap::slot_downloadCancel() + (void) dlgMapper::replyFinished(QNetworkReply *) ==> (void) TMap::slot_replyFinished(QNetworkReply *) * Enhanced download progress indication to also include parsing which can take even more time than download! * Provide means to import local XML map file * Prevent trying to import/download more than one map at a time Renamed: * (void) XMLimport::readAreaNames() ==> XMLimport::readArea() - for consistency with related functions Commented out unused: * (void) XMLimport::readUnknownRoomElement() Note the movement of the map file download code to the TMap class does require making the latter a class with the Q_OBJECT macro (which removes the need for Q_DECLARE_TR_FUNCTIONS as a side-effect!) - though as another side-effect the TMap header needed a boost name specifier added to one identifier as that identifier ("property") exists in both boost and QObject classes!!! YOU MAY NEED TO RUN QMAKE ON THE PROJECT IF THE BUILD SYSTEM DOES NOT PICK UP THE ADDITION OF "Q_OBJECT" TO TMAP CLASS. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: Include missing #include, remove unused return value The absence of this was causing build errors on the Travis C.I. platform! Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: move TMap.h to mudlet_MOC_HDRS to fix CMake build issue As we have made TMap inherit from QOject - to have signal/slot functionality that class needs to be run through Qt's MOC - and to do that with the CMake project/build system it needs to be included in the files included in the projects *_MOC_HDRS {and removed from the *_HDRS} variable. Also spotted a trivial error in that specifying a const return value from method is ineffective and pointless - so removed it from: TMap::retrieveMapFileStats(QString,QString *,int *,int *,int *,int *) Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: clean up TMap initialisation/clearing actions Now restores the customEnvColors set up on initialisation but that was cleared when the map replaced with another one that is loaded {which subsequently replaces that element anyway} or imported {which merely writes over it, replacing any matching keys}. Initialises elements that when inspected on the entry to the constructor proper previously were not being set to a consistent value {booleans/ints/floats}. NOTE: This will now clear the map user data member when the map is cleared if the date is required to be saved when one map is loaded OR IMPORTED over an existing one then the data will need to be saved outside of the map - as is already need for areas and rooms user data! Also comment out or remove unused members/methods: * (void) TMap::getConnectedNodesGreaterThanX(int, int) * (void) TMap::getConnectedNodesSmallerThanX(int, int) * (void) TMap::getConnectedNodesGreaterThanY(int, int) * (void) TMap::getConnectedNodesSmallerThanY(int, int) * (void) TMap::astBreitenAnpassung(int, int) * (void) TMap::astHoehenAnpassung(int, int) * (void) TMap::exportMapToDatabase() * (void) TMap::importMapFromDatabase() * (QVector3D) TMap::span * (int) TMap::mViewArea * (QMap<QString, int>) TMap::pixNameTable * (QMap<int, QPixmap>) TMap::pixTable * (bool) TMap::isToDisplayAuditErrorsToConsole Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * ImplimentationFixes: activate a valid optimisation & remove redundant code Adding a true as a non-default 3rd argument to TRoomDB::addRoom(...) call in XMLimport::readRoom(...) enables a significant optimisation (skips a computationally expensive step when ADDING a room to new map) which dramatically reduces the time to parse an XML map file. It also pointed to the fact that the TRoomDB::entranceMap was already correctly being handled and didn't need to be regenerated in XMLimport::readRoom(...) so the code that was added in a previous commit was redundant and could be removed. A code error in TMap::slot_setDownloadProgress(...) that caused an issue that a reviewer found on test has been fixed - the total download filesize that was being sent by the Qt system signal that is connected to this slot was a -1 value (as IS DOCUMENTED) when the Qt system does NOT know the size of a QNetworkReply in advance of reaching the end of the download was incorrectly handled in a previous commit in this change set. Also found during testing that there is no need for an error message for the QNetworkReply::OperationCanceledError case in TMap::slot_replayFinished(...) as it is already handled in the TMap::slot_downloadCancel() slot. Changed the text put up onto the progress widget during the XML room parsing to be a room count - which is likely more useful and to only do it for every hundredth room - which reduces any delay "wasted" in writing to the display - combined, the effects seem satisfactory IMHO. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: provide error messages for TLuaInterpreter::loadMap(...) Errors for the XML map file importing process as initiated from the Lua command should be returned to that command rather than plastered onto the main profile console - this commit attempts to perform that effect. In testing found that there was no error handling for failure to find or open the nominated file so messages for that have been added as well. Due to the previous program logic the action of creating a mapper widget using the main toolbar button automatically loaded the "default" (the newest Mudlet Map file format file from the currently active profile's map sub-directory). Under some previous situations it looked as though a map might be loaded twice as mudlet::slot_mapper() was called both directly and via signal/slot action. These were resolved by turning that slot into a wrapper that now calls the body of code formerly within to a new method mudlet::createMapper( bool isToLoadDefaultMapFile = true ) with a the default value as an argument. This allows other usages of the body of code to be called directly with a suitable argument, which for the TConsole::loadMap() & TConsole::importMap() and the dlgProfilePreferences::downloadMap() cases is false as they are all do not want the "default" map! Also: * spotted a word "area" missing from an advisory text in TRoom::auditRooms(...). Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: fix minor bug, correct a spelling, undo a few capitalisations Under certain, unanticipated (error with no error message) conditions TLuaInterpreter::loadMap(...) would push both a nil and then a false value onto the stack for return {wrong} but only indicate one value {correct}. The textual matters were found during peer review. off-by: Stephen Lyons <slysven@virginmedia.com>
2016-10-13 09:18:48 +01:00
bool isLocalImport = false;
if (!pHost) {
Enhance: fix map downloading code, add manual XML map importing (#326) * Enhance: fix map downloading code, add manual XML map importing A recent move by I.R.E. to using SSL for their public MUD map URLs broke the ability for Mudlet to download those XML format files. This commit addresses this issue (as mentioned in, but not the original problem referred to in https://bugs.launchpad.net/mudlet/+bug/1427364) the revision to the code does now use "https://www.<MUD URL>/maps/map.xml" as a default name for the I.R.E. MUDS - however the method that initiates the download which was moved to TMap class from the dlgMapper one (see below) is now: (bool) TMap::downloadMap( const QString * remoteUrl = Q_NULLPTR, const QString * localFileName = Q_NULLPTR ) which if not supplied with any arguments behaves as before. However the remoteUrl argument may be given as a full QString including the scheme (the bit of the URL at the beginning before the ':') to override that and a second argument may be used to provide a different name to use for the local file name which if is a RELATIVE pathFileName will be resolved in relation to the profile directory. At present no use is made of this additional functionality but it may be useful for use with other MUDs if they should choose to provide XML map files with other remote locations and scripts using a different local filename. As a long-standing thing that needed doing I have finally provided a means to import a map XML file that - for instance - has already been download. It had been noted that there was no way to read those I.R.E. map files even if they had been obtained from a web browser able to correctly handle https: URLs - now both the TLuaInterpreter::loadMap() and the dlgProfilePreference "loadMap" button {NOT the IRE only "map download" one} will both handle files ending in ".xml" (not case sensitive so it'll work MacOS platforms as well!} For the loadMap case it will be necessary to change the filetype filter on the File Selection dialog to select "xml" files. During testing it became clear to me that it was possible to try and read one or more XML files via several mechanisms simultaneously with "unhelpful" consequences. As well as hitting the dlgProfilePreferences IRE "map download" multiple times, the TLuaInterpreter::loadMap() does NOT block until the map has been loaded and as the import time {running of XMLinport::readPackage(...)} is of significant duration for a large map (a debug, without optimisation, build on my 1.8GHz Quad-core took over two minutes to process the current Achaea map file) it is very possible to get conditions where the same profile will try to run XMLinport::readPackage(...) asynchronously - given that a profile only supports ONE map at a time it was necessary to fit a QMutex to prevent the part of the XMLinport class relating to XML Map files being called from different places in the map related code. This means that if a map download is started further downloads and any local map imports will fail until that first download has completed or aborted. Similarly a local import will prevent a download being started. As a side effect this cures: https://bugs.launchpad.net/mudlet/+bug/852861 - "Map download button starts another download thread if one is already going" The previous XML import code was not adding the rooms that it parsed to the relevant TArea::rooms member - although this would be picked-up and fixed by TMap::audit() later on, this would be accompanied by an error message about every single room. The code now builds up this information while parsing the rooms' details and inserts it so that this does not cause report-able problems during the TMap::audit() execution - the data gathered also allows missing areas to be spotted so that if a room claimed to belong to an area that was not included in the preceding areas' data an unnamed area is created for it. As a consequence of the long time to actually parse an XML map file I have enhanced the progress dialog that was originally used to track the map file download. It is now retained until the file is completely imported and shows more information about the process - importantly it shows during the XMLimport::readRoom(...) the room id being processed - and THAT method is the time/cpu hog so seeing something happening during the time that Mudlet otherwise appears to hang is useful feedback even if it adds a few seconds to the overall duration (may be more than a minute). This dialog is now also used during the other routes that involve reading an XML file and there is now a bit of consistence with the on-screen messages. Whilst inspecting XMLimport class I found there was some uncertain initialisation which I have tidied up. In summary: Added: * (bool) TConsole::importMap(const QString & location) * (void) TRoomDB::setAreaRooms(const int areaId, const QSet<int> & roomIds) * image file mudlet_map_download.png used as icon for download/import progress dialog * (bool) TMap::importMap(QFile & file) * (bool) TMap::readXmlMapFile(QFile & file) * (void) TMap::slot_downloadError(QNetworkReply::NetworkError error) * (void) TMap::reportStringToProgressDialog(const QString text) * (void) TMap::reportProgressToProgressDialog(const int current, const int maximum) Revised: * (int)TLuaInterpreter::loadMap( lua_State * ) * Moved XML map download code from dlgMapper class to the TMap one: + (void) dlgMapper::downloadMap() ==> (bool) TMap::downloadMap(const QString * remoteUrl, const QString * localFileName) + (void) dlgMapper::setDownloadProgress(qint64, qint64) ==> (void) TMap::slot_setDownloadProgress(qint64,qint64) + (void) dlgMapper::cancel() ==> (void) TMap::slot_downloadCancel() + (void) dlgMapper::replyFinished(QNetworkReply *) ==> (void) TMap::slot_replyFinished(QNetworkReply *) * Enhanced download progress indication to also include parsing which can take even more time than download! * Provide means to import local XML map file * Prevent trying to import/download more than one map at a time Renamed: * (void) XMLimport::readAreaNames() ==> XMLimport::readArea() - for consistency with related functions Commented out unused: * (void) XMLimport::readUnknownRoomElement() Note the movement of the map file download code to the TMap class does require making the latter a class with the Q_OBJECT macro (which removes the need for Q_DECLARE_TR_FUNCTIONS as a side-effect!) - though as another side-effect the TMap header needed a boost name specifier added to one identifier as that identifier ("property") exists in both boost and QObject classes!!! YOU MAY NEED TO RUN QMAKE ON THE PROJECT IF THE BUILD SYSTEM DOES NOT PICK UP THE ADDITION OF "Q_OBJECT" TO TMAP CLASS. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: Include missing #include, remove unused return value The absence of this was causing build errors on the Travis C.I. platform! Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: move TMap.h to mudlet_MOC_HDRS to fix CMake build issue As we have made TMap inherit from QOject - to have signal/slot functionality that class needs to be run through Qt's MOC - and to do that with the CMake project/build system it needs to be included in the files included in the projects *_MOC_HDRS {and removed from the *_HDRS} variable. Also spotted a trivial error in that specifying a const return value from method is ineffective and pointless - so removed it from: TMap::retrieveMapFileStats(QString,QString *,int *,int *,int *,int *) Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: clean up TMap initialisation/clearing actions Now restores the customEnvColors set up on initialisation but that was cleared when the map replaced with another one that is loaded {which subsequently replaces that element anyway} or imported {which merely writes over it, replacing any matching keys}. Initialises elements that when inspected on the entry to the constructor proper previously were not being set to a consistent value {booleans/ints/floats}. NOTE: This will now clear the map user data member when the map is cleared if the date is required to be saved when one map is loaded OR IMPORTED over an existing one then the data will need to be saved outside of the map - as is already need for areas and rooms user data! Also comment out or remove unused members/methods: * (void) TMap::getConnectedNodesGreaterThanX(int, int) * (void) TMap::getConnectedNodesSmallerThanX(int, int) * (void) TMap::getConnectedNodesGreaterThanY(int, int) * (void) TMap::getConnectedNodesSmallerThanY(int, int) * (void) TMap::astBreitenAnpassung(int, int) * (void) TMap::astHoehenAnpassung(int, int) * (void) TMap::exportMapToDatabase() * (void) TMap::importMapFromDatabase() * (QVector3D) TMap::span * (int) TMap::mViewArea * (QMap<QString, int>) TMap::pixNameTable * (QMap<int, QPixmap>) TMap::pixTable * (bool) TMap::isToDisplayAuditErrorsToConsole Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * ImplimentationFixes: activate a valid optimisation & remove redundant code Adding a true as a non-default 3rd argument to TRoomDB::addRoom(...) call in XMLimport::readRoom(...) enables a significant optimisation (skips a computationally expensive step when ADDING a room to new map) which dramatically reduces the time to parse an XML map file. It also pointed to the fact that the TRoomDB::entranceMap was already correctly being handled and didn't need to be regenerated in XMLimport::readRoom(...) so the code that was added in a previous commit was redundant and could be removed. A code error in TMap::slot_setDownloadProgress(...) that caused an issue that a reviewer found on test has been fixed - the total download filesize that was being sent by the Qt system signal that is connected to this slot was a -1 value (as IS DOCUMENTED) when the Qt system does NOT know the size of a QNetworkReply in advance of reaching the end of the download was incorrectly handled in a previous commit in this change set. Also found during testing that there is no need for an error message for the QNetworkReply::OperationCanceledError case in TMap::slot_replayFinished(...) as it is already handled in the TMap::slot_downloadCancel() slot. Changed the text put up onto the progress widget during the XML room parsing to be a room count - which is likely more useful and to only do it for every hundredth room - which reduces any delay "wasted" in writing to the display - combined, the effects seem satisfactory IMHO. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: provide error messages for TLuaInterpreter::loadMap(...) Errors for the XML map file importing process as initiated from the Lua command should be returned to that command rather than plastered onto the main profile console - this commit attempts to perform that effect. In testing found that there was no error handling for failure to find or open the nominated file so messages for that have been added as well. Due to the previous program logic the action of creating a mapper widget using the main toolbar button automatically loaded the "default" (the newest Mudlet Map file format file from the currently active profile's map sub-directory). Under some previous situations it looked as though a map might be loaded twice as mudlet::slot_mapper() was called both directly and via signal/slot action. These were resolved by turning that slot into a wrapper that now calls the body of code formerly within to a new method mudlet::createMapper( bool isToLoadDefaultMapFile = true ) with a the default value as an argument. This allows other usages of the body of code to be called directly with a suitable argument, which for the TConsole::loadMap() & TConsole::importMap() and the dlgProfilePreferences::downloadMap() cases is false as they are all do not want the "default" map! Also: * spotted a word "area" missing from an advisory text in TRoom::auditRooms(...). Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: fix minor bug, correct a spelling, undo a few capitalisations Under certain, unanticipated (error with no error message) conditions TLuaInterpreter::loadMap(...) would push both a nil and then a false value onto the stack for return {wrong} but only indicate one value {correct}. The textual matters were found during peer review. off-by: Stephen Lyons <slysven@virginmedia.com>
2016-10-13 09:18:48 +01:00
return false;
}
if (!mpProgressDialog) {
Enhance: fix map downloading code, add manual XML map importing (#326) * Enhance: fix map downloading code, add manual XML map importing A recent move by I.R.E. to using SSL for their public MUD map URLs broke the ability for Mudlet to download those XML format files. This commit addresses this issue (as mentioned in, but not the original problem referred to in https://bugs.launchpad.net/mudlet/+bug/1427364) the revision to the code does now use "https://www.<MUD URL>/maps/map.xml" as a default name for the I.R.E. MUDS - however the method that initiates the download which was moved to TMap class from the dlgMapper one (see below) is now: (bool) TMap::downloadMap( const QString * remoteUrl = Q_NULLPTR, const QString * localFileName = Q_NULLPTR ) which if not supplied with any arguments behaves as before. However the remoteUrl argument may be given as a full QString including the scheme (the bit of the URL at the beginning before the ':') to override that and a second argument may be used to provide a different name to use for the local file name which if is a RELATIVE pathFileName will be resolved in relation to the profile directory. At present no use is made of this additional functionality but it may be useful for use with other MUDs if they should choose to provide XML map files with other remote locations and scripts using a different local filename. As a long-standing thing that needed doing I have finally provided a means to import a map XML file that - for instance - has already been download. It had been noted that there was no way to read those I.R.E. map files even if they had been obtained from a web browser able to correctly handle https: URLs - now both the TLuaInterpreter::loadMap() and the dlgProfilePreference "loadMap" button {NOT the IRE only "map download" one} will both handle files ending in ".xml" (not case sensitive so it'll work MacOS platforms as well!} For the loadMap case it will be necessary to change the filetype filter on the File Selection dialog to select "xml" files. During testing it became clear to me that it was possible to try and read one or more XML files via several mechanisms simultaneously with "unhelpful" consequences. As well as hitting the dlgProfilePreferences IRE "map download" multiple times, the TLuaInterpreter::loadMap() does NOT block until the map has been loaded and as the import time {running of XMLinport::readPackage(...)} is of significant duration for a large map (a debug, without optimisation, build on my 1.8GHz Quad-core took over two minutes to process the current Achaea map file) it is very possible to get conditions where the same profile will try to run XMLinport::readPackage(...) asynchronously - given that a profile only supports ONE map at a time it was necessary to fit a QMutex to prevent the part of the XMLinport class relating to XML Map files being called from different places in the map related code. This means that if a map download is started further downloads and any local map imports will fail until that first download has completed or aborted. Similarly a local import will prevent a download being started. As a side effect this cures: https://bugs.launchpad.net/mudlet/+bug/852861 - "Map download button starts another download thread if one is already going" The previous XML import code was not adding the rooms that it parsed to the relevant TArea::rooms member - although this would be picked-up and fixed by TMap::audit() later on, this would be accompanied by an error message about every single room. The code now builds up this information while parsing the rooms' details and inserts it so that this does not cause report-able problems during the TMap::audit() execution - the data gathered also allows missing areas to be spotted so that if a room claimed to belong to an area that was not included in the preceding areas' data an unnamed area is created for it. As a consequence of the long time to actually parse an XML map file I have enhanced the progress dialog that was originally used to track the map file download. It is now retained until the file is completely imported and shows more information about the process - importantly it shows during the XMLimport::readRoom(...) the room id being processed - and THAT method is the time/cpu hog so seeing something happening during the time that Mudlet otherwise appears to hang is useful feedback even if it adds a few seconds to the overall duration (may be more than a minute). This dialog is now also used during the other routes that involve reading an XML file and there is now a bit of consistence with the on-screen messages. Whilst inspecting XMLimport class I found there was some uncertain initialisation which I have tidied up. In summary: Added: * (bool) TConsole::importMap(const QString & location) * (void) TRoomDB::setAreaRooms(const int areaId, const QSet<int> & roomIds) * image file mudlet_map_download.png used as icon for download/import progress dialog * (bool) TMap::importMap(QFile & file) * (bool) TMap::readXmlMapFile(QFile & file) * (void) TMap::slot_downloadError(QNetworkReply::NetworkError error) * (void) TMap::reportStringToProgressDialog(const QString text) * (void) TMap::reportProgressToProgressDialog(const int current, const int maximum) Revised: * (int)TLuaInterpreter::loadMap( lua_State * ) * Moved XML map download code from dlgMapper class to the TMap one: + (void) dlgMapper::downloadMap() ==> (bool) TMap::downloadMap(const QString * remoteUrl, const QString * localFileName) + (void) dlgMapper::setDownloadProgress(qint64, qint64) ==> (void) TMap::slot_setDownloadProgress(qint64,qint64) + (void) dlgMapper::cancel() ==> (void) TMap::slot_downloadCancel() + (void) dlgMapper::replyFinished(QNetworkReply *) ==> (void) TMap::slot_replyFinished(QNetworkReply *) * Enhanced download progress indication to also include parsing which can take even more time than download! * Provide means to import local XML map file * Prevent trying to import/download more than one map at a time Renamed: * (void) XMLimport::readAreaNames() ==> XMLimport::readArea() - for consistency with related functions Commented out unused: * (void) XMLimport::readUnknownRoomElement() Note the movement of the map file download code to the TMap class does require making the latter a class with the Q_OBJECT macro (which removes the need for Q_DECLARE_TR_FUNCTIONS as a side-effect!) - though as another side-effect the TMap header needed a boost name specifier added to one identifier as that identifier ("property") exists in both boost and QObject classes!!! YOU MAY NEED TO RUN QMAKE ON THE PROJECT IF THE BUILD SYSTEM DOES NOT PICK UP THE ADDITION OF "Q_OBJECT" TO TMAP CLASS. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: Include missing #include, remove unused return value The absence of this was causing build errors on the Travis C.I. platform! Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: move TMap.h to mudlet_MOC_HDRS to fix CMake build issue As we have made TMap inherit from QOject - to have signal/slot functionality that class needs to be run through Qt's MOC - and to do that with the CMake project/build system it needs to be included in the files included in the projects *_MOC_HDRS {and removed from the *_HDRS} variable. Also spotted a trivial error in that specifying a const return value from method is ineffective and pointless - so removed it from: TMap::retrieveMapFileStats(QString,QString *,int *,int *,int *,int *) Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: clean up TMap initialisation/clearing actions Now restores the customEnvColors set up on initialisation but that was cleared when the map replaced with another one that is loaded {which subsequently replaces that element anyway} or imported {which merely writes over it, replacing any matching keys}. Initialises elements that when inspected on the entry to the constructor proper previously were not being set to a consistent value {booleans/ints/floats}. NOTE: This will now clear the map user data member when the map is cleared if the date is required to be saved when one map is loaded OR IMPORTED over an existing one then the data will need to be saved outside of the map - as is already need for areas and rooms user data! Also comment out or remove unused members/methods: * (void) TMap::getConnectedNodesGreaterThanX(int, int) * (void) TMap::getConnectedNodesSmallerThanX(int, int) * (void) TMap::getConnectedNodesGreaterThanY(int, int) * (void) TMap::getConnectedNodesSmallerThanY(int, int) * (void) TMap::astBreitenAnpassung(int, int) * (void) TMap::astHoehenAnpassung(int, int) * (void) TMap::exportMapToDatabase() * (void) TMap::importMapFromDatabase() * (QVector3D) TMap::span * (int) TMap::mViewArea * (QMap<QString, int>) TMap::pixNameTable * (QMap<int, QPixmap>) TMap::pixTable * (bool) TMap::isToDisplayAuditErrorsToConsole Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * ImplimentationFixes: activate a valid optimisation & remove redundant code Adding a true as a non-default 3rd argument to TRoomDB::addRoom(...) call in XMLimport::readRoom(...) enables a significant optimisation (skips a computationally expensive step when ADDING a room to new map) which dramatically reduces the time to parse an XML map file. It also pointed to the fact that the TRoomDB::entranceMap was already correctly being handled and didn't need to be regenerated in XMLimport::readRoom(...) so the code that was added in a previous commit was redundant and could be removed. A code error in TMap::slot_setDownloadProgress(...) that caused an issue that a reviewer found on test has been fixed - the total download filesize that was being sent by the Qt system signal that is connected to this slot was a -1 value (as IS DOCUMENTED) when the Qt system does NOT know the size of a QNetworkReply in advance of reaching the end of the download was incorrectly handled in a previous commit in this change set. Also found during testing that there is no need for an error message for the QNetworkReply::OperationCanceledError case in TMap::slot_replayFinished(...) as it is already handled in the TMap::slot_downloadCancel() slot. Changed the text put up onto the progress widget during the XML room parsing to be a room count - which is likely more useful and to only do it for every hundredth room - which reduces any delay "wasted" in writing to the display - combined, the effects seem satisfactory IMHO. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: provide error messages for TLuaInterpreter::loadMap(...) Errors for the XML map file importing process as initiated from the Lua command should be returned to that command rather than plastered onto the main profile console - this commit attempts to perform that effect. In testing found that there was no error handling for failure to find or open the nominated file so messages for that have been added as well. Due to the previous program logic the action of creating a mapper widget using the main toolbar button automatically loaded the "default" (the newest Mudlet Map file format file from the currently active profile's map sub-directory). Under some previous situations it looked as though a map might be loaded twice as mudlet::slot_mapper() was called both directly and via signal/slot action. These were resolved by turning that slot into a wrapper that now calls the body of code formerly within to a new method mudlet::createMapper( bool isToLoadDefaultMapFile = true ) with a the default value as an argument. This allows other usages of the body of code to be called directly with a suitable argument, which for the TConsole::loadMap() & TConsole::importMap() and the dlgProfilePreferences::downloadMap() cases is false as they are all do not want the "default" map! Also: * spotted a word "area" missing from an advisory text in TRoom::auditRooms(...). Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: fix minor bug, correct a spelling, undo a few capitalisations Under certain, unanticipated (error with no error message) conditions TLuaInterpreter::loadMap(...) would push both a nil and then a false value onto the stack for return {wrong} but only indicate one value {correct}. The textual matters were found during peer review. off-by: Stephen Lyons <slysven@virginmedia.com>
2016-10-13 09:18:48 +01:00
// This is the local import case - which has not got a progress dialog
// until now:
isLocalImport = true;
mpProgressDialog = new QProgressDialog(tr("Importing XML map file for use in %1...").arg(pHost->getName()), QString(), 0, 0);
mpProgressDialog->setWindowTitle(tr("Map import"));
mpProgressDialog->setWindowIcon(QIcon(QStringLiteral(":/icons/mudlet_map_download.png")));
mpProgressDialog->setMinimumWidth(300);
mpProgressDialog->setAutoClose(false);
mpProgressDialog->setAutoReset(false);
mpProgressDialog->setMinimumDuration(0); // Normally waits for 4 seconds before showing
} else {
Enhance: fix map downloading code, add manual XML map importing (#326) * Enhance: fix map downloading code, add manual XML map importing A recent move by I.R.E. to using SSL for their public MUD map URLs broke the ability for Mudlet to download those XML format files. This commit addresses this issue (as mentioned in, but not the original problem referred to in https://bugs.launchpad.net/mudlet/+bug/1427364) the revision to the code does now use "https://www.<MUD URL>/maps/map.xml" as a default name for the I.R.E. MUDS - however the method that initiates the download which was moved to TMap class from the dlgMapper one (see below) is now: (bool) TMap::downloadMap( const QString * remoteUrl = Q_NULLPTR, const QString * localFileName = Q_NULLPTR ) which if not supplied with any arguments behaves as before. However the remoteUrl argument may be given as a full QString including the scheme (the bit of the URL at the beginning before the ':') to override that and a second argument may be used to provide a different name to use for the local file name which if is a RELATIVE pathFileName will be resolved in relation to the profile directory. At present no use is made of this additional functionality but it may be useful for use with other MUDs if they should choose to provide XML map files with other remote locations and scripts using a different local filename. As a long-standing thing that needed doing I have finally provided a means to import a map XML file that - for instance - has already been download. It had been noted that there was no way to read those I.R.E. map files even if they had been obtained from a web browser able to correctly handle https: URLs - now both the TLuaInterpreter::loadMap() and the dlgProfilePreference "loadMap" button {NOT the IRE only "map download" one} will both handle files ending in ".xml" (not case sensitive so it'll work MacOS platforms as well!} For the loadMap case it will be necessary to change the filetype filter on the File Selection dialog to select "xml" files. During testing it became clear to me that it was possible to try and read one or more XML files via several mechanisms simultaneously with "unhelpful" consequences. As well as hitting the dlgProfilePreferences IRE "map download" multiple times, the TLuaInterpreter::loadMap() does NOT block until the map has been loaded and as the import time {running of XMLinport::readPackage(...)} is of significant duration for a large map (a debug, without optimisation, build on my 1.8GHz Quad-core took over two minutes to process the current Achaea map file) it is very possible to get conditions where the same profile will try to run XMLinport::readPackage(...) asynchronously - given that a profile only supports ONE map at a time it was necessary to fit a QMutex to prevent the part of the XMLinport class relating to XML Map files being called from different places in the map related code. This means that if a map download is started further downloads and any local map imports will fail until that first download has completed or aborted. Similarly a local import will prevent a download being started. As a side effect this cures: https://bugs.launchpad.net/mudlet/+bug/852861 - "Map download button starts another download thread if one is already going" The previous XML import code was not adding the rooms that it parsed to the relevant TArea::rooms member - although this would be picked-up and fixed by TMap::audit() later on, this would be accompanied by an error message about every single room. The code now builds up this information while parsing the rooms' details and inserts it so that this does not cause report-able problems during the TMap::audit() execution - the data gathered also allows missing areas to be spotted so that if a room claimed to belong to an area that was not included in the preceding areas' data an unnamed area is created for it. As a consequence of the long time to actually parse an XML map file I have enhanced the progress dialog that was originally used to track the map file download. It is now retained until the file is completely imported and shows more information about the process - importantly it shows during the XMLimport::readRoom(...) the room id being processed - and THAT method is the time/cpu hog so seeing something happening during the time that Mudlet otherwise appears to hang is useful feedback even if it adds a few seconds to the overall duration (may be more than a minute). This dialog is now also used during the other routes that involve reading an XML file and there is now a bit of consistence with the on-screen messages. Whilst inspecting XMLimport class I found there was some uncertain initialisation which I have tidied up. In summary: Added: * (bool) TConsole::importMap(const QString & location) * (void) TRoomDB::setAreaRooms(const int areaId, const QSet<int> & roomIds) * image file mudlet_map_download.png used as icon for download/import progress dialog * (bool) TMap::importMap(QFile & file) * (bool) TMap::readXmlMapFile(QFile & file) * (void) TMap::slot_downloadError(QNetworkReply::NetworkError error) * (void) TMap::reportStringToProgressDialog(const QString text) * (void) TMap::reportProgressToProgressDialog(const int current, const int maximum) Revised: * (int)TLuaInterpreter::loadMap( lua_State * ) * Moved XML map download code from dlgMapper class to the TMap one: + (void) dlgMapper::downloadMap() ==> (bool) TMap::downloadMap(const QString * remoteUrl, const QString * localFileName) + (void) dlgMapper::setDownloadProgress(qint64, qint64) ==> (void) TMap::slot_setDownloadProgress(qint64,qint64) + (void) dlgMapper::cancel() ==> (void) TMap::slot_downloadCancel() + (void) dlgMapper::replyFinished(QNetworkReply *) ==> (void) TMap::slot_replyFinished(QNetworkReply *) * Enhanced download progress indication to also include parsing which can take even more time than download! * Provide means to import local XML map file * Prevent trying to import/download more than one map at a time Renamed: * (void) XMLimport::readAreaNames() ==> XMLimport::readArea() - for consistency with related functions Commented out unused: * (void) XMLimport::readUnknownRoomElement() Note the movement of the map file download code to the TMap class does require making the latter a class with the Q_OBJECT macro (which removes the need for Q_DECLARE_TR_FUNCTIONS as a side-effect!) - though as another side-effect the TMap header needed a boost name specifier added to one identifier as that identifier ("property") exists in both boost and QObject classes!!! YOU MAY NEED TO RUN QMAKE ON THE PROJECT IF THE BUILD SYSTEM DOES NOT PICK UP THE ADDITION OF "Q_OBJECT" TO TMAP CLASS. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: Include missing #include, remove unused return value The absence of this was causing build errors on the Travis C.I. platform! Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: move TMap.h to mudlet_MOC_HDRS to fix CMake build issue As we have made TMap inherit from QOject - to have signal/slot functionality that class needs to be run through Qt's MOC - and to do that with the CMake project/build system it needs to be included in the files included in the projects *_MOC_HDRS {and removed from the *_HDRS} variable. Also spotted a trivial error in that specifying a const return value from method is ineffective and pointless - so removed it from: TMap::retrieveMapFileStats(QString,QString *,int *,int *,int *,int *) Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: clean up TMap initialisation/clearing actions Now restores the customEnvColors set up on initialisation but that was cleared when the map replaced with another one that is loaded {which subsequently replaces that element anyway} or imported {which merely writes over it, replacing any matching keys}. Initialises elements that when inspected on the entry to the constructor proper previously were not being set to a consistent value {booleans/ints/floats}. NOTE: This will now clear the map user data member when the map is cleared if the date is required to be saved when one map is loaded OR IMPORTED over an existing one then the data will need to be saved outside of the map - as is already need for areas and rooms user data! Also comment out or remove unused members/methods: * (void) TMap::getConnectedNodesGreaterThanX(int, int) * (void) TMap::getConnectedNodesSmallerThanX(int, int) * (void) TMap::getConnectedNodesGreaterThanY(int, int) * (void) TMap::getConnectedNodesSmallerThanY(int, int) * (void) TMap::astBreitenAnpassung(int, int) * (void) TMap::astHoehenAnpassung(int, int) * (void) TMap::exportMapToDatabase() * (void) TMap::importMapFromDatabase() * (QVector3D) TMap::span * (int) TMap::mViewArea * (QMap<QString, int>) TMap::pixNameTable * (QMap<int, QPixmap>) TMap::pixTable * (bool) TMap::isToDisplayAuditErrorsToConsole Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * ImplimentationFixes: activate a valid optimisation & remove redundant code Adding a true as a non-default 3rd argument to TRoomDB::addRoom(...) call in XMLimport::readRoom(...) enables a significant optimisation (skips a computationally expensive step when ADDING a room to new map) which dramatically reduces the time to parse an XML map file. It also pointed to the fact that the TRoomDB::entranceMap was already correctly being handled and didn't need to be regenerated in XMLimport::readRoom(...) so the code that was added in a previous commit was redundant and could be removed. A code error in TMap::slot_setDownloadProgress(...) that caused an issue that a reviewer found on test has been fixed - the total download filesize that was being sent by the Qt system signal that is connected to this slot was a -1 value (as IS DOCUMENTED) when the Qt system does NOT know the size of a QNetworkReply in advance of reaching the end of the download was incorrectly handled in a previous commit in this change set. Also found during testing that there is no need for an error message for the QNetworkReply::OperationCanceledError case in TMap::slot_replayFinished(...) as it is already handled in the TMap::slot_downloadCancel() slot. Changed the text put up onto the progress widget during the XML room parsing to be a room count - which is likely more useful and to only do it for every hundredth room - which reduces any delay "wasted" in writing to the display - combined, the effects seem satisfactory IMHO. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: provide error messages for TLuaInterpreter::loadMap(...) Errors for the XML map file importing process as initiated from the Lua command should be returned to that command rather than plastered onto the main profile console - this commit attempts to perform that effect. In testing found that there was no error handling for failure to find or open the nominated file so messages for that have been added as well. Due to the previous program logic the action of creating a mapper widget using the main toolbar button automatically loaded the "default" (the newest Mudlet Map file format file from the currently active profile's map sub-directory). Under some previous situations it looked as though a map might be loaded twice as mudlet::slot_mapper() was called both directly and via signal/slot action. These were resolved by turning that slot into a wrapper that now calls the body of code formerly within to a new method mudlet::createMapper( bool isToLoadDefaultMapFile = true ) with a the default value as an argument. This allows other usages of the body of code to be called directly with a suitable argument, which for the TConsole::loadMap() & TConsole::importMap() and the dlgProfilePreferences::downloadMap() cases is false as they are all do not want the "default" map! Also: * spotted a word "area" missing from an advisory text in TRoom::auditRooms(...). Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: fix minor bug, correct a spelling, undo a few capitalisations Under certain, unanticipated (error with no error message) conditions TLuaInterpreter::loadMap(...) would push both a nil and then a false value onto the stack for return {wrong} but only indicate one value {correct}. The textual matters were found during peer review. off-by: Stephen Lyons <slysven@virginmedia.com>
2016-10-13 09:18:48 +01:00
; // This is the download file case which is a no-op
}
// It is NOW safe to delete the map as we are in a position to load one
mapClear();
XMLimport reader(pHost);
bool result = reader.importPackage(&file);
Enhance: fix map downloading code, add manual XML map importing (#326) * Enhance: fix map downloading code, add manual XML map importing A recent move by I.R.E. to using SSL for their public MUD map URLs broke the ability for Mudlet to download those XML format files. This commit addresses this issue (as mentioned in, but not the original problem referred to in https://bugs.launchpad.net/mudlet/+bug/1427364) the revision to the code does now use "https://www.<MUD URL>/maps/map.xml" as a default name for the I.R.E. MUDS - however the method that initiates the download which was moved to TMap class from the dlgMapper one (see below) is now: (bool) TMap::downloadMap( const QString * remoteUrl = Q_NULLPTR, const QString * localFileName = Q_NULLPTR ) which if not supplied with any arguments behaves as before. However the remoteUrl argument may be given as a full QString including the scheme (the bit of the URL at the beginning before the ':') to override that and a second argument may be used to provide a different name to use for the local file name which if is a RELATIVE pathFileName will be resolved in relation to the profile directory. At present no use is made of this additional functionality but it may be useful for use with other MUDs if they should choose to provide XML map files with other remote locations and scripts using a different local filename. As a long-standing thing that needed doing I have finally provided a means to import a map XML file that - for instance - has already been download. It had been noted that there was no way to read those I.R.E. map files even if they had been obtained from a web browser able to correctly handle https: URLs - now both the TLuaInterpreter::loadMap() and the dlgProfilePreference "loadMap" button {NOT the IRE only "map download" one} will both handle files ending in ".xml" (not case sensitive so it'll work MacOS platforms as well!} For the loadMap case it will be necessary to change the filetype filter on the File Selection dialog to select "xml" files. During testing it became clear to me that it was possible to try and read one or more XML files via several mechanisms simultaneously with "unhelpful" consequences. As well as hitting the dlgProfilePreferences IRE "map download" multiple times, the TLuaInterpreter::loadMap() does NOT block until the map has been loaded and as the import time {running of XMLinport::readPackage(...)} is of significant duration for a large map (a debug, without optimisation, build on my 1.8GHz Quad-core took over two minutes to process the current Achaea map file) it is very possible to get conditions where the same profile will try to run XMLinport::readPackage(...) asynchronously - given that a profile only supports ONE map at a time it was necessary to fit a QMutex to prevent the part of the XMLinport class relating to XML Map files being called from different places in the map related code. This means that if a map download is started further downloads and any local map imports will fail until that first download has completed or aborted. Similarly a local import will prevent a download being started. As a side effect this cures: https://bugs.launchpad.net/mudlet/+bug/852861 - "Map download button starts another download thread if one is already going" The previous XML import code was not adding the rooms that it parsed to the relevant TArea::rooms member - although this would be picked-up and fixed by TMap::audit() later on, this would be accompanied by an error message about every single room. The code now builds up this information while parsing the rooms' details and inserts it so that this does not cause report-able problems during the TMap::audit() execution - the data gathered also allows missing areas to be spotted so that if a room claimed to belong to an area that was not included in the preceding areas' data an unnamed area is created for it. As a consequence of the long time to actually parse an XML map file I have enhanced the progress dialog that was originally used to track the map file download. It is now retained until the file is completely imported and shows more information about the process - importantly it shows during the XMLimport::readRoom(...) the room id being processed - and THAT method is the time/cpu hog so seeing something happening during the time that Mudlet otherwise appears to hang is useful feedback even if it adds a few seconds to the overall duration (may be more than a minute). This dialog is now also used during the other routes that involve reading an XML file and there is now a bit of consistence with the on-screen messages. Whilst inspecting XMLimport class I found there was some uncertain initialisation which I have tidied up. In summary: Added: * (bool) TConsole::importMap(const QString & location) * (void) TRoomDB::setAreaRooms(const int areaId, const QSet<int> & roomIds) * image file mudlet_map_download.png used as icon for download/import progress dialog * (bool) TMap::importMap(QFile & file) * (bool) TMap::readXmlMapFile(QFile & file) * (void) TMap::slot_downloadError(QNetworkReply::NetworkError error) * (void) TMap::reportStringToProgressDialog(const QString text) * (void) TMap::reportProgressToProgressDialog(const int current, const int maximum) Revised: * (int)TLuaInterpreter::loadMap( lua_State * ) * Moved XML map download code from dlgMapper class to the TMap one: + (void) dlgMapper::downloadMap() ==> (bool) TMap::downloadMap(const QString * remoteUrl, const QString * localFileName) + (void) dlgMapper::setDownloadProgress(qint64, qint64) ==> (void) TMap::slot_setDownloadProgress(qint64,qint64) + (void) dlgMapper::cancel() ==> (void) TMap::slot_downloadCancel() + (void) dlgMapper::replyFinished(QNetworkReply *) ==> (void) TMap::slot_replyFinished(QNetworkReply *) * Enhanced download progress indication to also include parsing which can take even more time than download! * Provide means to import local XML map file * Prevent trying to import/download more than one map at a time Renamed: * (void) XMLimport::readAreaNames() ==> XMLimport::readArea() - for consistency with related functions Commented out unused: * (void) XMLimport::readUnknownRoomElement() Note the movement of the map file download code to the TMap class does require making the latter a class with the Q_OBJECT macro (which removes the need for Q_DECLARE_TR_FUNCTIONS as a side-effect!) - though as another side-effect the TMap header needed a boost name specifier added to one identifier as that identifier ("property") exists in both boost and QObject classes!!! YOU MAY NEED TO RUN QMAKE ON THE PROJECT IF THE BUILD SYSTEM DOES NOT PICK UP THE ADDITION OF "Q_OBJECT" TO TMAP CLASS. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: Include missing #include, remove unused return value The absence of this was causing build errors on the Travis C.I. platform! Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: move TMap.h to mudlet_MOC_HDRS to fix CMake build issue As we have made TMap inherit from QOject - to have signal/slot functionality that class needs to be run through Qt's MOC - and to do that with the CMake project/build system it needs to be included in the files included in the projects *_MOC_HDRS {and removed from the *_HDRS} variable. Also spotted a trivial error in that specifying a const return value from method is ineffective and pointless - so removed it from: TMap::retrieveMapFileStats(QString,QString *,int *,int *,int *,int *) Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: clean up TMap initialisation/clearing actions Now restores the customEnvColors set up on initialisation but that was cleared when the map replaced with another one that is loaded {which subsequently replaces that element anyway} or imported {which merely writes over it, replacing any matching keys}. Initialises elements that when inspected on the entry to the constructor proper previously were not being set to a consistent value {booleans/ints/floats}. NOTE: This will now clear the map user data member when the map is cleared if the date is required to be saved when one map is loaded OR IMPORTED over an existing one then the data will need to be saved outside of the map - as is already need for areas and rooms user data! Also comment out or remove unused members/methods: * (void) TMap::getConnectedNodesGreaterThanX(int, int) * (void) TMap::getConnectedNodesSmallerThanX(int, int) * (void) TMap::getConnectedNodesGreaterThanY(int, int) * (void) TMap::getConnectedNodesSmallerThanY(int, int) * (void) TMap::astBreitenAnpassung(int, int) * (void) TMap::astHoehenAnpassung(int, int) * (void) TMap::exportMapToDatabase() * (void) TMap::importMapFromDatabase() * (QVector3D) TMap::span * (int) TMap::mViewArea * (QMap<QString, int>) TMap::pixNameTable * (QMap<int, QPixmap>) TMap::pixTable * (bool) TMap::isToDisplayAuditErrorsToConsole Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * ImplimentationFixes: activate a valid optimisation & remove redundant code Adding a true as a non-default 3rd argument to TRoomDB::addRoom(...) call in XMLimport::readRoom(...) enables a significant optimisation (skips a computationally expensive step when ADDING a room to new map) which dramatically reduces the time to parse an XML map file. It also pointed to the fact that the TRoomDB::entranceMap was already correctly being handled and didn't need to be regenerated in XMLimport::readRoom(...) so the code that was added in a previous commit was redundant and could be removed. A code error in TMap::slot_setDownloadProgress(...) that caused an issue that a reviewer found on test has been fixed - the total download filesize that was being sent by the Qt system signal that is connected to this slot was a -1 value (as IS DOCUMENTED) when the Qt system does NOT know the size of a QNetworkReply in advance of reaching the end of the download was incorrectly handled in a previous commit in this change set. Also found during testing that there is no need for an error message for the QNetworkReply::OperationCanceledError case in TMap::slot_replayFinished(...) as it is already handled in the TMap::slot_downloadCancel() slot. Changed the text put up onto the progress widget during the XML room parsing to be a room count - which is likely more useful and to only do it for every hundredth room - which reduces any delay "wasted" in writing to the display - combined, the effects seem satisfactory IMHO. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: provide error messages for TLuaInterpreter::loadMap(...) Errors for the XML map file importing process as initiated from the Lua command should be returned to that command rather than plastered onto the main profile console - this commit attempts to perform that effect. In testing found that there was no error handling for failure to find or open the nominated file so messages for that have been added as well. Due to the previous program logic the action of creating a mapper widget using the main toolbar button automatically loaded the "default" (the newest Mudlet Map file format file from the currently active profile's map sub-directory). Under some previous situations it looked as though a map might be loaded twice as mudlet::slot_mapper() was called both directly and via signal/slot action. These were resolved by turning that slot into a wrapper that now calls the body of code formerly within to a new method mudlet::createMapper( bool isToLoadDefaultMapFile = true ) with a the default value as an argument. This allows other usages of the body of code to be called directly with a suitable argument, which for the TConsole::loadMap() & TConsole::importMap() and the dlgProfilePreferences::downloadMap() cases is false as they are all do not want the "default" map! Also: * spotted a word "area" missing from an advisory text in TRoom::auditRooms(...). Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: fix minor bug, correct a spelling, undo a few capitalisations Under certain, unanticipated (error with no error message) conditions TLuaInterpreter::loadMap(...) would push both a nil and then a false value onto the stack for return {wrong} but only indicate one value {correct}. The textual matters were found during peer review. off-by: Stephen Lyons <slysven@virginmedia.com>
2016-10-13 09:18:48 +01:00
// probably not needed for the download but might be
// needed for local file case:
mpMapper->mp2dMap->init();
// No need to call audit() as XMLimport::importPackage() does it!
// audit() produces the successful ending [ OK ] message...!
mpMapper->updateAreaComboBox();
if (result) {
Enhance: fix map downloading code, add manual XML map importing (#326) * Enhance: fix map downloading code, add manual XML map importing A recent move by I.R.E. to using SSL for their public MUD map URLs broke the ability for Mudlet to download those XML format files. This commit addresses this issue (as mentioned in, but not the original problem referred to in https://bugs.launchpad.net/mudlet/+bug/1427364) the revision to the code does now use "https://www.<MUD URL>/maps/map.xml" as a default name for the I.R.E. MUDS - however the method that initiates the download which was moved to TMap class from the dlgMapper one (see below) is now: (bool) TMap::downloadMap( const QString * remoteUrl = Q_NULLPTR, const QString * localFileName = Q_NULLPTR ) which if not supplied with any arguments behaves as before. However the remoteUrl argument may be given as a full QString including the scheme (the bit of the URL at the beginning before the ':') to override that and a second argument may be used to provide a different name to use for the local file name which if is a RELATIVE pathFileName will be resolved in relation to the profile directory. At present no use is made of this additional functionality but it may be useful for use with other MUDs if they should choose to provide XML map files with other remote locations and scripts using a different local filename. As a long-standing thing that needed doing I have finally provided a means to import a map XML file that - for instance - has already been download. It had been noted that there was no way to read those I.R.E. map files even if they had been obtained from a web browser able to correctly handle https: URLs - now both the TLuaInterpreter::loadMap() and the dlgProfilePreference "loadMap" button {NOT the IRE only "map download" one} will both handle files ending in ".xml" (not case sensitive so it'll work MacOS platforms as well!} For the loadMap case it will be necessary to change the filetype filter on the File Selection dialog to select "xml" files. During testing it became clear to me that it was possible to try and read one or more XML files via several mechanisms simultaneously with "unhelpful" consequences. As well as hitting the dlgProfilePreferences IRE "map download" multiple times, the TLuaInterpreter::loadMap() does NOT block until the map has been loaded and as the import time {running of XMLinport::readPackage(...)} is of significant duration for a large map (a debug, without optimisation, build on my 1.8GHz Quad-core took over two minutes to process the current Achaea map file) it is very possible to get conditions where the same profile will try to run XMLinport::readPackage(...) asynchronously - given that a profile only supports ONE map at a time it was necessary to fit a QMutex to prevent the part of the XMLinport class relating to XML Map files being called from different places in the map related code. This means that if a map download is started further downloads and any local map imports will fail until that first download has completed or aborted. Similarly a local import will prevent a download being started. As a side effect this cures: https://bugs.launchpad.net/mudlet/+bug/852861 - "Map download button starts another download thread if one is already going" The previous XML import code was not adding the rooms that it parsed to the relevant TArea::rooms member - although this would be picked-up and fixed by TMap::audit() later on, this would be accompanied by an error message about every single room. The code now builds up this information while parsing the rooms' details and inserts it so that this does not cause report-able problems during the TMap::audit() execution - the data gathered also allows missing areas to be spotted so that if a room claimed to belong to an area that was not included in the preceding areas' data an unnamed area is created for it. As a consequence of the long time to actually parse an XML map file I have enhanced the progress dialog that was originally used to track the map file download. It is now retained until the file is completely imported and shows more information about the process - importantly it shows during the XMLimport::readRoom(...) the room id being processed - and THAT method is the time/cpu hog so seeing something happening during the time that Mudlet otherwise appears to hang is useful feedback even if it adds a few seconds to the overall duration (may be more than a minute). This dialog is now also used during the other routes that involve reading an XML file and there is now a bit of consistence with the on-screen messages. Whilst inspecting XMLimport class I found there was some uncertain initialisation which I have tidied up. In summary: Added: * (bool) TConsole::importMap(const QString & location) * (void) TRoomDB::setAreaRooms(const int areaId, const QSet<int> & roomIds) * image file mudlet_map_download.png used as icon for download/import progress dialog * (bool) TMap::importMap(QFile & file) * (bool) TMap::readXmlMapFile(QFile & file) * (void) TMap::slot_downloadError(QNetworkReply::NetworkError error) * (void) TMap::reportStringToProgressDialog(const QString text) * (void) TMap::reportProgressToProgressDialog(const int current, const int maximum) Revised: * (int)TLuaInterpreter::loadMap( lua_State * ) * Moved XML map download code from dlgMapper class to the TMap one: + (void) dlgMapper::downloadMap() ==> (bool) TMap::downloadMap(const QString * remoteUrl, const QString * localFileName) + (void) dlgMapper::setDownloadProgress(qint64, qint64) ==> (void) TMap::slot_setDownloadProgress(qint64,qint64) + (void) dlgMapper::cancel() ==> (void) TMap::slot_downloadCancel() + (void) dlgMapper::replyFinished(QNetworkReply *) ==> (void) TMap::slot_replyFinished(QNetworkReply *) * Enhanced download progress indication to also include parsing which can take even more time than download! * Provide means to import local XML map file * Prevent trying to import/download more than one map at a time Renamed: * (void) XMLimport::readAreaNames() ==> XMLimport::readArea() - for consistency with related functions Commented out unused: * (void) XMLimport::readUnknownRoomElement() Note the movement of the map file download code to the TMap class does require making the latter a class with the Q_OBJECT macro (which removes the need for Q_DECLARE_TR_FUNCTIONS as a side-effect!) - though as another side-effect the TMap header needed a boost name specifier added to one identifier as that identifier ("property") exists in both boost and QObject classes!!! YOU MAY NEED TO RUN QMAKE ON THE PROJECT IF THE BUILD SYSTEM DOES NOT PICK UP THE ADDITION OF "Q_OBJECT" TO TMAP CLASS. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: Include missing #include, remove unused return value The absence of this was causing build errors on the Travis C.I. platform! Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: move TMap.h to mudlet_MOC_HDRS to fix CMake build issue As we have made TMap inherit from QOject - to have signal/slot functionality that class needs to be run through Qt's MOC - and to do that with the CMake project/build system it needs to be included in the files included in the projects *_MOC_HDRS {and removed from the *_HDRS} variable. Also spotted a trivial error in that specifying a const return value from method is ineffective and pointless - so removed it from: TMap::retrieveMapFileStats(QString,QString *,int *,int *,int *,int *) Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: clean up TMap initialisation/clearing actions Now restores the customEnvColors set up on initialisation but that was cleared when the map replaced with another one that is loaded {which subsequently replaces that element anyway} or imported {which merely writes over it, replacing any matching keys}. Initialises elements that when inspected on the entry to the constructor proper previously were not being set to a consistent value {booleans/ints/floats}. NOTE: This will now clear the map user data member when the map is cleared if the date is required to be saved when one map is loaded OR IMPORTED over an existing one then the data will need to be saved outside of the map - as is already need for areas and rooms user data! Also comment out or remove unused members/methods: * (void) TMap::getConnectedNodesGreaterThanX(int, int) * (void) TMap::getConnectedNodesSmallerThanX(int, int) * (void) TMap::getConnectedNodesGreaterThanY(int, int) * (void) TMap::getConnectedNodesSmallerThanY(int, int) * (void) TMap::astBreitenAnpassung(int, int) * (void) TMap::astHoehenAnpassung(int, int) * (void) TMap::exportMapToDatabase() * (void) TMap::importMapFromDatabase() * (QVector3D) TMap::span * (int) TMap::mViewArea * (QMap<QString, int>) TMap::pixNameTable * (QMap<int, QPixmap>) TMap::pixTable * (bool) TMap::isToDisplayAuditErrorsToConsole Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * ImplimentationFixes: activate a valid optimisation & remove redundant code Adding a true as a non-default 3rd argument to TRoomDB::addRoom(...) call in XMLimport::readRoom(...) enables a significant optimisation (skips a computationally expensive step when ADDING a room to new map) which dramatically reduces the time to parse an XML map file. It also pointed to the fact that the TRoomDB::entranceMap was already correctly being handled and didn't need to be regenerated in XMLimport::readRoom(...) so the code that was added in a previous commit was redundant and could be removed. A code error in TMap::slot_setDownloadProgress(...) that caused an issue that a reviewer found on test has been fixed - the total download filesize that was being sent by the Qt system signal that is connected to this slot was a -1 value (as IS DOCUMENTED) when the Qt system does NOT know the size of a QNetworkReply in advance of reaching the end of the download was incorrectly handled in a previous commit in this change set. Also found during testing that there is no need for an error message for the QNetworkReply::OperationCanceledError case in TMap::slot_replayFinished(...) as it is already handled in the TMap::slot_downloadCancel() slot. Changed the text put up onto the progress widget during the XML room parsing to be a room count - which is likely more useful and to only do it for every hundredth room - which reduces any delay "wasted" in writing to the display - combined, the effects seem satisfactory IMHO. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: provide error messages for TLuaInterpreter::loadMap(...) Errors for the XML map file importing process as initiated from the Lua command should be returned to that command rather than plastered onto the main profile console - this commit attempts to perform that effect. In testing found that there was no error handling for failure to find or open the nominated file so messages for that have been added as well. Due to the previous program logic the action of creating a mapper widget using the main toolbar button automatically loaded the "default" (the newest Mudlet Map file format file from the currently active profile's map sub-directory). Under some previous situations it looked as though a map might be loaded twice as mudlet::slot_mapper() was called both directly and via signal/slot action. These were resolved by turning that slot into a wrapper that now calls the body of code formerly within to a new method mudlet::createMapper( bool isToLoadDefaultMapFile = true ) with a the default value as an argument. This allows other usages of the body of code to be called directly with a suitable argument, which for the TConsole::loadMap() & TConsole::importMap() and the dlgProfilePreferences::downloadMap() cases is false as they are all do not want the "default" map! Also: * spotted a word "area" missing from an advisory text in TRoom::auditRooms(...). Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: fix minor bug, correct a spelling, undo a few capitalisations Under certain, unanticipated (error with no error message) conditions TLuaInterpreter::loadMap(...) would push both a nil and then a false value onto the stack for return {wrong} but only indicate one value {correct}. The textual matters were found during peer review. off-by: Stephen Lyons <slysven@virginmedia.com>
2016-10-13 09:18:48 +01:00
mpMapper->resetAreaComboBoxToPlayerRoomArea();
} else {
Enhance: fix map downloading code, add manual XML map importing (#326) * Enhance: fix map downloading code, add manual XML map importing A recent move by I.R.E. to using SSL for their public MUD map URLs broke the ability for Mudlet to download those XML format files. This commit addresses this issue (as mentioned in, but not the original problem referred to in https://bugs.launchpad.net/mudlet/+bug/1427364) the revision to the code does now use "https://www.<MUD URL>/maps/map.xml" as a default name for the I.R.E. MUDS - however the method that initiates the download which was moved to TMap class from the dlgMapper one (see below) is now: (bool) TMap::downloadMap( const QString * remoteUrl = Q_NULLPTR, const QString * localFileName = Q_NULLPTR ) which if not supplied with any arguments behaves as before. However the remoteUrl argument may be given as a full QString including the scheme (the bit of the URL at the beginning before the ':') to override that and a second argument may be used to provide a different name to use for the local file name which if is a RELATIVE pathFileName will be resolved in relation to the profile directory. At present no use is made of this additional functionality but it may be useful for use with other MUDs if they should choose to provide XML map files with other remote locations and scripts using a different local filename. As a long-standing thing that needed doing I have finally provided a means to import a map XML file that - for instance - has already been download. It had been noted that there was no way to read those I.R.E. map files even if they had been obtained from a web browser able to correctly handle https: URLs - now both the TLuaInterpreter::loadMap() and the dlgProfilePreference "loadMap" button {NOT the IRE only "map download" one} will both handle files ending in ".xml" (not case sensitive so it'll work MacOS platforms as well!} For the loadMap case it will be necessary to change the filetype filter on the File Selection dialog to select "xml" files. During testing it became clear to me that it was possible to try and read one or more XML files via several mechanisms simultaneously with "unhelpful" consequences. As well as hitting the dlgProfilePreferences IRE "map download" multiple times, the TLuaInterpreter::loadMap() does NOT block until the map has been loaded and as the import time {running of XMLinport::readPackage(...)} is of significant duration for a large map (a debug, without optimisation, build on my 1.8GHz Quad-core took over two minutes to process the current Achaea map file) it is very possible to get conditions where the same profile will try to run XMLinport::readPackage(...) asynchronously - given that a profile only supports ONE map at a time it was necessary to fit a QMutex to prevent the part of the XMLinport class relating to XML Map files being called from different places in the map related code. This means that if a map download is started further downloads and any local map imports will fail until that first download has completed or aborted. Similarly a local import will prevent a download being started. As a side effect this cures: https://bugs.launchpad.net/mudlet/+bug/852861 - "Map download button starts another download thread if one is already going" The previous XML import code was not adding the rooms that it parsed to the relevant TArea::rooms member - although this would be picked-up and fixed by TMap::audit() later on, this would be accompanied by an error message about every single room. The code now builds up this information while parsing the rooms' details and inserts it so that this does not cause report-able problems during the TMap::audit() execution - the data gathered also allows missing areas to be spotted so that if a room claimed to belong to an area that was not included in the preceding areas' data an unnamed area is created for it. As a consequence of the long time to actually parse an XML map file I have enhanced the progress dialog that was originally used to track the map file download. It is now retained until the file is completely imported and shows more information about the process - importantly it shows during the XMLimport::readRoom(...) the room id being processed - and THAT method is the time/cpu hog so seeing something happening during the time that Mudlet otherwise appears to hang is useful feedback even if it adds a few seconds to the overall duration (may be more than a minute). This dialog is now also used during the other routes that involve reading an XML file and there is now a bit of consistence with the on-screen messages. Whilst inspecting XMLimport class I found there was some uncertain initialisation which I have tidied up. In summary: Added: * (bool) TConsole::importMap(const QString & location) * (void) TRoomDB::setAreaRooms(const int areaId, const QSet<int> & roomIds) * image file mudlet_map_download.png used as icon for download/import progress dialog * (bool) TMap::importMap(QFile & file) * (bool) TMap::readXmlMapFile(QFile & file) * (void) TMap::slot_downloadError(QNetworkReply::NetworkError error) * (void) TMap::reportStringToProgressDialog(const QString text) * (void) TMap::reportProgressToProgressDialog(const int current, const int maximum) Revised: * (int)TLuaInterpreter::loadMap( lua_State * ) * Moved XML map download code from dlgMapper class to the TMap one: + (void) dlgMapper::downloadMap() ==> (bool) TMap::downloadMap(const QString * remoteUrl, const QString * localFileName) + (void) dlgMapper::setDownloadProgress(qint64, qint64) ==> (void) TMap::slot_setDownloadProgress(qint64,qint64) + (void) dlgMapper::cancel() ==> (void) TMap::slot_downloadCancel() + (void) dlgMapper::replyFinished(QNetworkReply *) ==> (void) TMap::slot_replyFinished(QNetworkReply *) * Enhanced download progress indication to also include parsing which can take even more time than download! * Provide means to import local XML map file * Prevent trying to import/download more than one map at a time Renamed: * (void) XMLimport::readAreaNames() ==> XMLimport::readArea() - for consistency with related functions Commented out unused: * (void) XMLimport::readUnknownRoomElement() Note the movement of the map file download code to the TMap class does require making the latter a class with the Q_OBJECT macro (which removes the need for Q_DECLARE_TR_FUNCTIONS as a side-effect!) - though as another side-effect the TMap header needed a boost name specifier added to one identifier as that identifier ("property") exists in both boost and QObject classes!!! YOU MAY NEED TO RUN QMAKE ON THE PROJECT IF THE BUILD SYSTEM DOES NOT PICK UP THE ADDITION OF "Q_OBJECT" TO TMAP CLASS. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: Include missing #include, remove unused return value The absence of this was causing build errors on the Travis C.I. platform! Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: move TMap.h to mudlet_MOC_HDRS to fix CMake build issue As we have made TMap inherit from QOject - to have signal/slot functionality that class needs to be run through Qt's MOC - and to do that with the CMake project/build system it needs to be included in the files included in the projects *_MOC_HDRS {and removed from the *_HDRS} variable. Also spotted a trivial error in that specifying a const return value from method is ineffective and pointless - so removed it from: TMap::retrieveMapFileStats(QString,QString *,int *,int *,int *,int *) Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: clean up TMap initialisation/clearing actions Now restores the customEnvColors set up on initialisation but that was cleared when the map replaced with another one that is loaded {which subsequently replaces that element anyway} or imported {which merely writes over it, replacing any matching keys}. Initialises elements that when inspected on the entry to the constructor proper previously were not being set to a consistent value {booleans/ints/floats}. NOTE: This will now clear the map user data member when the map is cleared if the date is required to be saved when one map is loaded OR IMPORTED over an existing one then the data will need to be saved outside of the map - as is already need for areas and rooms user data! Also comment out or remove unused members/methods: * (void) TMap::getConnectedNodesGreaterThanX(int, int) * (void) TMap::getConnectedNodesSmallerThanX(int, int) * (void) TMap::getConnectedNodesGreaterThanY(int, int) * (void) TMap::getConnectedNodesSmallerThanY(int, int) * (void) TMap::astBreitenAnpassung(int, int) * (void) TMap::astHoehenAnpassung(int, int) * (void) TMap::exportMapToDatabase() * (void) TMap::importMapFromDatabase() * (QVector3D) TMap::span * (int) TMap::mViewArea * (QMap<QString, int>) TMap::pixNameTable * (QMap<int, QPixmap>) TMap::pixTable * (bool) TMap::isToDisplayAuditErrorsToConsole Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * ImplimentationFixes: activate a valid optimisation & remove redundant code Adding a true as a non-default 3rd argument to TRoomDB::addRoom(...) call in XMLimport::readRoom(...) enables a significant optimisation (skips a computationally expensive step when ADDING a room to new map) which dramatically reduces the time to parse an XML map file. It also pointed to the fact that the TRoomDB::entranceMap was already correctly being handled and didn't need to be regenerated in XMLimport::readRoom(...) so the code that was added in a previous commit was redundant and could be removed. A code error in TMap::slot_setDownloadProgress(...) that caused an issue that a reviewer found on test has been fixed - the total download filesize that was being sent by the Qt system signal that is connected to this slot was a -1 value (as IS DOCUMENTED) when the Qt system does NOT know the size of a QNetworkReply in advance of reaching the end of the download was incorrectly handled in a previous commit in this change set. Also found during testing that there is no need for an error message for the QNetworkReply::OperationCanceledError case in TMap::slot_replayFinished(...) as it is already handled in the TMap::slot_downloadCancel() slot. Changed the text put up onto the progress widget during the XML room parsing to be a room count - which is likely more useful and to only do it for every hundredth room - which reduces any delay "wasted" in writing to the display - combined, the effects seem satisfactory IMHO. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: provide error messages for TLuaInterpreter::loadMap(...) Errors for the XML map file importing process as initiated from the Lua command should be returned to that command rather than plastered onto the main profile console - this commit attempts to perform that effect. In testing found that there was no error handling for failure to find or open the nominated file so messages for that have been added as well. Due to the previous program logic the action of creating a mapper widget using the main toolbar button automatically loaded the "default" (the newest Mudlet Map file format file from the currently active profile's map sub-directory). Under some previous situations it looked as though a map might be loaded twice as mudlet::slot_mapper() was called both directly and via signal/slot action. These were resolved by turning that slot into a wrapper that now calls the body of code formerly within to a new method mudlet::createMapper( bool isToLoadDefaultMapFile = true ) with a the default value as an argument. This allows other usages of the body of code to be called directly with a suitable argument, which for the TConsole::loadMap() & TConsole::importMap() and the dlgProfilePreferences::downloadMap() cases is false as they are all do not want the "default" map! Also: * spotted a word "area" missing from an advisory text in TRoom::auditRooms(...). Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: fix minor bug, correct a spelling, undo a few capitalisations Under certain, unanticipated (error with no error message) conditions TLuaInterpreter::loadMap(...) would push both a nil and then a false value onto the stack for return {wrong} but only indicate one value {correct}. The textual matters were found during peer review. off-by: Stephen Lyons <slysven@virginmedia.com>
2016-10-13 09:18:48 +01:00
// Failed...
if (errMsg) {
*errMsg = tr("loadMap: failure to import XML map file, further information may be available\n"
"in main console!");
Enhance: fix map downloading code, add manual XML map importing (#326) * Enhance: fix map downloading code, add manual XML map importing A recent move by I.R.E. to using SSL for their public MUD map URLs broke the ability for Mudlet to download those XML format files. This commit addresses this issue (as mentioned in, but not the original problem referred to in https://bugs.launchpad.net/mudlet/+bug/1427364) the revision to the code does now use "https://www.<MUD URL>/maps/map.xml" as a default name for the I.R.E. MUDS - however the method that initiates the download which was moved to TMap class from the dlgMapper one (see below) is now: (bool) TMap::downloadMap( const QString * remoteUrl = Q_NULLPTR, const QString * localFileName = Q_NULLPTR ) which if not supplied with any arguments behaves as before. However the remoteUrl argument may be given as a full QString including the scheme (the bit of the URL at the beginning before the ':') to override that and a second argument may be used to provide a different name to use for the local file name which if is a RELATIVE pathFileName will be resolved in relation to the profile directory. At present no use is made of this additional functionality but it may be useful for use with other MUDs if they should choose to provide XML map files with other remote locations and scripts using a different local filename. As a long-standing thing that needed doing I have finally provided a means to import a map XML file that - for instance - has already been download. It had been noted that there was no way to read those I.R.E. map files even if they had been obtained from a web browser able to correctly handle https: URLs - now both the TLuaInterpreter::loadMap() and the dlgProfilePreference "loadMap" button {NOT the IRE only "map download" one} will both handle files ending in ".xml" (not case sensitive so it'll work MacOS platforms as well!} For the loadMap case it will be necessary to change the filetype filter on the File Selection dialog to select "xml" files. During testing it became clear to me that it was possible to try and read one or more XML files via several mechanisms simultaneously with "unhelpful" consequences. As well as hitting the dlgProfilePreferences IRE "map download" multiple times, the TLuaInterpreter::loadMap() does NOT block until the map has been loaded and as the import time {running of XMLinport::readPackage(...)} is of significant duration for a large map (a debug, without optimisation, build on my 1.8GHz Quad-core took over two minutes to process the current Achaea map file) it is very possible to get conditions where the same profile will try to run XMLinport::readPackage(...) asynchronously - given that a profile only supports ONE map at a time it was necessary to fit a QMutex to prevent the part of the XMLinport class relating to XML Map files being called from different places in the map related code. This means that if a map download is started further downloads and any local map imports will fail until that first download has completed or aborted. Similarly a local import will prevent a download being started. As a side effect this cures: https://bugs.launchpad.net/mudlet/+bug/852861 - "Map download button starts another download thread if one is already going" The previous XML import code was not adding the rooms that it parsed to the relevant TArea::rooms member - although this would be picked-up and fixed by TMap::audit() later on, this would be accompanied by an error message about every single room. The code now builds up this information while parsing the rooms' details and inserts it so that this does not cause report-able problems during the TMap::audit() execution - the data gathered also allows missing areas to be spotted so that if a room claimed to belong to an area that was not included in the preceding areas' data an unnamed area is created for it. As a consequence of the long time to actually parse an XML map file I have enhanced the progress dialog that was originally used to track the map file download. It is now retained until the file is completely imported and shows more information about the process - importantly it shows during the XMLimport::readRoom(...) the room id being processed - and THAT method is the time/cpu hog so seeing something happening during the time that Mudlet otherwise appears to hang is useful feedback even if it adds a few seconds to the overall duration (may be more than a minute). This dialog is now also used during the other routes that involve reading an XML file and there is now a bit of consistence with the on-screen messages. Whilst inspecting XMLimport class I found there was some uncertain initialisation which I have tidied up. In summary: Added: * (bool) TConsole::importMap(const QString & location) * (void) TRoomDB::setAreaRooms(const int areaId, const QSet<int> & roomIds) * image file mudlet_map_download.png used as icon for download/import progress dialog * (bool) TMap::importMap(QFile & file) * (bool) TMap::readXmlMapFile(QFile & file) * (void) TMap::slot_downloadError(QNetworkReply::NetworkError error) * (void) TMap::reportStringToProgressDialog(const QString text) * (void) TMap::reportProgressToProgressDialog(const int current, const int maximum) Revised: * (int)TLuaInterpreter::loadMap( lua_State * ) * Moved XML map download code from dlgMapper class to the TMap one: + (void) dlgMapper::downloadMap() ==> (bool) TMap::downloadMap(const QString * remoteUrl, const QString * localFileName) + (void) dlgMapper::setDownloadProgress(qint64, qint64) ==> (void) TMap::slot_setDownloadProgress(qint64,qint64) + (void) dlgMapper::cancel() ==> (void) TMap::slot_downloadCancel() + (void) dlgMapper::replyFinished(QNetworkReply *) ==> (void) TMap::slot_replyFinished(QNetworkReply *) * Enhanced download progress indication to also include parsing which can take even more time than download! * Provide means to import local XML map file * Prevent trying to import/download more than one map at a time Renamed: * (void) XMLimport::readAreaNames() ==> XMLimport::readArea() - for consistency with related functions Commented out unused: * (void) XMLimport::readUnknownRoomElement() Note the movement of the map file download code to the TMap class does require making the latter a class with the Q_OBJECT macro (which removes the need for Q_DECLARE_TR_FUNCTIONS as a side-effect!) - though as another side-effect the TMap header needed a boost name specifier added to one identifier as that identifier ("property") exists in both boost and QObject classes!!! YOU MAY NEED TO RUN QMAKE ON THE PROJECT IF THE BUILD SYSTEM DOES NOT PICK UP THE ADDITION OF "Q_OBJECT" TO TMAP CLASS. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: Include missing #include, remove unused return value The absence of this was causing build errors on the Travis C.I. platform! Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: move TMap.h to mudlet_MOC_HDRS to fix CMake build issue As we have made TMap inherit from QOject - to have signal/slot functionality that class needs to be run through Qt's MOC - and to do that with the CMake project/build system it needs to be included in the files included in the projects *_MOC_HDRS {and removed from the *_HDRS} variable. Also spotted a trivial error in that specifying a const return value from method is ineffective and pointless - so removed it from: TMap::retrieveMapFileStats(QString,QString *,int *,int *,int *,int *) Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: clean up TMap initialisation/clearing actions Now restores the customEnvColors set up on initialisation but that was cleared when the map replaced with another one that is loaded {which subsequently replaces that element anyway} or imported {which merely writes over it, replacing any matching keys}. Initialises elements that when inspected on the entry to the constructor proper previously were not being set to a consistent value {booleans/ints/floats}. NOTE: This will now clear the map user data member when the map is cleared if the date is required to be saved when one map is loaded OR IMPORTED over an existing one then the data will need to be saved outside of the map - as is already need for areas and rooms user data! Also comment out or remove unused members/methods: * (void) TMap::getConnectedNodesGreaterThanX(int, int) * (void) TMap::getConnectedNodesSmallerThanX(int, int) * (void) TMap::getConnectedNodesGreaterThanY(int, int) * (void) TMap::getConnectedNodesSmallerThanY(int, int) * (void) TMap::astBreitenAnpassung(int, int) * (void) TMap::astHoehenAnpassung(int, int) * (void) TMap::exportMapToDatabase() * (void) TMap::importMapFromDatabase() * (QVector3D) TMap::span * (int) TMap::mViewArea * (QMap<QString, int>) TMap::pixNameTable * (QMap<int, QPixmap>) TMap::pixTable * (bool) TMap::isToDisplayAuditErrorsToConsole Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * ImplimentationFixes: activate a valid optimisation & remove redundant code Adding a true as a non-default 3rd argument to TRoomDB::addRoom(...) call in XMLimport::readRoom(...) enables a significant optimisation (skips a computationally expensive step when ADDING a room to new map) which dramatically reduces the time to parse an XML map file. It also pointed to the fact that the TRoomDB::entranceMap was already correctly being handled and didn't need to be regenerated in XMLimport::readRoom(...) so the code that was added in a previous commit was redundant and could be removed. A code error in TMap::slot_setDownloadProgress(...) that caused an issue that a reviewer found on test has been fixed - the total download filesize that was being sent by the Qt system signal that is connected to this slot was a -1 value (as IS DOCUMENTED) when the Qt system does NOT know the size of a QNetworkReply in advance of reaching the end of the download was incorrectly handled in a previous commit in this change set. Also found during testing that there is no need for an error message for the QNetworkReply::OperationCanceledError case in TMap::slot_replayFinished(...) as it is already handled in the TMap::slot_downloadCancel() slot. Changed the text put up onto the progress widget during the XML room parsing to be a room count - which is likely more useful and to only do it for every hundredth room - which reduces any delay "wasted" in writing to the display - combined, the effects seem satisfactory IMHO. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: provide error messages for TLuaInterpreter::loadMap(...) Errors for the XML map file importing process as initiated from the Lua command should be returned to that command rather than plastered onto the main profile console - this commit attempts to perform that effect. In testing found that there was no error handling for failure to find or open the nominated file so messages for that have been added as well. Due to the previous program logic the action of creating a mapper widget using the main toolbar button automatically loaded the "default" (the newest Mudlet Map file format file from the currently active profile's map sub-directory). Under some previous situations it looked as though a map might be loaded twice as mudlet::slot_mapper() was called both directly and via signal/slot action. These were resolved by turning that slot into a wrapper that now calls the body of code formerly within to a new method mudlet::createMapper( bool isToLoadDefaultMapFile = true ) with a the default value as an argument. This allows other usages of the body of code to be called directly with a suitable argument, which for the TConsole::loadMap() & TConsole::importMap() and the dlgProfilePreferences::downloadMap() cases is false as they are all do not want the "default" map! Also: * spotted a word "area" missing from an advisory text in TRoom::auditRooms(...). Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: fix minor bug, correct a spelling, undo a few capitalisations Under certain, unanticipated (error with no error message) conditions TLuaInterpreter::loadMap(...) would push both a nil and then a false value onto the stack for return {wrong} but only indicate one value {correct}. The textual matters were found during peer review. off-by: Stephen Lyons <slysven@virginmedia.com>
2016-10-13 09:18:48 +01:00
}
}
if (isLocalImport) {
Enhance: fix map downloading code, add manual XML map importing (#326) * Enhance: fix map downloading code, add manual XML map importing A recent move by I.R.E. to using SSL for their public MUD map URLs broke the ability for Mudlet to download those XML format files. This commit addresses this issue (as mentioned in, but not the original problem referred to in https://bugs.launchpad.net/mudlet/+bug/1427364) the revision to the code does now use "https://www.<MUD URL>/maps/map.xml" as a default name for the I.R.E. MUDS - however the method that initiates the download which was moved to TMap class from the dlgMapper one (see below) is now: (bool) TMap::downloadMap( const QString * remoteUrl = Q_NULLPTR, const QString * localFileName = Q_NULLPTR ) which if not supplied with any arguments behaves as before. However the remoteUrl argument may be given as a full QString including the scheme (the bit of the URL at the beginning before the ':') to override that and a second argument may be used to provide a different name to use for the local file name which if is a RELATIVE pathFileName will be resolved in relation to the profile directory. At present no use is made of this additional functionality but it may be useful for use with other MUDs if they should choose to provide XML map files with other remote locations and scripts using a different local filename. As a long-standing thing that needed doing I have finally provided a means to import a map XML file that - for instance - has already been download. It had been noted that there was no way to read those I.R.E. map files even if they had been obtained from a web browser able to correctly handle https: URLs - now both the TLuaInterpreter::loadMap() and the dlgProfilePreference "loadMap" button {NOT the IRE only "map download" one} will both handle files ending in ".xml" (not case sensitive so it'll work MacOS platforms as well!} For the loadMap case it will be necessary to change the filetype filter on the File Selection dialog to select "xml" files. During testing it became clear to me that it was possible to try and read one or more XML files via several mechanisms simultaneously with "unhelpful" consequences. As well as hitting the dlgProfilePreferences IRE "map download" multiple times, the TLuaInterpreter::loadMap() does NOT block until the map has been loaded and as the import time {running of XMLinport::readPackage(...)} is of significant duration for a large map (a debug, without optimisation, build on my 1.8GHz Quad-core took over two minutes to process the current Achaea map file) it is very possible to get conditions where the same profile will try to run XMLinport::readPackage(...) asynchronously - given that a profile only supports ONE map at a time it was necessary to fit a QMutex to prevent the part of the XMLinport class relating to XML Map files being called from different places in the map related code. This means that if a map download is started further downloads and any local map imports will fail until that first download has completed or aborted. Similarly a local import will prevent a download being started. As a side effect this cures: https://bugs.launchpad.net/mudlet/+bug/852861 - "Map download button starts another download thread if one is already going" The previous XML import code was not adding the rooms that it parsed to the relevant TArea::rooms member - although this would be picked-up and fixed by TMap::audit() later on, this would be accompanied by an error message about every single room. The code now builds up this information while parsing the rooms' details and inserts it so that this does not cause report-able problems during the TMap::audit() execution - the data gathered also allows missing areas to be spotted so that if a room claimed to belong to an area that was not included in the preceding areas' data an unnamed area is created for it. As a consequence of the long time to actually parse an XML map file I have enhanced the progress dialog that was originally used to track the map file download. It is now retained until the file is completely imported and shows more information about the process - importantly it shows during the XMLimport::readRoom(...) the room id being processed - and THAT method is the time/cpu hog so seeing something happening during the time that Mudlet otherwise appears to hang is useful feedback even if it adds a few seconds to the overall duration (may be more than a minute). This dialog is now also used during the other routes that involve reading an XML file and there is now a bit of consistence with the on-screen messages. Whilst inspecting XMLimport class I found there was some uncertain initialisation which I have tidied up. In summary: Added: * (bool) TConsole::importMap(const QString & location) * (void) TRoomDB::setAreaRooms(const int areaId, const QSet<int> & roomIds) * image file mudlet_map_download.png used as icon for download/import progress dialog * (bool) TMap::importMap(QFile & file) * (bool) TMap::readXmlMapFile(QFile & file) * (void) TMap::slot_downloadError(QNetworkReply::NetworkError error) * (void) TMap::reportStringToProgressDialog(const QString text) * (void) TMap::reportProgressToProgressDialog(const int current, const int maximum) Revised: * (int)TLuaInterpreter::loadMap( lua_State * ) * Moved XML map download code from dlgMapper class to the TMap one: + (void) dlgMapper::downloadMap() ==> (bool) TMap::downloadMap(const QString * remoteUrl, const QString * localFileName) + (void) dlgMapper::setDownloadProgress(qint64, qint64) ==> (void) TMap::slot_setDownloadProgress(qint64,qint64) + (void) dlgMapper::cancel() ==> (void) TMap::slot_downloadCancel() + (void) dlgMapper::replyFinished(QNetworkReply *) ==> (void) TMap::slot_replyFinished(QNetworkReply *) * Enhanced download progress indication to also include parsing which can take even more time than download! * Provide means to import local XML map file * Prevent trying to import/download more than one map at a time Renamed: * (void) XMLimport::readAreaNames() ==> XMLimport::readArea() - for consistency with related functions Commented out unused: * (void) XMLimport::readUnknownRoomElement() Note the movement of the map file download code to the TMap class does require making the latter a class with the Q_OBJECT macro (which removes the need for Q_DECLARE_TR_FUNCTIONS as a side-effect!) - though as another side-effect the TMap header needed a boost name specifier added to one identifier as that identifier ("property") exists in both boost and QObject classes!!! YOU MAY NEED TO RUN QMAKE ON THE PROJECT IF THE BUILD SYSTEM DOES NOT PICK UP THE ADDITION OF "Q_OBJECT" TO TMAP CLASS. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: Include missing #include, remove unused return value The absence of this was causing build errors on the Travis C.I. platform! Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: move TMap.h to mudlet_MOC_HDRS to fix CMake build issue As we have made TMap inherit from QOject - to have signal/slot functionality that class needs to be run through Qt's MOC - and to do that with the CMake project/build system it needs to be included in the files included in the projects *_MOC_HDRS {and removed from the *_HDRS} variable. Also spotted a trivial error in that specifying a const return value from method is ineffective and pointless - so removed it from: TMap::retrieveMapFileStats(QString,QString *,int *,int *,int *,int *) Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: clean up TMap initialisation/clearing actions Now restores the customEnvColors set up on initialisation but that was cleared when the map replaced with another one that is loaded {which subsequently replaces that element anyway} or imported {which merely writes over it, replacing any matching keys}. Initialises elements that when inspected on the entry to the constructor proper previously were not being set to a consistent value {booleans/ints/floats}. NOTE: This will now clear the map user data member when the map is cleared if the date is required to be saved when one map is loaded OR IMPORTED over an existing one then the data will need to be saved outside of the map - as is already need for areas and rooms user data! Also comment out or remove unused members/methods: * (void) TMap::getConnectedNodesGreaterThanX(int, int) * (void) TMap::getConnectedNodesSmallerThanX(int, int) * (void) TMap::getConnectedNodesGreaterThanY(int, int) * (void) TMap::getConnectedNodesSmallerThanY(int, int) * (void) TMap::astBreitenAnpassung(int, int) * (void) TMap::astHoehenAnpassung(int, int) * (void) TMap::exportMapToDatabase() * (void) TMap::importMapFromDatabase() * (QVector3D) TMap::span * (int) TMap::mViewArea * (QMap<QString, int>) TMap::pixNameTable * (QMap<int, QPixmap>) TMap::pixTable * (bool) TMap::isToDisplayAuditErrorsToConsole Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * ImplimentationFixes: activate a valid optimisation & remove redundant code Adding a true as a non-default 3rd argument to TRoomDB::addRoom(...) call in XMLimport::readRoom(...) enables a significant optimisation (skips a computationally expensive step when ADDING a room to new map) which dramatically reduces the time to parse an XML map file. It also pointed to the fact that the TRoomDB::entranceMap was already correctly being handled and didn't need to be regenerated in XMLimport::readRoom(...) so the code that was added in a previous commit was redundant and could be removed. A code error in TMap::slot_setDownloadProgress(...) that caused an issue that a reviewer found on test has been fixed - the total download filesize that was being sent by the Qt system signal that is connected to this slot was a -1 value (as IS DOCUMENTED) when the Qt system does NOT know the size of a QNetworkReply in advance of reaching the end of the download was incorrectly handled in a previous commit in this change set. Also found during testing that there is no need for an error message for the QNetworkReply::OperationCanceledError case in TMap::slot_replayFinished(...) as it is already handled in the TMap::slot_downloadCancel() slot. Changed the text put up onto the progress widget during the XML room parsing to be a room count - which is likely more useful and to only do it for every hundredth room - which reduces any delay "wasted" in writing to the display - combined, the effects seem satisfactory IMHO. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: provide error messages for TLuaInterpreter::loadMap(...) Errors for the XML map file importing process as initiated from the Lua command should be returned to that command rather than plastered onto the main profile console - this commit attempts to perform that effect. In testing found that there was no error handling for failure to find or open the nominated file so messages for that have been added as well. Due to the previous program logic the action of creating a mapper widget using the main toolbar button automatically loaded the "default" (the newest Mudlet Map file format file from the currently active profile's map sub-directory). Under some previous situations it looked as though a map might be loaded twice as mudlet::slot_mapper() was called both directly and via signal/slot action. These were resolved by turning that slot into a wrapper that now calls the body of code formerly within to a new method mudlet::createMapper( bool isToLoadDefaultMapFile = true ) with a the default value as an argument. This allows other usages of the body of code to be called directly with a suitable argument, which for the TConsole::loadMap() & TConsole::importMap() and the dlgProfilePreferences::downloadMap() cases is false as they are all do not want the "default" map! Also: * spotted a word "area" missing from an advisory text in TRoom::auditRooms(...). Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: fix minor bug, correct a spelling, undo a few capitalisations Under certain, unanticipated (error with no error message) conditions TLuaInterpreter::loadMap(...) would push both a nil and then a false value onto the stack for return {wrong} but only indicate one value {correct}. The textual matters were found during peer review. off-by: Stephen Lyons <slysven@virginmedia.com>
2016-10-13 09:18:48 +01:00
// clean-up
mpProgressDialog->deleteLater();
mpProgressDialog = nullptr;
Enhance: fix map downloading code, add manual XML map importing (#326) * Enhance: fix map downloading code, add manual XML map importing A recent move by I.R.E. to using SSL for their public MUD map URLs broke the ability for Mudlet to download those XML format files. This commit addresses this issue (as mentioned in, but not the original problem referred to in https://bugs.launchpad.net/mudlet/+bug/1427364) the revision to the code does now use "https://www.<MUD URL>/maps/map.xml" as a default name for the I.R.E. MUDS - however the method that initiates the download which was moved to TMap class from the dlgMapper one (see below) is now: (bool) TMap::downloadMap( const QString * remoteUrl = Q_NULLPTR, const QString * localFileName = Q_NULLPTR ) which if not supplied with any arguments behaves as before. However the remoteUrl argument may be given as a full QString including the scheme (the bit of the URL at the beginning before the ':') to override that and a second argument may be used to provide a different name to use for the local file name which if is a RELATIVE pathFileName will be resolved in relation to the profile directory. At present no use is made of this additional functionality but it may be useful for use with other MUDs if they should choose to provide XML map files with other remote locations and scripts using a different local filename. As a long-standing thing that needed doing I have finally provided a means to import a map XML file that - for instance - has already been download. It had been noted that there was no way to read those I.R.E. map files even if they had been obtained from a web browser able to correctly handle https: URLs - now both the TLuaInterpreter::loadMap() and the dlgProfilePreference "loadMap" button {NOT the IRE only "map download" one} will both handle files ending in ".xml" (not case sensitive so it'll work MacOS platforms as well!} For the loadMap case it will be necessary to change the filetype filter on the File Selection dialog to select "xml" files. During testing it became clear to me that it was possible to try and read one or more XML files via several mechanisms simultaneously with "unhelpful" consequences. As well as hitting the dlgProfilePreferences IRE "map download" multiple times, the TLuaInterpreter::loadMap() does NOT block until the map has been loaded and as the import time {running of XMLinport::readPackage(...)} is of significant duration for a large map (a debug, without optimisation, build on my 1.8GHz Quad-core took over two minutes to process the current Achaea map file) it is very possible to get conditions where the same profile will try to run XMLinport::readPackage(...) asynchronously - given that a profile only supports ONE map at a time it was necessary to fit a QMutex to prevent the part of the XMLinport class relating to XML Map files being called from different places in the map related code. This means that if a map download is started further downloads and any local map imports will fail until that first download has completed or aborted. Similarly a local import will prevent a download being started. As a side effect this cures: https://bugs.launchpad.net/mudlet/+bug/852861 - "Map download button starts another download thread if one is already going" The previous XML import code was not adding the rooms that it parsed to the relevant TArea::rooms member - although this would be picked-up and fixed by TMap::audit() later on, this would be accompanied by an error message about every single room. The code now builds up this information while parsing the rooms' details and inserts it so that this does not cause report-able problems during the TMap::audit() execution - the data gathered also allows missing areas to be spotted so that if a room claimed to belong to an area that was not included in the preceding areas' data an unnamed area is created for it. As a consequence of the long time to actually parse an XML map file I have enhanced the progress dialog that was originally used to track the map file download. It is now retained until the file is completely imported and shows more information about the process - importantly it shows during the XMLimport::readRoom(...) the room id being processed - and THAT method is the time/cpu hog so seeing something happening during the time that Mudlet otherwise appears to hang is useful feedback even if it adds a few seconds to the overall duration (may be more than a minute). This dialog is now also used during the other routes that involve reading an XML file and there is now a bit of consistence with the on-screen messages. Whilst inspecting XMLimport class I found there was some uncertain initialisation which I have tidied up. In summary: Added: * (bool) TConsole::importMap(const QString & location) * (void) TRoomDB::setAreaRooms(const int areaId, const QSet<int> & roomIds) * image file mudlet_map_download.png used as icon for download/import progress dialog * (bool) TMap::importMap(QFile & file) * (bool) TMap::readXmlMapFile(QFile & file) * (void) TMap::slot_downloadError(QNetworkReply::NetworkError error) * (void) TMap::reportStringToProgressDialog(const QString text) * (void) TMap::reportProgressToProgressDialog(const int current, const int maximum) Revised: * (int)TLuaInterpreter::loadMap( lua_State * ) * Moved XML map download code from dlgMapper class to the TMap one: + (void) dlgMapper::downloadMap() ==> (bool) TMap::downloadMap(const QString * remoteUrl, const QString * localFileName) + (void) dlgMapper::setDownloadProgress(qint64, qint64) ==> (void) TMap::slot_setDownloadProgress(qint64,qint64) + (void) dlgMapper::cancel() ==> (void) TMap::slot_downloadCancel() + (void) dlgMapper::replyFinished(QNetworkReply *) ==> (void) TMap::slot_replyFinished(QNetworkReply *) * Enhanced download progress indication to also include parsing which can take even more time than download! * Provide means to import local XML map file * Prevent trying to import/download more than one map at a time Renamed: * (void) XMLimport::readAreaNames() ==> XMLimport::readArea() - for consistency with related functions Commented out unused: * (void) XMLimport::readUnknownRoomElement() Note the movement of the map file download code to the TMap class does require making the latter a class with the Q_OBJECT macro (which removes the need for Q_DECLARE_TR_FUNCTIONS as a side-effect!) - though as another side-effect the TMap header needed a boost name specifier added to one identifier as that identifier ("property") exists in both boost and QObject classes!!! YOU MAY NEED TO RUN QMAKE ON THE PROJECT IF THE BUILD SYSTEM DOES NOT PICK UP THE ADDITION OF "Q_OBJECT" TO TMAP CLASS. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: Include missing #include, remove unused return value The absence of this was causing build errors on the Travis C.I. platform! Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: move TMap.h to mudlet_MOC_HDRS to fix CMake build issue As we have made TMap inherit from QOject - to have signal/slot functionality that class needs to be run through Qt's MOC - and to do that with the CMake project/build system it needs to be included in the files included in the projects *_MOC_HDRS {and removed from the *_HDRS} variable. Also spotted a trivial error in that specifying a const return value from method is ineffective and pointless - so removed it from: TMap::retrieveMapFileStats(QString,QString *,int *,int *,int *,int *) Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: clean up TMap initialisation/clearing actions Now restores the customEnvColors set up on initialisation but that was cleared when the map replaced with another one that is loaded {which subsequently replaces that element anyway} or imported {which merely writes over it, replacing any matching keys}. Initialises elements that when inspected on the entry to the constructor proper previously were not being set to a consistent value {booleans/ints/floats}. NOTE: This will now clear the map user data member when the map is cleared if the date is required to be saved when one map is loaded OR IMPORTED over an existing one then the data will need to be saved outside of the map - as is already need for areas and rooms user data! Also comment out or remove unused members/methods: * (void) TMap::getConnectedNodesGreaterThanX(int, int) * (void) TMap::getConnectedNodesSmallerThanX(int, int) * (void) TMap::getConnectedNodesGreaterThanY(int, int) * (void) TMap::getConnectedNodesSmallerThanY(int, int) * (void) TMap::astBreitenAnpassung(int, int) * (void) TMap::astHoehenAnpassung(int, int) * (void) TMap::exportMapToDatabase() * (void) TMap::importMapFromDatabase() * (QVector3D) TMap::span * (int) TMap::mViewArea * (QMap<QString, int>) TMap::pixNameTable * (QMap<int, QPixmap>) TMap::pixTable * (bool) TMap::isToDisplayAuditErrorsToConsole Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * ImplimentationFixes: activate a valid optimisation & remove redundant code Adding a true as a non-default 3rd argument to TRoomDB::addRoom(...) call in XMLimport::readRoom(...) enables a significant optimisation (skips a computationally expensive step when ADDING a room to new map) which dramatically reduces the time to parse an XML map file. It also pointed to the fact that the TRoomDB::entranceMap was already correctly being handled and didn't need to be regenerated in XMLimport::readRoom(...) so the code that was added in a previous commit was redundant and could be removed. A code error in TMap::slot_setDownloadProgress(...) that caused an issue that a reviewer found on test has been fixed - the total download filesize that was being sent by the Qt system signal that is connected to this slot was a -1 value (as IS DOCUMENTED) when the Qt system does NOT know the size of a QNetworkReply in advance of reaching the end of the download was incorrectly handled in a previous commit in this change set. Also found during testing that there is no need for an error message for the QNetworkReply::OperationCanceledError case in TMap::slot_replayFinished(...) as it is already handled in the TMap::slot_downloadCancel() slot. Changed the text put up onto the progress widget during the XML room parsing to be a room count - which is likely more useful and to only do it for every hundredth room - which reduces any delay "wasted" in writing to the display - combined, the effects seem satisfactory IMHO. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: provide error messages for TLuaInterpreter::loadMap(...) Errors for the XML map file importing process as initiated from the Lua command should be returned to that command rather than plastered onto the main profile console - this commit attempts to perform that effect. In testing found that there was no error handling for failure to find or open the nominated file so messages for that have been added as well. Due to the previous program logic the action of creating a mapper widget using the main toolbar button automatically loaded the "default" (the newest Mudlet Map file format file from the currently active profile's map sub-directory). Under some previous situations it looked as though a map might be loaded twice as mudlet::slot_mapper() was called both directly and via signal/slot action. These were resolved by turning that slot into a wrapper that now calls the body of code formerly within to a new method mudlet::createMapper( bool isToLoadDefaultMapFile = true ) with a the default value as an argument. This allows other usages of the body of code to be called directly with a suitable argument, which for the TConsole::loadMap() & TConsole::importMap() and the dlgProfilePreferences::downloadMap() cases is false as they are all do not want the "default" map! Also: * spotted a word "area" missing from an advisory text in TRoom::auditRooms(...). Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: fix minor bug, correct a spelling, undo a few capitalisations Under certain, unanticipated (error with no error message) conditions TLuaInterpreter::loadMap(...) would push both a nil and then a false value onto the stack for return {wrong} but only indicate one value {correct}. The textual matters were found during peer review. off-by: Stephen Lyons <slysven@virginmedia.com>
2016-10-13 09:18:48 +01:00
}
mpMapper->show();
return result;
}
void TMap::slot_setDownloadProgress(qint64 got, qint64 tot)
Enhance: fix map downloading code, add manual XML map importing (#326) * Enhance: fix map downloading code, add manual XML map importing A recent move by I.R.E. to using SSL for their public MUD map URLs broke the ability for Mudlet to download those XML format files. This commit addresses this issue (as mentioned in, but not the original problem referred to in https://bugs.launchpad.net/mudlet/+bug/1427364) the revision to the code does now use "https://www.<MUD URL>/maps/map.xml" as a default name for the I.R.E. MUDS - however the method that initiates the download which was moved to TMap class from the dlgMapper one (see below) is now: (bool) TMap::downloadMap( const QString * remoteUrl = Q_NULLPTR, const QString * localFileName = Q_NULLPTR ) which if not supplied with any arguments behaves as before. However the remoteUrl argument may be given as a full QString including the scheme (the bit of the URL at the beginning before the ':') to override that and a second argument may be used to provide a different name to use for the local file name which if is a RELATIVE pathFileName will be resolved in relation to the profile directory. At present no use is made of this additional functionality but it may be useful for use with other MUDs if they should choose to provide XML map files with other remote locations and scripts using a different local filename. As a long-standing thing that needed doing I have finally provided a means to import a map XML file that - for instance - has already been download. It had been noted that there was no way to read those I.R.E. map files even if they had been obtained from a web browser able to correctly handle https: URLs - now both the TLuaInterpreter::loadMap() and the dlgProfilePreference "loadMap" button {NOT the IRE only "map download" one} will both handle files ending in ".xml" (not case sensitive so it'll work MacOS platforms as well!} For the loadMap case it will be necessary to change the filetype filter on the File Selection dialog to select "xml" files. During testing it became clear to me that it was possible to try and read one or more XML files via several mechanisms simultaneously with "unhelpful" consequences. As well as hitting the dlgProfilePreferences IRE "map download" multiple times, the TLuaInterpreter::loadMap() does NOT block until the map has been loaded and as the import time {running of XMLinport::readPackage(...)} is of significant duration for a large map (a debug, without optimisation, build on my 1.8GHz Quad-core took over two minutes to process the current Achaea map file) it is very possible to get conditions where the same profile will try to run XMLinport::readPackage(...) asynchronously - given that a profile only supports ONE map at a time it was necessary to fit a QMutex to prevent the part of the XMLinport class relating to XML Map files being called from different places in the map related code. This means that if a map download is started further downloads and any local map imports will fail until that first download has completed or aborted. Similarly a local import will prevent a download being started. As a side effect this cures: https://bugs.launchpad.net/mudlet/+bug/852861 - "Map download button starts another download thread if one is already going" The previous XML import code was not adding the rooms that it parsed to the relevant TArea::rooms member - although this would be picked-up and fixed by TMap::audit() later on, this would be accompanied by an error message about every single room. The code now builds up this information while parsing the rooms' details and inserts it so that this does not cause report-able problems during the TMap::audit() execution - the data gathered also allows missing areas to be spotted so that if a room claimed to belong to an area that was not included in the preceding areas' data an unnamed area is created for it. As a consequence of the long time to actually parse an XML map file I have enhanced the progress dialog that was originally used to track the map file download. It is now retained until the file is completely imported and shows more information about the process - importantly it shows during the XMLimport::readRoom(...) the room id being processed - and THAT method is the time/cpu hog so seeing something happening during the time that Mudlet otherwise appears to hang is useful feedback even if it adds a few seconds to the overall duration (may be more than a minute). This dialog is now also used during the other routes that involve reading an XML file and there is now a bit of consistence with the on-screen messages. Whilst inspecting XMLimport class I found there was some uncertain initialisation which I have tidied up. In summary: Added: * (bool) TConsole::importMap(const QString & location) * (void) TRoomDB::setAreaRooms(const int areaId, const QSet<int> & roomIds) * image file mudlet_map_download.png used as icon for download/import progress dialog * (bool) TMap::importMap(QFile & file) * (bool) TMap::readXmlMapFile(QFile & file) * (void) TMap::slot_downloadError(QNetworkReply::NetworkError error) * (void) TMap::reportStringToProgressDialog(const QString text) * (void) TMap::reportProgressToProgressDialog(const int current, const int maximum) Revised: * (int)TLuaInterpreter::loadMap( lua_State * ) * Moved XML map download code from dlgMapper class to the TMap one: + (void) dlgMapper::downloadMap() ==> (bool) TMap::downloadMap(const QString * remoteUrl, const QString * localFileName) + (void) dlgMapper::setDownloadProgress(qint64, qint64) ==> (void) TMap::slot_setDownloadProgress(qint64,qint64) + (void) dlgMapper::cancel() ==> (void) TMap::slot_downloadCancel() + (void) dlgMapper::replyFinished(QNetworkReply *) ==> (void) TMap::slot_replyFinished(QNetworkReply *) * Enhanced download progress indication to also include parsing which can take even more time than download! * Provide means to import local XML map file * Prevent trying to import/download more than one map at a time Renamed: * (void) XMLimport::readAreaNames() ==> XMLimport::readArea() - for consistency with related functions Commented out unused: * (void) XMLimport::readUnknownRoomElement() Note the movement of the map file download code to the TMap class does require making the latter a class with the Q_OBJECT macro (which removes the need for Q_DECLARE_TR_FUNCTIONS as a side-effect!) - though as another side-effect the TMap header needed a boost name specifier added to one identifier as that identifier ("property") exists in both boost and QObject classes!!! YOU MAY NEED TO RUN QMAKE ON THE PROJECT IF THE BUILD SYSTEM DOES NOT PICK UP THE ADDITION OF "Q_OBJECT" TO TMAP CLASS. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: Include missing #include, remove unused return value The absence of this was causing build errors on the Travis C.I. platform! Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: move TMap.h to mudlet_MOC_HDRS to fix CMake build issue As we have made TMap inherit from QOject - to have signal/slot functionality that class needs to be run through Qt's MOC - and to do that with the CMake project/build system it needs to be included in the files included in the projects *_MOC_HDRS {and removed from the *_HDRS} variable. Also spotted a trivial error in that specifying a const return value from method is ineffective and pointless - so removed it from: TMap::retrieveMapFileStats(QString,QString *,int *,int *,int *,int *) Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: clean up TMap initialisation/clearing actions Now restores the customEnvColors set up on initialisation but that was cleared when the map replaced with another one that is loaded {which subsequently replaces that element anyway} or imported {which merely writes over it, replacing any matching keys}. Initialises elements that when inspected on the entry to the constructor proper previously were not being set to a consistent value {booleans/ints/floats}. NOTE: This will now clear the map user data member when the map is cleared if the date is required to be saved when one map is loaded OR IMPORTED over an existing one then the data will need to be saved outside of the map - as is already need for areas and rooms user data! Also comment out or remove unused members/methods: * (void) TMap::getConnectedNodesGreaterThanX(int, int) * (void) TMap::getConnectedNodesSmallerThanX(int, int) * (void) TMap::getConnectedNodesGreaterThanY(int, int) * (void) TMap::getConnectedNodesSmallerThanY(int, int) * (void) TMap::astBreitenAnpassung(int, int) * (void) TMap::astHoehenAnpassung(int, int) * (void) TMap::exportMapToDatabase() * (void) TMap::importMapFromDatabase() * (QVector3D) TMap::span * (int) TMap::mViewArea * (QMap<QString, int>) TMap::pixNameTable * (QMap<int, QPixmap>) TMap::pixTable * (bool) TMap::isToDisplayAuditErrorsToConsole Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * ImplimentationFixes: activate a valid optimisation & remove redundant code Adding a true as a non-default 3rd argument to TRoomDB::addRoom(...) call in XMLimport::readRoom(...) enables a significant optimisation (skips a computationally expensive step when ADDING a room to new map) which dramatically reduces the time to parse an XML map file. It also pointed to the fact that the TRoomDB::entranceMap was already correctly being handled and didn't need to be regenerated in XMLimport::readRoom(...) so the code that was added in a previous commit was redundant and could be removed. A code error in TMap::slot_setDownloadProgress(...) that caused an issue that a reviewer found on test has been fixed - the total download filesize that was being sent by the Qt system signal that is connected to this slot was a -1 value (as IS DOCUMENTED) when the Qt system does NOT know the size of a QNetworkReply in advance of reaching the end of the download was incorrectly handled in a previous commit in this change set. Also found during testing that there is no need for an error message for the QNetworkReply::OperationCanceledError case in TMap::slot_replayFinished(...) as it is already handled in the TMap::slot_downloadCancel() slot. Changed the text put up onto the progress widget during the XML room parsing to be a room count - which is likely more useful and to only do it for every hundredth room - which reduces any delay "wasted" in writing to the display - combined, the effects seem satisfactory IMHO. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: provide error messages for TLuaInterpreter::loadMap(...) Errors for the XML map file importing process as initiated from the Lua command should be returned to that command rather than plastered onto the main profile console - this commit attempts to perform that effect. In testing found that there was no error handling for failure to find or open the nominated file so messages for that have been added as well. Due to the previous program logic the action of creating a mapper widget using the main toolbar button automatically loaded the "default" (the newest Mudlet Map file format file from the currently active profile's map sub-directory). Under some previous situations it looked as though a map might be loaded twice as mudlet::slot_mapper() was called both directly and via signal/slot action. These were resolved by turning that slot into a wrapper that now calls the body of code formerly within to a new method mudlet::createMapper( bool isToLoadDefaultMapFile = true ) with a the default value as an argument. This allows other usages of the body of code to be called directly with a suitable argument, which for the TConsole::loadMap() & TConsole::importMap() and the dlgProfilePreferences::downloadMap() cases is false as they are all do not want the "default" map! Also: * spotted a word "area" missing from an advisory text in TRoom::auditRooms(...). Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: fix minor bug, correct a spelling, undo a few capitalisations Under certain, unanticipated (error with no error message) conditions TLuaInterpreter::loadMap(...) would push both a nil and then a false value onto the stack for return {wrong} but only indicate one value {correct}. The textual matters were found during peer review. off-by: Stephen Lyons <slysven@virginmedia.com>
2016-10-13 09:18:48 +01:00
{
if (!mpProgressDialog) {
Enhance: fix map downloading code, add manual XML map importing (#326) * Enhance: fix map downloading code, add manual XML map importing A recent move by I.R.E. to using SSL for their public MUD map URLs broke the ability for Mudlet to download those XML format files. This commit addresses this issue (as mentioned in, but not the original problem referred to in https://bugs.launchpad.net/mudlet/+bug/1427364) the revision to the code does now use "https://www.<MUD URL>/maps/map.xml" as a default name for the I.R.E. MUDS - however the method that initiates the download which was moved to TMap class from the dlgMapper one (see below) is now: (bool) TMap::downloadMap( const QString * remoteUrl = Q_NULLPTR, const QString * localFileName = Q_NULLPTR ) which if not supplied with any arguments behaves as before. However the remoteUrl argument may be given as a full QString including the scheme (the bit of the URL at the beginning before the ':') to override that and a second argument may be used to provide a different name to use for the local file name which if is a RELATIVE pathFileName will be resolved in relation to the profile directory. At present no use is made of this additional functionality but it may be useful for use with other MUDs if they should choose to provide XML map files with other remote locations and scripts using a different local filename. As a long-standing thing that needed doing I have finally provided a means to import a map XML file that - for instance - has already been download. It had been noted that there was no way to read those I.R.E. map files even if they had been obtained from a web browser able to correctly handle https: URLs - now both the TLuaInterpreter::loadMap() and the dlgProfilePreference "loadMap" button {NOT the IRE only "map download" one} will both handle files ending in ".xml" (not case sensitive so it'll work MacOS platforms as well!} For the loadMap case it will be necessary to change the filetype filter on the File Selection dialog to select "xml" files. During testing it became clear to me that it was possible to try and read one or more XML files via several mechanisms simultaneously with "unhelpful" consequences. As well as hitting the dlgProfilePreferences IRE "map download" multiple times, the TLuaInterpreter::loadMap() does NOT block until the map has been loaded and as the import time {running of XMLinport::readPackage(...)} is of significant duration for a large map (a debug, without optimisation, build on my 1.8GHz Quad-core took over two minutes to process the current Achaea map file) it is very possible to get conditions where the same profile will try to run XMLinport::readPackage(...) asynchronously - given that a profile only supports ONE map at a time it was necessary to fit a QMutex to prevent the part of the XMLinport class relating to XML Map files being called from different places in the map related code. This means that if a map download is started further downloads and any local map imports will fail until that first download has completed or aborted. Similarly a local import will prevent a download being started. As a side effect this cures: https://bugs.launchpad.net/mudlet/+bug/852861 - "Map download button starts another download thread if one is already going" The previous XML import code was not adding the rooms that it parsed to the relevant TArea::rooms member - although this would be picked-up and fixed by TMap::audit() later on, this would be accompanied by an error message about every single room. The code now builds up this information while parsing the rooms' details and inserts it so that this does not cause report-able problems during the TMap::audit() execution - the data gathered also allows missing areas to be spotted so that if a room claimed to belong to an area that was not included in the preceding areas' data an unnamed area is created for it. As a consequence of the long time to actually parse an XML map file I have enhanced the progress dialog that was originally used to track the map file download. It is now retained until the file is completely imported and shows more information about the process - importantly it shows during the XMLimport::readRoom(...) the room id being processed - and THAT method is the time/cpu hog so seeing something happening during the time that Mudlet otherwise appears to hang is useful feedback even if it adds a few seconds to the overall duration (may be more than a minute). This dialog is now also used during the other routes that involve reading an XML file and there is now a bit of consistence with the on-screen messages. Whilst inspecting XMLimport class I found there was some uncertain initialisation which I have tidied up. In summary: Added: * (bool) TConsole::importMap(const QString & location) * (void) TRoomDB::setAreaRooms(const int areaId, const QSet<int> & roomIds) * image file mudlet_map_download.png used as icon for download/import progress dialog * (bool) TMap::importMap(QFile & file) * (bool) TMap::readXmlMapFile(QFile & file) * (void) TMap::slot_downloadError(QNetworkReply::NetworkError error) * (void) TMap::reportStringToProgressDialog(const QString text) * (void) TMap::reportProgressToProgressDialog(const int current, const int maximum) Revised: * (int)TLuaInterpreter::loadMap( lua_State * ) * Moved XML map download code from dlgMapper class to the TMap one: + (void) dlgMapper::downloadMap() ==> (bool) TMap::downloadMap(const QString * remoteUrl, const QString * localFileName) + (void) dlgMapper::setDownloadProgress(qint64, qint64) ==> (void) TMap::slot_setDownloadProgress(qint64,qint64) + (void) dlgMapper::cancel() ==> (void) TMap::slot_downloadCancel() + (void) dlgMapper::replyFinished(QNetworkReply *) ==> (void) TMap::slot_replyFinished(QNetworkReply *) * Enhanced download progress indication to also include parsing which can take even more time than download! * Provide means to import local XML map file * Prevent trying to import/download more than one map at a time Renamed: * (void) XMLimport::readAreaNames() ==> XMLimport::readArea() - for consistency with related functions Commented out unused: * (void) XMLimport::readUnknownRoomElement() Note the movement of the map file download code to the TMap class does require making the latter a class with the Q_OBJECT macro (which removes the need for Q_DECLARE_TR_FUNCTIONS as a side-effect!) - though as another side-effect the TMap header needed a boost name specifier added to one identifier as that identifier ("property") exists in both boost and QObject classes!!! YOU MAY NEED TO RUN QMAKE ON THE PROJECT IF THE BUILD SYSTEM DOES NOT PICK UP THE ADDITION OF "Q_OBJECT" TO TMAP CLASS. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: Include missing #include, remove unused return value The absence of this was causing build errors on the Travis C.I. platform! Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: move TMap.h to mudlet_MOC_HDRS to fix CMake build issue As we have made TMap inherit from QOject - to have signal/slot functionality that class needs to be run through Qt's MOC - and to do that with the CMake project/build system it needs to be included in the files included in the projects *_MOC_HDRS {and removed from the *_HDRS} variable. Also spotted a trivial error in that specifying a const return value from method is ineffective and pointless - so removed it from: TMap::retrieveMapFileStats(QString,QString *,int *,int *,int *,int *) Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: clean up TMap initialisation/clearing actions Now restores the customEnvColors set up on initialisation but that was cleared when the map replaced with another one that is loaded {which subsequently replaces that element anyway} or imported {which merely writes over it, replacing any matching keys}. Initialises elements that when inspected on the entry to the constructor proper previously were not being set to a consistent value {booleans/ints/floats}. NOTE: This will now clear the map user data member when the map is cleared if the date is required to be saved when one map is loaded OR IMPORTED over an existing one then the data will need to be saved outside of the map - as is already need for areas and rooms user data! Also comment out or remove unused members/methods: * (void) TMap::getConnectedNodesGreaterThanX(int, int) * (void) TMap::getConnectedNodesSmallerThanX(int, int) * (void) TMap::getConnectedNodesGreaterThanY(int, int) * (void) TMap::getConnectedNodesSmallerThanY(int, int) * (void) TMap::astBreitenAnpassung(int, int) * (void) TMap::astHoehenAnpassung(int, int) * (void) TMap::exportMapToDatabase() * (void) TMap::importMapFromDatabase() * (QVector3D) TMap::span * (int) TMap::mViewArea * (QMap<QString, int>) TMap::pixNameTable * (QMap<int, QPixmap>) TMap::pixTable * (bool) TMap::isToDisplayAuditErrorsToConsole Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * ImplimentationFixes: activate a valid optimisation & remove redundant code Adding a true as a non-default 3rd argument to TRoomDB::addRoom(...) call in XMLimport::readRoom(...) enables a significant optimisation (skips a computationally expensive step when ADDING a room to new map) which dramatically reduces the time to parse an XML map file. It also pointed to the fact that the TRoomDB::entranceMap was already correctly being handled and didn't need to be regenerated in XMLimport::readRoom(...) so the code that was added in a previous commit was redundant and could be removed. A code error in TMap::slot_setDownloadProgress(...) that caused an issue that a reviewer found on test has been fixed - the total download filesize that was being sent by the Qt system signal that is connected to this slot was a -1 value (as IS DOCUMENTED) when the Qt system does NOT know the size of a QNetworkReply in advance of reaching the end of the download was incorrectly handled in a previous commit in this change set. Also found during testing that there is no need for an error message for the QNetworkReply::OperationCanceledError case in TMap::slot_replayFinished(...) as it is already handled in the TMap::slot_downloadCancel() slot. Changed the text put up onto the progress widget during the XML room parsing to be a room count - which is likely more useful and to only do it for every hundredth room - which reduces any delay "wasted" in writing to the display - combined, the effects seem satisfactory IMHO. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: provide error messages for TLuaInterpreter::loadMap(...) Errors for the XML map file importing process as initiated from the Lua command should be returned to that command rather than plastered onto the main profile console - this commit attempts to perform that effect. In testing found that there was no error handling for failure to find or open the nominated file so messages for that have been added as well. Due to the previous program logic the action of creating a mapper widget using the main toolbar button automatically loaded the "default" (the newest Mudlet Map file format file from the currently active profile's map sub-directory). Under some previous situations it looked as though a map might be loaded twice as mudlet::slot_mapper() was called both directly and via signal/slot action. These were resolved by turning that slot into a wrapper that now calls the body of code formerly within to a new method mudlet::createMapper( bool isToLoadDefaultMapFile = true ) with a the default value as an argument. This allows other usages of the body of code to be called directly with a suitable argument, which for the TConsole::loadMap() & TConsole::importMap() and the dlgProfilePreferences::downloadMap() cases is false as they are all do not want the "default" map! Also: * spotted a word "area" missing from an advisory text in TRoom::auditRooms(...). Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: fix minor bug, correct a spelling, undo a few capitalisations Under certain, unanticipated (error with no error message) conditions TLuaInterpreter::loadMap(...) would push both a nil and then a false value onto the stack for return {wrong} but only indicate one value {correct}. The textual matters were found during peer review. off-by: Stephen Lyons <slysven@virginmedia.com>
2016-10-13 09:18:48 +01:00
return;
}
if (!mpProgressDialog->maximum()) {
Enhance: fix map downloading code, add manual XML map importing (#326) * Enhance: fix map downloading code, add manual XML map importing A recent move by I.R.E. to using SSL for their public MUD map URLs broke the ability for Mudlet to download those XML format files. This commit addresses this issue (as mentioned in, but not the original problem referred to in https://bugs.launchpad.net/mudlet/+bug/1427364) the revision to the code does now use "https://www.<MUD URL>/maps/map.xml" as a default name for the I.R.E. MUDS - however the method that initiates the download which was moved to TMap class from the dlgMapper one (see below) is now: (bool) TMap::downloadMap( const QString * remoteUrl = Q_NULLPTR, const QString * localFileName = Q_NULLPTR ) which if not supplied with any arguments behaves as before. However the remoteUrl argument may be given as a full QString including the scheme (the bit of the URL at the beginning before the ':') to override that and a second argument may be used to provide a different name to use for the local file name which if is a RELATIVE pathFileName will be resolved in relation to the profile directory. At present no use is made of this additional functionality but it may be useful for use with other MUDs if they should choose to provide XML map files with other remote locations and scripts using a different local filename. As a long-standing thing that needed doing I have finally provided a means to import a map XML file that - for instance - has already been download. It had been noted that there was no way to read those I.R.E. map files even if they had been obtained from a web browser able to correctly handle https: URLs - now both the TLuaInterpreter::loadMap() and the dlgProfilePreference "loadMap" button {NOT the IRE only "map download" one} will both handle files ending in ".xml" (not case sensitive so it'll work MacOS platforms as well!} For the loadMap case it will be necessary to change the filetype filter on the File Selection dialog to select "xml" files. During testing it became clear to me that it was possible to try and read one or more XML files via several mechanisms simultaneously with "unhelpful" consequences. As well as hitting the dlgProfilePreferences IRE "map download" multiple times, the TLuaInterpreter::loadMap() does NOT block until the map has been loaded and as the import time {running of XMLinport::readPackage(...)} is of significant duration for a large map (a debug, without optimisation, build on my 1.8GHz Quad-core took over two minutes to process the current Achaea map file) it is very possible to get conditions where the same profile will try to run XMLinport::readPackage(...) asynchronously - given that a profile only supports ONE map at a time it was necessary to fit a QMutex to prevent the part of the XMLinport class relating to XML Map files being called from different places in the map related code. This means that if a map download is started further downloads and any local map imports will fail until that first download has completed or aborted. Similarly a local import will prevent a download being started. As a side effect this cures: https://bugs.launchpad.net/mudlet/+bug/852861 - "Map download button starts another download thread if one is already going" The previous XML import code was not adding the rooms that it parsed to the relevant TArea::rooms member - although this would be picked-up and fixed by TMap::audit() later on, this would be accompanied by an error message about every single room. The code now builds up this information while parsing the rooms' details and inserts it so that this does not cause report-able problems during the TMap::audit() execution - the data gathered also allows missing areas to be spotted so that if a room claimed to belong to an area that was not included in the preceding areas' data an unnamed area is created for it. As a consequence of the long time to actually parse an XML map file I have enhanced the progress dialog that was originally used to track the map file download. It is now retained until the file is completely imported and shows more information about the process - importantly it shows during the XMLimport::readRoom(...) the room id being processed - and THAT method is the time/cpu hog so seeing something happening during the time that Mudlet otherwise appears to hang is useful feedback even if it adds a few seconds to the overall duration (may be more than a minute). This dialog is now also used during the other routes that involve reading an XML file and there is now a bit of consistence with the on-screen messages. Whilst inspecting XMLimport class I found there was some uncertain initialisation which I have tidied up. In summary: Added: * (bool) TConsole::importMap(const QString & location) * (void) TRoomDB::setAreaRooms(const int areaId, const QSet<int> & roomIds) * image file mudlet_map_download.png used as icon for download/import progress dialog * (bool) TMap::importMap(QFile & file) * (bool) TMap::readXmlMapFile(QFile & file) * (void) TMap::slot_downloadError(QNetworkReply::NetworkError error) * (void) TMap::reportStringToProgressDialog(const QString text) * (void) TMap::reportProgressToProgressDialog(const int current, const int maximum) Revised: * (int)TLuaInterpreter::loadMap( lua_State * ) * Moved XML map download code from dlgMapper class to the TMap one: + (void) dlgMapper::downloadMap() ==> (bool) TMap::downloadMap(const QString * remoteUrl, const QString * localFileName) + (void) dlgMapper::setDownloadProgress(qint64, qint64) ==> (void) TMap::slot_setDownloadProgress(qint64,qint64) + (void) dlgMapper::cancel() ==> (void) TMap::slot_downloadCancel() + (void) dlgMapper::replyFinished(QNetworkReply *) ==> (void) TMap::slot_replyFinished(QNetworkReply *) * Enhanced download progress indication to also include parsing which can take even more time than download! * Provide means to import local XML map file * Prevent trying to import/download more than one map at a time Renamed: * (void) XMLimport::readAreaNames() ==> XMLimport::readArea() - for consistency with related functions Commented out unused: * (void) XMLimport::readUnknownRoomElement() Note the movement of the map file download code to the TMap class does require making the latter a class with the Q_OBJECT macro (which removes the need for Q_DECLARE_TR_FUNCTIONS as a side-effect!) - though as another side-effect the TMap header needed a boost name specifier added to one identifier as that identifier ("property") exists in both boost and QObject classes!!! YOU MAY NEED TO RUN QMAKE ON THE PROJECT IF THE BUILD SYSTEM DOES NOT PICK UP THE ADDITION OF "Q_OBJECT" TO TMAP CLASS. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: Include missing #include, remove unused return value The absence of this was causing build errors on the Travis C.I. platform! Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: move TMap.h to mudlet_MOC_HDRS to fix CMake build issue As we have made TMap inherit from QOject - to have signal/slot functionality that class needs to be run through Qt's MOC - and to do that with the CMake project/build system it needs to be included in the files included in the projects *_MOC_HDRS {and removed from the *_HDRS} variable. Also spotted a trivial error in that specifying a const return value from method is ineffective and pointless - so removed it from: TMap::retrieveMapFileStats(QString,QString *,int *,int *,int *,int *) Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: clean up TMap initialisation/clearing actions Now restores the customEnvColors set up on initialisation but that was cleared when the map replaced with another one that is loaded {which subsequently replaces that element anyway} or imported {which merely writes over it, replacing any matching keys}. Initialises elements that when inspected on the entry to the constructor proper previously were not being set to a consistent value {booleans/ints/floats}. NOTE: This will now clear the map user data member when the map is cleared if the date is required to be saved when one map is loaded OR IMPORTED over an existing one then the data will need to be saved outside of the map - as is already need for areas and rooms user data! Also comment out or remove unused members/methods: * (void) TMap::getConnectedNodesGreaterThanX(int, int) * (void) TMap::getConnectedNodesSmallerThanX(int, int) * (void) TMap::getConnectedNodesGreaterThanY(int, int) * (void) TMap::getConnectedNodesSmallerThanY(int, int) * (void) TMap::astBreitenAnpassung(int, int) * (void) TMap::astHoehenAnpassung(int, int) * (void) TMap::exportMapToDatabase() * (void) TMap::importMapFromDatabase() * (QVector3D) TMap::span * (int) TMap::mViewArea * (QMap<QString, int>) TMap::pixNameTable * (QMap<int, QPixmap>) TMap::pixTable * (bool) TMap::isToDisplayAuditErrorsToConsole Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * ImplimentationFixes: activate a valid optimisation & remove redundant code Adding a true as a non-default 3rd argument to TRoomDB::addRoom(...) call in XMLimport::readRoom(...) enables a significant optimisation (skips a computationally expensive step when ADDING a room to new map) which dramatically reduces the time to parse an XML map file. It also pointed to the fact that the TRoomDB::entranceMap was already correctly being handled and didn't need to be regenerated in XMLimport::readRoom(...) so the code that was added in a previous commit was redundant and could be removed. A code error in TMap::slot_setDownloadProgress(...) that caused an issue that a reviewer found on test has been fixed - the total download filesize that was being sent by the Qt system signal that is connected to this slot was a -1 value (as IS DOCUMENTED) when the Qt system does NOT know the size of a QNetworkReply in advance of reaching the end of the download was incorrectly handled in a previous commit in this change set. Also found during testing that there is no need for an error message for the QNetworkReply::OperationCanceledError case in TMap::slot_replayFinished(...) as it is already handled in the TMap::slot_downloadCancel() slot. Changed the text put up onto the progress widget during the XML room parsing to be a room count - which is likely more useful and to only do it for every hundredth room - which reduces any delay "wasted" in writing to the display - combined, the effects seem satisfactory IMHO. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: provide error messages for TLuaInterpreter::loadMap(...) Errors for the XML map file importing process as initiated from the Lua command should be returned to that command rather than plastered onto the main profile console - this commit attempts to perform that effect. In testing found that there was no error handling for failure to find or open the nominated file so messages for that have been added as well. Due to the previous program logic the action of creating a mapper widget using the main toolbar button automatically loaded the "default" (the newest Mudlet Map file format file from the currently active profile's map sub-directory). Under some previous situations it looked as though a map might be loaded twice as mudlet::slot_mapper() was called both directly and via signal/slot action. These were resolved by turning that slot into a wrapper that now calls the body of code formerly within to a new method mudlet::createMapper( bool isToLoadDefaultMapFile = true ) with a the default value as an argument. This allows other usages of the body of code to be called directly with a suitable argument, which for the TConsole::loadMap() & TConsole::importMap() and the dlgProfilePreferences::downloadMap() cases is false as they are all do not want the "default" map! Also: * spotted a word "area" missing from an advisory text in TRoom::auditRooms(...). Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: fix minor bug, correct a spelling, undo a few capitalisations Under certain, unanticipated (error with no error message) conditions TLuaInterpreter::loadMap(...) would push both a nil and then a false value onto the stack for return {wrong} but only indicate one value {correct}. The textual matters were found during peer review. off-by: Stephen Lyons <slysven@virginmedia.com>
2016-10-13 09:18:48 +01:00
// First call, range has not been set;
mpProgressDialog->setRange(0, mExpectedFileSize);
} else if (tot != -1 && mpProgressDialog->maximum() != static_cast<int>(tot)) {
Enhance: fix map downloading code, add manual XML map importing (#326) * Enhance: fix map downloading code, add manual XML map importing A recent move by I.R.E. to using SSL for their public MUD map URLs broke the ability for Mudlet to download those XML format files. This commit addresses this issue (as mentioned in, but not the original problem referred to in https://bugs.launchpad.net/mudlet/+bug/1427364) the revision to the code does now use "https://www.<MUD URL>/maps/map.xml" as a default name for the I.R.E. MUDS - however the method that initiates the download which was moved to TMap class from the dlgMapper one (see below) is now: (bool) TMap::downloadMap( const QString * remoteUrl = Q_NULLPTR, const QString * localFileName = Q_NULLPTR ) which if not supplied with any arguments behaves as before. However the remoteUrl argument may be given as a full QString including the scheme (the bit of the URL at the beginning before the ':') to override that and a second argument may be used to provide a different name to use for the local file name which if is a RELATIVE pathFileName will be resolved in relation to the profile directory. At present no use is made of this additional functionality but it may be useful for use with other MUDs if they should choose to provide XML map files with other remote locations and scripts using a different local filename. As a long-standing thing that needed doing I have finally provided a means to import a map XML file that - for instance - has already been download. It had been noted that there was no way to read those I.R.E. map files even if they had been obtained from a web browser able to correctly handle https: URLs - now both the TLuaInterpreter::loadMap() and the dlgProfilePreference "loadMap" button {NOT the IRE only "map download" one} will both handle files ending in ".xml" (not case sensitive so it'll work MacOS platforms as well!} For the loadMap case it will be necessary to change the filetype filter on the File Selection dialog to select "xml" files. During testing it became clear to me that it was possible to try and read one or more XML files via several mechanisms simultaneously with "unhelpful" consequences. As well as hitting the dlgProfilePreferences IRE "map download" multiple times, the TLuaInterpreter::loadMap() does NOT block until the map has been loaded and as the import time {running of XMLinport::readPackage(...)} is of significant duration for a large map (a debug, without optimisation, build on my 1.8GHz Quad-core took over two minutes to process the current Achaea map file) it is very possible to get conditions where the same profile will try to run XMLinport::readPackage(...) asynchronously - given that a profile only supports ONE map at a time it was necessary to fit a QMutex to prevent the part of the XMLinport class relating to XML Map files being called from different places in the map related code. This means that if a map download is started further downloads and any local map imports will fail until that first download has completed or aborted. Similarly a local import will prevent a download being started. As a side effect this cures: https://bugs.launchpad.net/mudlet/+bug/852861 - "Map download button starts another download thread if one is already going" The previous XML import code was not adding the rooms that it parsed to the relevant TArea::rooms member - although this would be picked-up and fixed by TMap::audit() later on, this would be accompanied by an error message about every single room. The code now builds up this information while parsing the rooms' details and inserts it so that this does not cause report-able problems during the TMap::audit() execution - the data gathered also allows missing areas to be spotted so that if a room claimed to belong to an area that was not included in the preceding areas' data an unnamed area is created for it. As a consequence of the long time to actually parse an XML map file I have enhanced the progress dialog that was originally used to track the map file download. It is now retained until the file is completely imported and shows more information about the process - importantly it shows during the XMLimport::readRoom(...) the room id being processed - and THAT method is the time/cpu hog so seeing something happening during the time that Mudlet otherwise appears to hang is useful feedback even if it adds a few seconds to the overall duration (may be more than a minute). This dialog is now also used during the other routes that involve reading an XML file and there is now a bit of consistence with the on-screen messages. Whilst inspecting XMLimport class I found there was some uncertain initialisation which I have tidied up. In summary: Added: * (bool) TConsole::importMap(const QString & location) * (void) TRoomDB::setAreaRooms(const int areaId, const QSet<int> & roomIds) * image file mudlet_map_download.png used as icon for download/import progress dialog * (bool) TMap::importMap(QFile & file) * (bool) TMap::readXmlMapFile(QFile & file) * (void) TMap::slot_downloadError(QNetworkReply::NetworkError error) * (void) TMap::reportStringToProgressDialog(const QString text) * (void) TMap::reportProgressToProgressDialog(const int current, const int maximum) Revised: * (int)TLuaInterpreter::loadMap( lua_State * ) * Moved XML map download code from dlgMapper class to the TMap one: + (void) dlgMapper::downloadMap() ==> (bool) TMap::downloadMap(const QString * remoteUrl, const QString * localFileName) + (void) dlgMapper::setDownloadProgress(qint64, qint64) ==> (void) TMap::slot_setDownloadProgress(qint64,qint64) + (void) dlgMapper::cancel() ==> (void) TMap::slot_downloadCancel() + (void) dlgMapper::replyFinished(QNetworkReply *) ==> (void) TMap::slot_replyFinished(QNetworkReply *) * Enhanced download progress indication to also include parsing which can take even more time than download! * Provide means to import local XML map file * Prevent trying to import/download more than one map at a time Renamed: * (void) XMLimport::readAreaNames() ==> XMLimport::readArea() - for consistency with related functions Commented out unused: * (void) XMLimport::readUnknownRoomElement() Note the movement of the map file download code to the TMap class does require making the latter a class with the Q_OBJECT macro (which removes the need for Q_DECLARE_TR_FUNCTIONS as a side-effect!) - though as another side-effect the TMap header needed a boost name specifier added to one identifier as that identifier ("property") exists in both boost and QObject classes!!! YOU MAY NEED TO RUN QMAKE ON THE PROJECT IF THE BUILD SYSTEM DOES NOT PICK UP THE ADDITION OF "Q_OBJECT" TO TMAP CLASS. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: Include missing #include, remove unused return value The absence of this was causing build errors on the Travis C.I. platform! Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: move TMap.h to mudlet_MOC_HDRS to fix CMake build issue As we have made TMap inherit from QOject - to have signal/slot functionality that class needs to be run through Qt's MOC - and to do that with the CMake project/build system it needs to be included in the files included in the projects *_MOC_HDRS {and removed from the *_HDRS} variable. Also spotted a trivial error in that specifying a const return value from method is ineffective and pointless - so removed it from: TMap::retrieveMapFileStats(QString,QString *,int *,int *,int *,int *) Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: clean up TMap initialisation/clearing actions Now restores the customEnvColors set up on initialisation but that was cleared when the map replaced with another one that is loaded {which subsequently replaces that element anyway} or imported {which merely writes over it, replacing any matching keys}. Initialises elements that when inspected on the entry to the constructor proper previously were not being set to a consistent value {booleans/ints/floats}. NOTE: This will now clear the map user data member when the map is cleared if the date is required to be saved when one map is loaded OR IMPORTED over an existing one then the data will need to be saved outside of the map - as is already need for areas and rooms user data! Also comment out or remove unused members/methods: * (void) TMap::getConnectedNodesGreaterThanX(int, int) * (void) TMap::getConnectedNodesSmallerThanX(int, int) * (void) TMap::getConnectedNodesGreaterThanY(int, int) * (void) TMap::getConnectedNodesSmallerThanY(int, int) * (void) TMap::astBreitenAnpassung(int, int) * (void) TMap::astHoehenAnpassung(int, int) * (void) TMap::exportMapToDatabase() * (void) TMap::importMapFromDatabase() * (QVector3D) TMap::span * (int) TMap::mViewArea * (QMap<QString, int>) TMap::pixNameTable * (QMap<int, QPixmap>) TMap::pixTable * (bool) TMap::isToDisplayAuditErrorsToConsole Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * ImplimentationFixes: activate a valid optimisation & remove redundant code Adding a true as a non-default 3rd argument to TRoomDB::addRoom(...) call in XMLimport::readRoom(...) enables a significant optimisation (skips a computationally expensive step when ADDING a room to new map) which dramatically reduces the time to parse an XML map file. It also pointed to the fact that the TRoomDB::entranceMap was already correctly being handled and didn't need to be regenerated in XMLimport::readRoom(...) so the code that was added in a previous commit was redundant and could be removed. A code error in TMap::slot_setDownloadProgress(...) that caused an issue that a reviewer found on test has been fixed - the total download filesize that was being sent by the Qt system signal that is connected to this slot was a -1 value (as IS DOCUMENTED) when the Qt system does NOT know the size of a QNetworkReply in advance of reaching the end of the download was incorrectly handled in a previous commit in this change set. Also found during testing that there is no need for an error message for the QNetworkReply::OperationCanceledError case in TMap::slot_replayFinished(...) as it is already handled in the TMap::slot_downloadCancel() slot. Changed the text put up onto the progress widget during the XML room parsing to be a room count - which is likely more useful and to only do it for every hundredth room - which reduces any delay "wasted" in writing to the display - combined, the effects seem satisfactory IMHO. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: provide error messages for TLuaInterpreter::loadMap(...) Errors for the XML map file importing process as initiated from the Lua command should be returned to that command rather than plastered onto the main profile console - this commit attempts to perform that effect. In testing found that there was no error handling for failure to find or open the nominated file so messages for that have been added as well. Due to the previous program logic the action of creating a mapper widget using the main toolbar button automatically loaded the "default" (the newest Mudlet Map file format file from the currently active profile's map sub-directory). Under some previous situations it looked as though a map might be loaded twice as mudlet::slot_mapper() was called both directly and via signal/slot action. These were resolved by turning that slot into a wrapper that now calls the body of code formerly within to a new method mudlet::createMapper( bool isToLoadDefaultMapFile = true ) with a the default value as an argument. This allows other usages of the body of code to be called directly with a suitable argument, which for the TConsole::loadMap() & TConsole::importMap() and the dlgProfilePreferences::downloadMap() cases is false as they are all do not want the "default" map! Also: * spotted a word "area" missing from an advisory text in TRoom::auditRooms(...). Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: fix minor bug, correct a spelling, undo a few capitalisations Under certain, unanticipated (error with no error message) conditions TLuaInterpreter::loadMap(...) would push both a nil and then a false value onto the stack for return {wrong} but only indicate one value {correct}. The textual matters were found during peer review. off-by: Stephen Lyons <slysven@virginmedia.com>
2016-10-13 09:18:48 +01:00
// tot will stuck at -1 when we do not know how big the download is
// which seems to be the case for the IRE MUDS - *sigh* - Slysven
mpProgressDialog->setRange(0, static_cast<int>(tot));
Enhance: fix map downloading code, add manual XML map importing (#326) * Enhance: fix map downloading code, add manual XML map importing A recent move by I.R.E. to using SSL for their public MUD map URLs broke the ability for Mudlet to download those XML format files. This commit addresses this issue (as mentioned in, but not the original problem referred to in https://bugs.launchpad.net/mudlet/+bug/1427364) the revision to the code does now use "https://www.<MUD URL>/maps/map.xml" as a default name for the I.R.E. MUDS - however the method that initiates the download which was moved to TMap class from the dlgMapper one (see below) is now: (bool) TMap::downloadMap( const QString * remoteUrl = Q_NULLPTR, const QString * localFileName = Q_NULLPTR ) which if not supplied with any arguments behaves as before. However the remoteUrl argument may be given as a full QString including the scheme (the bit of the URL at the beginning before the ':') to override that and a second argument may be used to provide a different name to use for the local file name which if is a RELATIVE pathFileName will be resolved in relation to the profile directory. At present no use is made of this additional functionality but it may be useful for use with other MUDs if they should choose to provide XML map files with other remote locations and scripts using a different local filename. As a long-standing thing that needed doing I have finally provided a means to import a map XML file that - for instance - has already been download. It had been noted that there was no way to read those I.R.E. map files even if they had been obtained from a web browser able to correctly handle https: URLs - now both the TLuaInterpreter::loadMap() and the dlgProfilePreference "loadMap" button {NOT the IRE only "map download" one} will both handle files ending in ".xml" (not case sensitive so it'll work MacOS platforms as well!} For the loadMap case it will be necessary to change the filetype filter on the File Selection dialog to select "xml" files. During testing it became clear to me that it was possible to try and read one or more XML files via several mechanisms simultaneously with "unhelpful" consequences. As well as hitting the dlgProfilePreferences IRE "map download" multiple times, the TLuaInterpreter::loadMap() does NOT block until the map has been loaded and as the import time {running of XMLinport::readPackage(...)} is of significant duration for a large map (a debug, without optimisation, build on my 1.8GHz Quad-core took over two minutes to process the current Achaea map file) it is very possible to get conditions where the same profile will try to run XMLinport::readPackage(...) asynchronously - given that a profile only supports ONE map at a time it was necessary to fit a QMutex to prevent the part of the XMLinport class relating to XML Map files being called from different places in the map related code. This means that if a map download is started further downloads and any local map imports will fail until that first download has completed or aborted. Similarly a local import will prevent a download being started. As a side effect this cures: https://bugs.launchpad.net/mudlet/+bug/852861 - "Map download button starts another download thread if one is already going" The previous XML import code was not adding the rooms that it parsed to the relevant TArea::rooms member - although this would be picked-up and fixed by TMap::audit() later on, this would be accompanied by an error message about every single room. The code now builds up this information while parsing the rooms' details and inserts it so that this does not cause report-able problems during the TMap::audit() execution - the data gathered also allows missing areas to be spotted so that if a room claimed to belong to an area that was not included in the preceding areas' data an unnamed area is created for it. As a consequence of the long time to actually parse an XML map file I have enhanced the progress dialog that was originally used to track the map file download. It is now retained until the file is completely imported and shows more information about the process - importantly it shows during the XMLimport::readRoom(...) the room id being processed - and THAT method is the time/cpu hog so seeing something happening during the time that Mudlet otherwise appears to hang is useful feedback even if it adds a few seconds to the overall duration (may be more than a minute). This dialog is now also used during the other routes that involve reading an XML file and there is now a bit of consistence with the on-screen messages. Whilst inspecting XMLimport class I found there was some uncertain initialisation which I have tidied up. In summary: Added: * (bool) TConsole::importMap(const QString & location) * (void) TRoomDB::setAreaRooms(const int areaId, const QSet<int> & roomIds) * image file mudlet_map_download.png used as icon for download/import progress dialog * (bool) TMap::importMap(QFile & file) * (bool) TMap::readXmlMapFile(QFile & file) * (void) TMap::slot_downloadError(QNetworkReply::NetworkError error) * (void) TMap::reportStringToProgressDialog(const QString text) * (void) TMap::reportProgressToProgressDialog(const int current, const int maximum) Revised: * (int)TLuaInterpreter::loadMap( lua_State * ) * Moved XML map download code from dlgMapper class to the TMap one: + (void) dlgMapper::downloadMap() ==> (bool) TMap::downloadMap(const QString * remoteUrl, const QString * localFileName) + (void) dlgMapper::setDownloadProgress(qint64, qint64) ==> (void) TMap::slot_setDownloadProgress(qint64,qint64) + (void) dlgMapper::cancel() ==> (void) TMap::slot_downloadCancel() + (void) dlgMapper::replyFinished(QNetworkReply *) ==> (void) TMap::slot_replyFinished(QNetworkReply *) * Enhanced download progress indication to also include parsing which can take even more time than download! * Provide means to import local XML map file * Prevent trying to import/download more than one map at a time Renamed: * (void) XMLimport::readAreaNames() ==> XMLimport::readArea() - for consistency with related functions Commented out unused: * (void) XMLimport::readUnknownRoomElement() Note the movement of the map file download code to the TMap class does require making the latter a class with the Q_OBJECT macro (which removes the need for Q_DECLARE_TR_FUNCTIONS as a side-effect!) - though as another side-effect the TMap header needed a boost name specifier added to one identifier as that identifier ("property") exists in both boost and QObject classes!!! YOU MAY NEED TO RUN QMAKE ON THE PROJECT IF THE BUILD SYSTEM DOES NOT PICK UP THE ADDITION OF "Q_OBJECT" TO TMAP CLASS. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: Include missing #include, remove unused return value The absence of this was causing build errors on the Travis C.I. platform! Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: move TMap.h to mudlet_MOC_HDRS to fix CMake build issue As we have made TMap inherit from QOject - to have signal/slot functionality that class needs to be run through Qt's MOC - and to do that with the CMake project/build system it needs to be included in the files included in the projects *_MOC_HDRS {and removed from the *_HDRS} variable. Also spotted a trivial error in that specifying a const return value from method is ineffective and pointless - so removed it from: TMap::retrieveMapFileStats(QString,QString *,int *,int *,int *,int *) Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: clean up TMap initialisation/clearing actions Now restores the customEnvColors set up on initialisation but that was cleared when the map replaced with another one that is loaded {which subsequently replaces that element anyway} or imported {which merely writes over it, replacing any matching keys}. Initialises elements that when inspected on the entry to the constructor proper previously were not being set to a consistent value {booleans/ints/floats}. NOTE: This will now clear the map user data member when the map is cleared if the date is required to be saved when one map is loaded OR IMPORTED over an existing one then the data will need to be saved outside of the map - as is already need for areas and rooms user data! Also comment out or remove unused members/methods: * (void) TMap::getConnectedNodesGreaterThanX(int, int) * (void) TMap::getConnectedNodesSmallerThanX(int, int) * (void) TMap::getConnectedNodesGreaterThanY(int, int) * (void) TMap::getConnectedNodesSmallerThanY(int, int) * (void) TMap::astBreitenAnpassung(int, int) * (void) TMap::astHoehenAnpassung(int, int) * (void) TMap::exportMapToDatabase() * (void) TMap::importMapFromDatabase() * (QVector3D) TMap::span * (int) TMap::mViewArea * (QMap<QString, int>) TMap::pixNameTable * (QMap<int, QPixmap>) TMap::pixTable * (bool) TMap::isToDisplayAuditErrorsToConsole Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * ImplimentationFixes: activate a valid optimisation & remove redundant code Adding a true as a non-default 3rd argument to TRoomDB::addRoom(...) call in XMLimport::readRoom(...) enables a significant optimisation (skips a computationally expensive step when ADDING a room to new map) which dramatically reduces the time to parse an XML map file. It also pointed to the fact that the TRoomDB::entranceMap was already correctly being handled and didn't need to be regenerated in XMLimport::readRoom(...) so the code that was added in a previous commit was redundant and could be removed. A code error in TMap::slot_setDownloadProgress(...) that caused an issue that a reviewer found on test has been fixed - the total download filesize that was being sent by the Qt system signal that is connected to this slot was a -1 value (as IS DOCUMENTED) when the Qt system does NOT know the size of a QNetworkReply in advance of reaching the end of the download was incorrectly handled in a previous commit in this change set. Also found during testing that there is no need for an error message for the QNetworkReply::OperationCanceledError case in TMap::slot_replayFinished(...) as it is already handled in the TMap::slot_downloadCancel() slot. Changed the text put up onto the progress widget during the XML room parsing to be a room count - which is likely more useful and to only do it for every hundredth room - which reduces any delay "wasted" in writing to the display - combined, the effects seem satisfactory IMHO. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: provide error messages for TLuaInterpreter::loadMap(...) Errors for the XML map file importing process as initiated from the Lua command should be returned to that command rather than plastered onto the main profile console - this commit attempts to perform that effect. In testing found that there was no error handling for failure to find or open the nominated file so messages for that have been added as well. Due to the previous program logic the action of creating a mapper widget using the main toolbar button automatically loaded the "default" (the newest Mudlet Map file format file from the currently active profile's map sub-directory). Under some previous situations it looked as though a map might be loaded twice as mudlet::slot_mapper() was called both directly and via signal/slot action. These were resolved by turning that slot into a wrapper that now calls the body of code formerly within to a new method mudlet::createMapper( bool isToLoadDefaultMapFile = true ) with a the default value as an argument. This allows other usages of the body of code to be called directly with a suitable argument, which for the TConsole::loadMap() & TConsole::importMap() and the dlgProfilePreferences::downloadMap() cases is false as they are all do not want the "default" map! Also: * spotted a word "area" missing from an advisory text in TRoom::auditRooms(...). Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: fix minor bug, correct a spelling, undo a few capitalisations Under certain, unanticipated (error with no error message) conditions TLuaInterpreter::loadMap(...) would push both a nil and then a false value onto the stack for return {wrong} but only indicate one value {correct}. The textual matters were found during peer review. off-by: Stephen Lyons <slysven@virginmedia.com>
2016-10-13 09:18:48 +01:00
}
mpProgressDialog->setValue(static_cast<int>(got));
Enhance: fix map downloading code, add manual XML map importing (#326) * Enhance: fix map downloading code, add manual XML map importing A recent move by I.R.E. to using SSL for their public MUD map URLs broke the ability for Mudlet to download those XML format files. This commit addresses this issue (as mentioned in, but not the original problem referred to in https://bugs.launchpad.net/mudlet/+bug/1427364) the revision to the code does now use "https://www.<MUD URL>/maps/map.xml" as a default name for the I.R.E. MUDS - however the method that initiates the download which was moved to TMap class from the dlgMapper one (see below) is now: (bool) TMap::downloadMap( const QString * remoteUrl = Q_NULLPTR, const QString * localFileName = Q_NULLPTR ) which if not supplied with any arguments behaves as before. However the remoteUrl argument may be given as a full QString including the scheme (the bit of the URL at the beginning before the ':') to override that and a second argument may be used to provide a different name to use for the local file name which if is a RELATIVE pathFileName will be resolved in relation to the profile directory. At present no use is made of this additional functionality but it may be useful for use with other MUDs if they should choose to provide XML map files with other remote locations and scripts using a different local filename. As a long-standing thing that needed doing I have finally provided a means to import a map XML file that - for instance - has already been download. It had been noted that there was no way to read those I.R.E. map files even if they had been obtained from a web browser able to correctly handle https: URLs - now both the TLuaInterpreter::loadMap() and the dlgProfilePreference "loadMap" button {NOT the IRE only "map download" one} will both handle files ending in ".xml" (not case sensitive so it'll work MacOS platforms as well!} For the loadMap case it will be necessary to change the filetype filter on the File Selection dialog to select "xml" files. During testing it became clear to me that it was possible to try and read one or more XML files via several mechanisms simultaneously with "unhelpful" consequences. As well as hitting the dlgProfilePreferences IRE "map download" multiple times, the TLuaInterpreter::loadMap() does NOT block until the map has been loaded and as the import time {running of XMLinport::readPackage(...)} is of significant duration for a large map (a debug, without optimisation, build on my 1.8GHz Quad-core took over two minutes to process the current Achaea map file) it is very possible to get conditions where the same profile will try to run XMLinport::readPackage(...) asynchronously - given that a profile only supports ONE map at a time it was necessary to fit a QMutex to prevent the part of the XMLinport class relating to XML Map files being called from different places in the map related code. This means that if a map download is started further downloads and any local map imports will fail until that first download has completed or aborted. Similarly a local import will prevent a download being started. As a side effect this cures: https://bugs.launchpad.net/mudlet/+bug/852861 - "Map download button starts another download thread if one is already going" The previous XML import code was not adding the rooms that it parsed to the relevant TArea::rooms member - although this would be picked-up and fixed by TMap::audit() later on, this would be accompanied by an error message about every single room. The code now builds up this information while parsing the rooms' details and inserts it so that this does not cause report-able problems during the TMap::audit() execution - the data gathered also allows missing areas to be spotted so that if a room claimed to belong to an area that was not included in the preceding areas' data an unnamed area is created for it. As a consequence of the long time to actually parse an XML map file I have enhanced the progress dialog that was originally used to track the map file download. It is now retained until the file is completely imported and shows more information about the process - importantly it shows during the XMLimport::readRoom(...) the room id being processed - and THAT method is the time/cpu hog so seeing something happening during the time that Mudlet otherwise appears to hang is useful feedback even if it adds a few seconds to the overall duration (may be more than a minute). This dialog is now also used during the other routes that involve reading an XML file and there is now a bit of consistence with the on-screen messages. Whilst inspecting XMLimport class I found there was some uncertain initialisation which I have tidied up. In summary: Added: * (bool) TConsole::importMap(const QString & location) * (void) TRoomDB::setAreaRooms(const int areaId, const QSet<int> & roomIds) * image file mudlet_map_download.png used as icon for download/import progress dialog * (bool) TMap::importMap(QFile & file) * (bool) TMap::readXmlMapFile(QFile & file) * (void) TMap::slot_downloadError(QNetworkReply::NetworkError error) * (void) TMap::reportStringToProgressDialog(const QString text) * (void) TMap::reportProgressToProgressDialog(const int current, const int maximum) Revised: * (int)TLuaInterpreter::loadMap( lua_State * ) * Moved XML map download code from dlgMapper class to the TMap one: + (void) dlgMapper::downloadMap() ==> (bool) TMap::downloadMap(const QString * remoteUrl, const QString * localFileName) + (void) dlgMapper::setDownloadProgress(qint64, qint64) ==> (void) TMap::slot_setDownloadProgress(qint64,qint64) + (void) dlgMapper::cancel() ==> (void) TMap::slot_downloadCancel() + (void) dlgMapper::replyFinished(QNetworkReply *) ==> (void) TMap::slot_replyFinished(QNetworkReply *) * Enhanced download progress indication to also include parsing which can take even more time than download! * Provide means to import local XML map file * Prevent trying to import/download more than one map at a time Renamed: * (void) XMLimport::readAreaNames() ==> XMLimport::readArea() - for consistency with related functions Commented out unused: * (void) XMLimport::readUnknownRoomElement() Note the movement of the map file download code to the TMap class does require making the latter a class with the Q_OBJECT macro (which removes the need for Q_DECLARE_TR_FUNCTIONS as a side-effect!) - though as another side-effect the TMap header needed a boost name specifier added to one identifier as that identifier ("property") exists in both boost and QObject classes!!! YOU MAY NEED TO RUN QMAKE ON THE PROJECT IF THE BUILD SYSTEM DOES NOT PICK UP THE ADDITION OF "Q_OBJECT" TO TMAP CLASS. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: Include missing #include, remove unused return value The absence of this was causing build errors on the Travis C.I. platform! Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: move TMap.h to mudlet_MOC_HDRS to fix CMake build issue As we have made TMap inherit from QOject - to have signal/slot functionality that class needs to be run through Qt's MOC - and to do that with the CMake project/build system it needs to be included in the files included in the projects *_MOC_HDRS {and removed from the *_HDRS} variable. Also spotted a trivial error in that specifying a const return value from method is ineffective and pointless - so removed it from: TMap::retrieveMapFileStats(QString,QString *,int *,int *,int *,int *) Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: clean up TMap initialisation/clearing actions Now restores the customEnvColors set up on initialisation but that was cleared when the map replaced with another one that is loaded {which subsequently replaces that element anyway} or imported {which merely writes over it, replacing any matching keys}. Initialises elements that when inspected on the entry to the constructor proper previously were not being set to a consistent value {booleans/ints/floats}. NOTE: This will now clear the map user data member when the map is cleared if the date is required to be saved when one map is loaded OR IMPORTED over an existing one then the data will need to be saved outside of the map - as is already need for areas and rooms user data! Also comment out or remove unused members/methods: * (void) TMap::getConnectedNodesGreaterThanX(int, int) * (void) TMap::getConnectedNodesSmallerThanX(int, int) * (void) TMap::getConnectedNodesGreaterThanY(int, int) * (void) TMap::getConnectedNodesSmallerThanY(int, int) * (void) TMap::astBreitenAnpassung(int, int) * (void) TMap::astHoehenAnpassung(int, int) * (void) TMap::exportMapToDatabase() * (void) TMap::importMapFromDatabase() * (QVector3D) TMap::span * (int) TMap::mViewArea * (QMap<QString, int>) TMap::pixNameTable * (QMap<int, QPixmap>) TMap::pixTable * (bool) TMap::isToDisplayAuditErrorsToConsole Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * ImplimentationFixes: activate a valid optimisation & remove redundant code Adding a true as a non-default 3rd argument to TRoomDB::addRoom(...) call in XMLimport::readRoom(...) enables a significant optimisation (skips a computationally expensive step when ADDING a room to new map) which dramatically reduces the time to parse an XML map file. It also pointed to the fact that the TRoomDB::entranceMap was already correctly being handled and didn't need to be regenerated in XMLimport::readRoom(...) so the code that was added in a previous commit was redundant and could be removed. A code error in TMap::slot_setDownloadProgress(...) that caused an issue that a reviewer found on test has been fixed - the total download filesize that was being sent by the Qt system signal that is connected to this slot was a -1 value (as IS DOCUMENTED) when the Qt system does NOT know the size of a QNetworkReply in advance of reaching the end of the download was incorrectly handled in a previous commit in this change set. Also found during testing that there is no need for an error message for the QNetworkReply::OperationCanceledError case in TMap::slot_replayFinished(...) as it is already handled in the TMap::slot_downloadCancel() slot. Changed the text put up onto the progress widget during the XML room parsing to be a room count - which is likely more useful and to only do it for every hundredth room - which reduces any delay "wasted" in writing to the display - combined, the effects seem satisfactory IMHO. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: provide error messages for TLuaInterpreter::loadMap(...) Errors for the XML map file importing process as initiated from the Lua command should be returned to that command rather than plastered onto the main profile console - this commit attempts to perform that effect. In testing found that there was no error handling for failure to find or open the nominated file so messages for that have been added as well. Due to the previous program logic the action of creating a mapper widget using the main toolbar button automatically loaded the "default" (the newest Mudlet Map file format file from the currently active profile's map sub-directory). Under some previous situations it looked as though a map might be loaded twice as mudlet::slot_mapper() was called both directly and via signal/slot action. These were resolved by turning that slot into a wrapper that now calls the body of code formerly within to a new method mudlet::createMapper( bool isToLoadDefaultMapFile = true ) with a the default value as an argument. This allows other usages of the body of code to be called directly with a suitable argument, which for the TConsole::loadMap() & TConsole::importMap() and the dlgProfilePreferences::downloadMap() cases is false as they are all do not want the "default" map! Also: * spotted a word "area" missing from an advisory text in TRoom::auditRooms(...). Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: fix minor bug, correct a spelling, undo a few capitalisations Under certain, unanticipated (error with no error message) conditions TLuaInterpreter::loadMap(...) would push both a nil and then a false value onto the stack for return {wrong} but only indicate one value {correct}. The textual matters were found during peer review. off-by: Stephen Lyons <slysven@virginmedia.com>
2016-10-13 09:18:48 +01:00
}
void TMap::slot_downloadCancel()
{
QString alertMsg = tr("[ ALERT ] - Map download was canceled, on user's request.");
postMessage(alertMsg);
if (mpProgressDialog) {
Enhance: fix map downloading code, add manual XML map importing (#326) * Enhance: fix map downloading code, add manual XML map importing A recent move by I.R.E. to using SSL for their public MUD map URLs broke the ability for Mudlet to download those XML format files. This commit addresses this issue (as mentioned in, but not the original problem referred to in https://bugs.launchpad.net/mudlet/+bug/1427364) the revision to the code does now use "https://www.<MUD URL>/maps/map.xml" as a default name for the I.R.E. MUDS - however the method that initiates the download which was moved to TMap class from the dlgMapper one (see below) is now: (bool) TMap::downloadMap( const QString * remoteUrl = Q_NULLPTR, const QString * localFileName = Q_NULLPTR ) which if not supplied with any arguments behaves as before. However the remoteUrl argument may be given as a full QString including the scheme (the bit of the URL at the beginning before the ':') to override that and a second argument may be used to provide a different name to use for the local file name which if is a RELATIVE pathFileName will be resolved in relation to the profile directory. At present no use is made of this additional functionality but it may be useful for use with other MUDs if they should choose to provide XML map files with other remote locations and scripts using a different local filename. As a long-standing thing that needed doing I have finally provided a means to import a map XML file that - for instance - has already been download. It had been noted that there was no way to read those I.R.E. map files even if they had been obtained from a web browser able to correctly handle https: URLs - now both the TLuaInterpreter::loadMap() and the dlgProfilePreference "loadMap" button {NOT the IRE only "map download" one} will both handle files ending in ".xml" (not case sensitive so it'll work MacOS platforms as well!} For the loadMap case it will be necessary to change the filetype filter on the File Selection dialog to select "xml" files. During testing it became clear to me that it was possible to try and read one or more XML files via several mechanisms simultaneously with "unhelpful" consequences. As well as hitting the dlgProfilePreferences IRE "map download" multiple times, the TLuaInterpreter::loadMap() does NOT block until the map has been loaded and as the import time {running of XMLinport::readPackage(...)} is of significant duration for a large map (a debug, without optimisation, build on my 1.8GHz Quad-core took over two minutes to process the current Achaea map file) it is very possible to get conditions where the same profile will try to run XMLinport::readPackage(...) asynchronously - given that a profile only supports ONE map at a time it was necessary to fit a QMutex to prevent the part of the XMLinport class relating to XML Map files being called from different places in the map related code. This means that if a map download is started further downloads and any local map imports will fail until that first download has completed or aborted. Similarly a local import will prevent a download being started. As a side effect this cures: https://bugs.launchpad.net/mudlet/+bug/852861 - "Map download button starts another download thread if one is already going" The previous XML import code was not adding the rooms that it parsed to the relevant TArea::rooms member - although this would be picked-up and fixed by TMap::audit() later on, this would be accompanied by an error message about every single room. The code now builds up this information while parsing the rooms' details and inserts it so that this does not cause report-able problems during the TMap::audit() execution - the data gathered also allows missing areas to be spotted so that if a room claimed to belong to an area that was not included in the preceding areas' data an unnamed area is created for it. As a consequence of the long time to actually parse an XML map file I have enhanced the progress dialog that was originally used to track the map file download. It is now retained until the file is completely imported and shows more information about the process - importantly it shows during the XMLimport::readRoom(...) the room id being processed - and THAT method is the time/cpu hog so seeing something happening during the time that Mudlet otherwise appears to hang is useful feedback even if it adds a few seconds to the overall duration (may be more than a minute). This dialog is now also used during the other routes that involve reading an XML file and there is now a bit of consistence with the on-screen messages. Whilst inspecting XMLimport class I found there was some uncertain initialisation which I have tidied up. In summary: Added: * (bool) TConsole::importMap(const QString & location) * (void) TRoomDB::setAreaRooms(const int areaId, const QSet<int> & roomIds) * image file mudlet_map_download.png used as icon for download/import progress dialog * (bool) TMap::importMap(QFile & file) * (bool) TMap::readXmlMapFile(QFile & file) * (void) TMap::slot_downloadError(QNetworkReply::NetworkError error) * (void) TMap::reportStringToProgressDialog(const QString text) * (void) TMap::reportProgressToProgressDialog(const int current, const int maximum) Revised: * (int)TLuaInterpreter::loadMap( lua_State * ) * Moved XML map download code from dlgMapper class to the TMap one: + (void) dlgMapper::downloadMap() ==> (bool) TMap::downloadMap(const QString * remoteUrl, const QString * localFileName) + (void) dlgMapper::setDownloadProgress(qint64, qint64) ==> (void) TMap::slot_setDownloadProgress(qint64,qint64) + (void) dlgMapper::cancel() ==> (void) TMap::slot_downloadCancel() + (void) dlgMapper::replyFinished(QNetworkReply *) ==> (void) TMap::slot_replyFinished(QNetworkReply *) * Enhanced download progress indication to also include parsing which can take even more time than download! * Provide means to import local XML map file * Prevent trying to import/download more than one map at a time Renamed: * (void) XMLimport::readAreaNames() ==> XMLimport::readArea() - for consistency with related functions Commented out unused: * (void) XMLimport::readUnknownRoomElement() Note the movement of the map file download code to the TMap class does require making the latter a class with the Q_OBJECT macro (which removes the need for Q_DECLARE_TR_FUNCTIONS as a side-effect!) - though as another side-effect the TMap header needed a boost name specifier added to one identifier as that identifier ("property") exists in both boost and QObject classes!!! YOU MAY NEED TO RUN QMAKE ON THE PROJECT IF THE BUILD SYSTEM DOES NOT PICK UP THE ADDITION OF "Q_OBJECT" TO TMAP CLASS. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: Include missing #include, remove unused return value The absence of this was causing build errors on the Travis C.I. platform! Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: move TMap.h to mudlet_MOC_HDRS to fix CMake build issue As we have made TMap inherit from QOject - to have signal/slot functionality that class needs to be run through Qt's MOC - and to do that with the CMake project/build system it needs to be included in the files included in the projects *_MOC_HDRS {and removed from the *_HDRS} variable. Also spotted a trivial error in that specifying a const return value from method is ineffective and pointless - so removed it from: TMap::retrieveMapFileStats(QString,QString *,int *,int *,int *,int *) Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: clean up TMap initialisation/clearing actions Now restores the customEnvColors set up on initialisation but that was cleared when the map replaced with another one that is loaded {which subsequently replaces that element anyway} or imported {which merely writes over it, replacing any matching keys}. Initialises elements that when inspected on the entry to the constructor proper previously were not being set to a consistent value {booleans/ints/floats}. NOTE: This will now clear the map user data member when the map is cleared if the date is required to be saved when one map is loaded OR IMPORTED over an existing one then the data will need to be saved outside of the map - as is already need for areas and rooms user data! Also comment out or remove unused members/methods: * (void) TMap::getConnectedNodesGreaterThanX(int, int) * (void) TMap::getConnectedNodesSmallerThanX(int, int) * (void) TMap::getConnectedNodesGreaterThanY(int, int) * (void) TMap::getConnectedNodesSmallerThanY(int, int) * (void) TMap::astBreitenAnpassung(int, int) * (void) TMap::astHoehenAnpassung(int, int) * (void) TMap::exportMapToDatabase() * (void) TMap::importMapFromDatabase() * (QVector3D) TMap::span * (int) TMap::mViewArea * (QMap<QString, int>) TMap::pixNameTable * (QMap<int, QPixmap>) TMap::pixTable * (bool) TMap::isToDisplayAuditErrorsToConsole Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * ImplimentationFixes: activate a valid optimisation & remove redundant code Adding a true as a non-default 3rd argument to TRoomDB::addRoom(...) call in XMLimport::readRoom(...) enables a significant optimisation (skips a computationally expensive step when ADDING a room to new map) which dramatically reduces the time to parse an XML map file. It also pointed to the fact that the TRoomDB::entranceMap was already correctly being handled and didn't need to be regenerated in XMLimport::readRoom(...) so the code that was added in a previous commit was redundant and could be removed. A code error in TMap::slot_setDownloadProgress(...) that caused an issue that a reviewer found on test has been fixed - the total download filesize that was being sent by the Qt system signal that is connected to this slot was a -1 value (as IS DOCUMENTED) when the Qt system does NOT know the size of a QNetworkReply in advance of reaching the end of the download was incorrectly handled in a previous commit in this change set. Also found during testing that there is no need for an error message for the QNetworkReply::OperationCanceledError case in TMap::slot_replayFinished(...) as it is already handled in the TMap::slot_downloadCancel() slot. Changed the text put up onto the progress widget during the XML room parsing to be a room count - which is likely more useful and to only do it for every hundredth room - which reduces any delay "wasted" in writing to the display - combined, the effects seem satisfactory IMHO. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: provide error messages for TLuaInterpreter::loadMap(...) Errors for the XML map file importing process as initiated from the Lua command should be returned to that command rather than plastered onto the main profile console - this commit attempts to perform that effect. In testing found that there was no error handling for failure to find or open the nominated file so messages for that have been added as well. Due to the previous program logic the action of creating a mapper widget using the main toolbar button automatically loaded the "default" (the newest Mudlet Map file format file from the currently active profile's map sub-directory). Under some previous situations it looked as though a map might be loaded twice as mudlet::slot_mapper() was called both directly and via signal/slot action. These were resolved by turning that slot into a wrapper that now calls the body of code formerly within to a new method mudlet::createMapper( bool isToLoadDefaultMapFile = true ) with a the default value as an argument. This allows other usages of the body of code to be called directly with a suitable argument, which for the TConsole::loadMap() & TConsole::importMap() and the dlgProfilePreferences::downloadMap() cases is false as they are all do not want the "default" map! Also: * spotted a word "area" missing from an advisory text in TRoom::auditRooms(...). Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: fix minor bug, correct a spelling, undo a few capitalisations Under certain, unanticipated (error with no error message) conditions TLuaInterpreter::loadMap(...) would push both a nil and then a false value onto the stack for return {wrong} but only indicate one value {correct}. The textual matters were found during peer review. off-by: Stephen Lyons <slysven@virginmedia.com>
2016-10-13 09:18:48 +01:00
mpProgressDialog->deleteLater();
mpProgressDialog = Q_NULLPTR; // Must reset this so it can be reused
}
if (mpNetworkReply) {
Enhance: fix map downloading code, add manual XML map importing (#326) * Enhance: fix map downloading code, add manual XML map importing A recent move by I.R.E. to using SSL for their public MUD map URLs broke the ability for Mudlet to download those XML format files. This commit addresses this issue (as mentioned in, but not the original problem referred to in https://bugs.launchpad.net/mudlet/+bug/1427364) the revision to the code does now use "https://www.<MUD URL>/maps/map.xml" as a default name for the I.R.E. MUDS - however the method that initiates the download which was moved to TMap class from the dlgMapper one (see below) is now: (bool) TMap::downloadMap( const QString * remoteUrl = Q_NULLPTR, const QString * localFileName = Q_NULLPTR ) which if not supplied with any arguments behaves as before. However the remoteUrl argument may be given as a full QString including the scheme (the bit of the URL at the beginning before the ':') to override that and a second argument may be used to provide a different name to use for the local file name which if is a RELATIVE pathFileName will be resolved in relation to the profile directory. At present no use is made of this additional functionality but it may be useful for use with other MUDs if they should choose to provide XML map files with other remote locations and scripts using a different local filename. As a long-standing thing that needed doing I have finally provided a means to import a map XML file that - for instance - has already been download. It had been noted that there was no way to read those I.R.E. map files even if they had been obtained from a web browser able to correctly handle https: URLs - now both the TLuaInterpreter::loadMap() and the dlgProfilePreference "loadMap" button {NOT the IRE only "map download" one} will both handle files ending in ".xml" (not case sensitive so it'll work MacOS platforms as well!} For the loadMap case it will be necessary to change the filetype filter on the File Selection dialog to select "xml" files. During testing it became clear to me that it was possible to try and read one or more XML files via several mechanisms simultaneously with "unhelpful" consequences. As well as hitting the dlgProfilePreferences IRE "map download" multiple times, the TLuaInterpreter::loadMap() does NOT block until the map has been loaded and as the import time {running of XMLinport::readPackage(...)} is of significant duration for a large map (a debug, without optimisation, build on my 1.8GHz Quad-core took over two minutes to process the current Achaea map file) it is very possible to get conditions where the same profile will try to run XMLinport::readPackage(...) asynchronously - given that a profile only supports ONE map at a time it was necessary to fit a QMutex to prevent the part of the XMLinport class relating to XML Map files being called from different places in the map related code. This means that if a map download is started further downloads and any local map imports will fail until that first download has completed or aborted. Similarly a local import will prevent a download being started. As a side effect this cures: https://bugs.launchpad.net/mudlet/+bug/852861 - "Map download button starts another download thread if one is already going" The previous XML import code was not adding the rooms that it parsed to the relevant TArea::rooms member - although this would be picked-up and fixed by TMap::audit() later on, this would be accompanied by an error message about every single room. The code now builds up this information while parsing the rooms' details and inserts it so that this does not cause report-able problems during the TMap::audit() execution - the data gathered also allows missing areas to be spotted so that if a room claimed to belong to an area that was not included in the preceding areas' data an unnamed area is created for it. As a consequence of the long time to actually parse an XML map file I have enhanced the progress dialog that was originally used to track the map file download. It is now retained until the file is completely imported and shows more information about the process - importantly it shows during the XMLimport::readRoom(...) the room id being processed - and THAT method is the time/cpu hog so seeing something happening during the time that Mudlet otherwise appears to hang is useful feedback even if it adds a few seconds to the overall duration (may be more than a minute). This dialog is now also used during the other routes that involve reading an XML file and there is now a bit of consistence with the on-screen messages. Whilst inspecting XMLimport class I found there was some uncertain initialisation which I have tidied up. In summary: Added: * (bool) TConsole::importMap(const QString & location) * (void) TRoomDB::setAreaRooms(const int areaId, const QSet<int> & roomIds) * image file mudlet_map_download.png used as icon for download/import progress dialog * (bool) TMap::importMap(QFile & file) * (bool) TMap::readXmlMapFile(QFile & file) * (void) TMap::slot_downloadError(QNetworkReply::NetworkError error) * (void) TMap::reportStringToProgressDialog(const QString text) * (void) TMap::reportProgressToProgressDialog(const int current, const int maximum) Revised: * (int)TLuaInterpreter::loadMap( lua_State * ) * Moved XML map download code from dlgMapper class to the TMap one: + (void) dlgMapper::downloadMap() ==> (bool) TMap::downloadMap(const QString * remoteUrl, const QString * localFileName) + (void) dlgMapper::setDownloadProgress(qint64, qint64) ==> (void) TMap::slot_setDownloadProgress(qint64,qint64) + (void) dlgMapper::cancel() ==> (void) TMap::slot_downloadCancel() + (void) dlgMapper::replyFinished(QNetworkReply *) ==> (void) TMap::slot_replyFinished(QNetworkReply *) * Enhanced download progress indication to also include parsing which can take even more time than download! * Provide means to import local XML map file * Prevent trying to import/download more than one map at a time Renamed: * (void) XMLimport::readAreaNames() ==> XMLimport::readArea() - for consistency with related functions Commented out unused: * (void) XMLimport::readUnknownRoomElement() Note the movement of the map file download code to the TMap class does require making the latter a class with the Q_OBJECT macro (which removes the need for Q_DECLARE_TR_FUNCTIONS as a side-effect!) - though as another side-effect the TMap header needed a boost name specifier added to one identifier as that identifier ("property") exists in both boost and QObject classes!!! YOU MAY NEED TO RUN QMAKE ON THE PROJECT IF THE BUILD SYSTEM DOES NOT PICK UP THE ADDITION OF "Q_OBJECT" TO TMAP CLASS. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: Include missing #include, remove unused return value The absence of this was causing build errors on the Travis C.I. platform! Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: move TMap.h to mudlet_MOC_HDRS to fix CMake build issue As we have made TMap inherit from QOject - to have signal/slot functionality that class needs to be run through Qt's MOC - and to do that with the CMake project/build system it needs to be included in the files included in the projects *_MOC_HDRS {and removed from the *_HDRS} variable. Also spotted a trivial error in that specifying a const return value from method is ineffective and pointless - so removed it from: TMap::retrieveMapFileStats(QString,QString *,int *,int *,int *,int *) Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: clean up TMap initialisation/clearing actions Now restores the customEnvColors set up on initialisation but that was cleared when the map replaced with another one that is loaded {which subsequently replaces that element anyway} or imported {which merely writes over it, replacing any matching keys}. Initialises elements that when inspected on the entry to the constructor proper previously were not being set to a consistent value {booleans/ints/floats}. NOTE: This will now clear the map user data member when the map is cleared if the date is required to be saved when one map is loaded OR IMPORTED over an existing one then the data will need to be saved outside of the map - as is already need for areas and rooms user data! Also comment out or remove unused members/methods: * (void) TMap::getConnectedNodesGreaterThanX(int, int) * (void) TMap::getConnectedNodesSmallerThanX(int, int) * (void) TMap::getConnectedNodesGreaterThanY(int, int) * (void) TMap::getConnectedNodesSmallerThanY(int, int) * (void) TMap::astBreitenAnpassung(int, int) * (void) TMap::astHoehenAnpassung(int, int) * (void) TMap::exportMapToDatabase() * (void) TMap::importMapFromDatabase() * (QVector3D) TMap::span * (int) TMap::mViewArea * (QMap<QString, int>) TMap::pixNameTable * (QMap<int, QPixmap>) TMap::pixTable * (bool) TMap::isToDisplayAuditErrorsToConsole Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * ImplimentationFixes: activate a valid optimisation & remove redundant code Adding a true as a non-default 3rd argument to TRoomDB::addRoom(...) call in XMLimport::readRoom(...) enables a significant optimisation (skips a computationally expensive step when ADDING a room to new map) which dramatically reduces the time to parse an XML map file. It also pointed to the fact that the TRoomDB::entranceMap was already correctly being handled and didn't need to be regenerated in XMLimport::readRoom(...) so the code that was added in a previous commit was redundant and could be removed. A code error in TMap::slot_setDownloadProgress(...) that caused an issue that a reviewer found on test has been fixed - the total download filesize that was being sent by the Qt system signal that is connected to this slot was a -1 value (as IS DOCUMENTED) when the Qt system does NOT know the size of a QNetworkReply in advance of reaching the end of the download was incorrectly handled in a previous commit in this change set. Also found during testing that there is no need for an error message for the QNetworkReply::OperationCanceledError case in TMap::slot_replayFinished(...) as it is already handled in the TMap::slot_downloadCancel() slot. Changed the text put up onto the progress widget during the XML room parsing to be a room count - which is likely more useful and to only do it for every hundredth room - which reduces any delay "wasted" in writing to the display - combined, the effects seem satisfactory IMHO. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: provide error messages for TLuaInterpreter::loadMap(...) Errors for the XML map file importing process as initiated from the Lua command should be returned to that command rather than plastered onto the main profile console - this commit attempts to perform that effect. In testing found that there was no error handling for failure to find or open the nominated file so messages for that have been added as well. Due to the previous program logic the action of creating a mapper widget using the main toolbar button automatically loaded the "default" (the newest Mudlet Map file format file from the currently active profile's map sub-directory). Under some previous situations it looked as though a map might be loaded twice as mudlet::slot_mapper() was called both directly and via signal/slot action. These were resolved by turning that slot into a wrapper that now calls the body of code formerly within to a new method mudlet::createMapper( bool isToLoadDefaultMapFile = true ) with a the default value as an argument. This allows other usages of the body of code to be called directly with a suitable argument, which for the TConsole::loadMap() & TConsole::importMap() and the dlgProfilePreferences::downloadMap() cases is false as they are all do not want the "default" map! Also: * spotted a word "area" missing from an advisory text in TRoom::auditRooms(...). Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: fix minor bug, correct a spelling, undo a few capitalisations Under certain, unanticipated (error with no error message) conditions TLuaInterpreter::loadMap(...) would push both a nil and then a false value onto the stack for return {wrong} but only indicate one value {correct}. The textual matters were found during peer review. off-by: Stephen Lyons <slysven@virginmedia.com>
2016-10-13 09:18:48 +01:00
mpNetworkReply->abort(); // Will indirectly cause error() AND replyFinished signals to be sent
}
}
void TMap::slot_downloadError(QNetworkReply::NetworkError error)
Enhance: fix map downloading code, add manual XML map importing (#326) * Enhance: fix map downloading code, add manual XML map importing A recent move by I.R.E. to using SSL for their public MUD map URLs broke the ability for Mudlet to download those XML format files. This commit addresses this issue (as mentioned in, but not the original problem referred to in https://bugs.launchpad.net/mudlet/+bug/1427364) the revision to the code does now use "https://www.<MUD URL>/maps/map.xml" as a default name for the I.R.E. MUDS - however the method that initiates the download which was moved to TMap class from the dlgMapper one (see below) is now: (bool) TMap::downloadMap( const QString * remoteUrl = Q_NULLPTR, const QString * localFileName = Q_NULLPTR ) which if not supplied with any arguments behaves as before. However the remoteUrl argument may be given as a full QString including the scheme (the bit of the URL at the beginning before the ':') to override that and a second argument may be used to provide a different name to use for the local file name which if is a RELATIVE pathFileName will be resolved in relation to the profile directory. At present no use is made of this additional functionality but it may be useful for use with other MUDs if they should choose to provide XML map files with other remote locations and scripts using a different local filename. As a long-standing thing that needed doing I have finally provided a means to import a map XML file that - for instance - has already been download. It had been noted that there was no way to read those I.R.E. map files even if they had been obtained from a web browser able to correctly handle https: URLs - now both the TLuaInterpreter::loadMap() and the dlgProfilePreference "loadMap" button {NOT the IRE only "map download" one} will both handle files ending in ".xml" (not case sensitive so it'll work MacOS platforms as well!} For the loadMap case it will be necessary to change the filetype filter on the File Selection dialog to select "xml" files. During testing it became clear to me that it was possible to try and read one or more XML files via several mechanisms simultaneously with "unhelpful" consequences. As well as hitting the dlgProfilePreferences IRE "map download" multiple times, the TLuaInterpreter::loadMap() does NOT block until the map has been loaded and as the import time {running of XMLinport::readPackage(...)} is of significant duration for a large map (a debug, without optimisation, build on my 1.8GHz Quad-core took over two minutes to process the current Achaea map file) it is very possible to get conditions where the same profile will try to run XMLinport::readPackage(...) asynchronously - given that a profile only supports ONE map at a time it was necessary to fit a QMutex to prevent the part of the XMLinport class relating to XML Map files being called from different places in the map related code. This means that if a map download is started further downloads and any local map imports will fail until that first download has completed or aborted. Similarly a local import will prevent a download being started. As a side effect this cures: https://bugs.launchpad.net/mudlet/+bug/852861 - "Map download button starts another download thread if one is already going" The previous XML import code was not adding the rooms that it parsed to the relevant TArea::rooms member - although this would be picked-up and fixed by TMap::audit() later on, this would be accompanied by an error message about every single room. The code now builds up this information while parsing the rooms' details and inserts it so that this does not cause report-able problems during the TMap::audit() execution - the data gathered also allows missing areas to be spotted so that if a room claimed to belong to an area that was not included in the preceding areas' data an unnamed area is created for it. As a consequence of the long time to actually parse an XML map file I have enhanced the progress dialog that was originally used to track the map file download. It is now retained until the file is completely imported and shows more information about the process - importantly it shows during the XMLimport::readRoom(...) the room id being processed - and THAT method is the time/cpu hog so seeing something happening during the time that Mudlet otherwise appears to hang is useful feedback even if it adds a few seconds to the overall duration (may be more than a minute). This dialog is now also used during the other routes that involve reading an XML file and there is now a bit of consistence with the on-screen messages. Whilst inspecting XMLimport class I found there was some uncertain initialisation which I have tidied up. In summary: Added: * (bool) TConsole::importMap(const QString & location) * (void) TRoomDB::setAreaRooms(const int areaId, const QSet<int> & roomIds) * image file mudlet_map_download.png used as icon for download/import progress dialog * (bool) TMap::importMap(QFile & file) * (bool) TMap::readXmlMapFile(QFile & file) * (void) TMap::slot_downloadError(QNetworkReply::NetworkError error) * (void) TMap::reportStringToProgressDialog(const QString text) * (void) TMap::reportProgressToProgressDialog(const int current, const int maximum) Revised: * (int)TLuaInterpreter::loadMap( lua_State * ) * Moved XML map download code from dlgMapper class to the TMap one: + (void) dlgMapper::downloadMap() ==> (bool) TMap::downloadMap(const QString * remoteUrl, const QString * localFileName) + (void) dlgMapper::setDownloadProgress(qint64, qint64) ==> (void) TMap::slot_setDownloadProgress(qint64,qint64) + (void) dlgMapper::cancel() ==> (void) TMap::slot_downloadCancel() + (void) dlgMapper::replyFinished(QNetworkReply *) ==> (void) TMap::slot_replyFinished(QNetworkReply *) * Enhanced download progress indication to also include parsing which can take even more time than download! * Provide means to import local XML map file * Prevent trying to import/download more than one map at a time Renamed: * (void) XMLimport::readAreaNames() ==> XMLimport::readArea() - for consistency with related functions Commented out unused: * (void) XMLimport::readUnknownRoomElement() Note the movement of the map file download code to the TMap class does require making the latter a class with the Q_OBJECT macro (which removes the need for Q_DECLARE_TR_FUNCTIONS as a side-effect!) - though as another side-effect the TMap header needed a boost name specifier added to one identifier as that identifier ("property") exists in both boost and QObject classes!!! YOU MAY NEED TO RUN QMAKE ON THE PROJECT IF THE BUILD SYSTEM DOES NOT PICK UP THE ADDITION OF "Q_OBJECT" TO TMAP CLASS. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: Include missing #include, remove unused return value The absence of this was causing build errors on the Travis C.I. platform! Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: move TMap.h to mudlet_MOC_HDRS to fix CMake build issue As we have made TMap inherit from QOject - to have signal/slot functionality that class needs to be run through Qt's MOC - and to do that with the CMake project/build system it needs to be included in the files included in the projects *_MOC_HDRS {and removed from the *_HDRS} variable. Also spotted a trivial error in that specifying a const return value from method is ineffective and pointless - so removed it from: TMap::retrieveMapFileStats(QString,QString *,int *,int *,int *,int *) Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: clean up TMap initialisation/clearing actions Now restores the customEnvColors set up on initialisation but that was cleared when the map replaced with another one that is loaded {which subsequently replaces that element anyway} or imported {which merely writes over it, replacing any matching keys}. Initialises elements that when inspected on the entry to the constructor proper previously were not being set to a consistent value {booleans/ints/floats}. NOTE: This will now clear the map user data member when the map is cleared if the date is required to be saved when one map is loaded OR IMPORTED over an existing one then the data will need to be saved outside of the map - as is already need for areas and rooms user data! Also comment out or remove unused members/methods: * (void) TMap::getConnectedNodesGreaterThanX(int, int) * (void) TMap::getConnectedNodesSmallerThanX(int, int) * (void) TMap::getConnectedNodesGreaterThanY(int, int) * (void) TMap::getConnectedNodesSmallerThanY(int, int) * (void) TMap::astBreitenAnpassung(int, int) * (void) TMap::astHoehenAnpassung(int, int) * (void) TMap::exportMapToDatabase() * (void) TMap::importMapFromDatabase() * (QVector3D) TMap::span * (int) TMap::mViewArea * (QMap<QString, int>) TMap::pixNameTable * (QMap<int, QPixmap>) TMap::pixTable * (bool) TMap::isToDisplayAuditErrorsToConsole Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * ImplimentationFixes: activate a valid optimisation & remove redundant code Adding a true as a non-default 3rd argument to TRoomDB::addRoom(...) call in XMLimport::readRoom(...) enables a significant optimisation (skips a computationally expensive step when ADDING a room to new map) which dramatically reduces the time to parse an XML map file. It also pointed to the fact that the TRoomDB::entranceMap was already correctly being handled and didn't need to be regenerated in XMLimport::readRoom(...) so the code that was added in a previous commit was redundant and could be removed. A code error in TMap::slot_setDownloadProgress(...) that caused an issue that a reviewer found on test has been fixed - the total download filesize that was being sent by the Qt system signal that is connected to this slot was a -1 value (as IS DOCUMENTED) when the Qt system does NOT know the size of a QNetworkReply in advance of reaching the end of the download was incorrectly handled in a previous commit in this change set. Also found during testing that there is no need for an error message for the QNetworkReply::OperationCanceledError case in TMap::slot_replayFinished(...) as it is already handled in the TMap::slot_downloadCancel() slot. Changed the text put up onto the progress widget during the XML room parsing to be a room count - which is likely more useful and to only do it for every hundredth room - which reduces any delay "wasted" in writing to the display - combined, the effects seem satisfactory IMHO. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: provide error messages for TLuaInterpreter::loadMap(...) Errors for the XML map file importing process as initiated from the Lua command should be returned to that command rather than plastered onto the main profile console - this commit attempts to perform that effect. In testing found that there was no error handling for failure to find or open the nominated file so messages for that have been added as well. Due to the previous program logic the action of creating a mapper widget using the main toolbar button automatically loaded the "default" (the newest Mudlet Map file format file from the currently active profile's map sub-directory). Under some previous situations it looked as though a map might be loaded twice as mudlet::slot_mapper() was called both directly and via signal/slot action. These were resolved by turning that slot into a wrapper that now calls the body of code formerly within to a new method mudlet::createMapper( bool isToLoadDefaultMapFile = true ) with a the default value as an argument. This allows other usages of the body of code to be called directly with a suitable argument, which for the TConsole::loadMap() & TConsole::importMap() and the dlgProfilePreferences::downloadMap() cases is false as they are all do not want the "default" map! Also: * spotted a word "area" missing from an advisory text in TRoom::auditRooms(...). Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: fix minor bug, correct a spelling, undo a few capitalisations Under certain, unanticipated (error with no error message) conditions TLuaInterpreter::loadMap(...) would push both a nil and then a false value onto the stack for return {wrong} but only indicate one value {correct}. The textual matters were found during peer review. off-by: Stephen Lyons <slysven@virginmedia.com>
2016-10-13 09:18:48 +01:00
{
if (!mpNetworkReply) {
Enhance: fix map downloading code, add manual XML map importing (#326) * Enhance: fix map downloading code, add manual XML map importing A recent move by I.R.E. to using SSL for their public MUD map URLs broke the ability for Mudlet to download those XML format files. This commit addresses this issue (as mentioned in, but not the original problem referred to in https://bugs.launchpad.net/mudlet/+bug/1427364) the revision to the code does now use "https://www.<MUD URL>/maps/map.xml" as a default name for the I.R.E. MUDS - however the method that initiates the download which was moved to TMap class from the dlgMapper one (see below) is now: (bool) TMap::downloadMap( const QString * remoteUrl = Q_NULLPTR, const QString * localFileName = Q_NULLPTR ) which if not supplied with any arguments behaves as before. However the remoteUrl argument may be given as a full QString including the scheme (the bit of the URL at the beginning before the ':') to override that and a second argument may be used to provide a different name to use for the local file name which if is a RELATIVE pathFileName will be resolved in relation to the profile directory. At present no use is made of this additional functionality but it may be useful for use with other MUDs if they should choose to provide XML map files with other remote locations and scripts using a different local filename. As a long-standing thing that needed doing I have finally provided a means to import a map XML file that - for instance - has already been download. It had been noted that there was no way to read those I.R.E. map files even if they had been obtained from a web browser able to correctly handle https: URLs - now both the TLuaInterpreter::loadMap() and the dlgProfilePreference "loadMap" button {NOT the IRE only "map download" one} will both handle files ending in ".xml" (not case sensitive so it'll work MacOS platforms as well!} For the loadMap case it will be necessary to change the filetype filter on the File Selection dialog to select "xml" files. During testing it became clear to me that it was possible to try and read one or more XML files via several mechanisms simultaneously with "unhelpful" consequences. As well as hitting the dlgProfilePreferences IRE "map download" multiple times, the TLuaInterpreter::loadMap() does NOT block until the map has been loaded and as the import time {running of XMLinport::readPackage(...)} is of significant duration for a large map (a debug, without optimisation, build on my 1.8GHz Quad-core took over two minutes to process the current Achaea map file) it is very possible to get conditions where the same profile will try to run XMLinport::readPackage(...) asynchronously - given that a profile only supports ONE map at a time it was necessary to fit a QMutex to prevent the part of the XMLinport class relating to XML Map files being called from different places in the map related code. This means that if a map download is started further downloads and any local map imports will fail until that first download has completed or aborted. Similarly a local import will prevent a download being started. As a side effect this cures: https://bugs.launchpad.net/mudlet/+bug/852861 - "Map download button starts another download thread if one is already going" The previous XML import code was not adding the rooms that it parsed to the relevant TArea::rooms member - although this would be picked-up and fixed by TMap::audit() later on, this would be accompanied by an error message about every single room. The code now builds up this information while parsing the rooms' details and inserts it so that this does not cause report-able problems during the TMap::audit() execution - the data gathered also allows missing areas to be spotted so that if a room claimed to belong to an area that was not included in the preceding areas' data an unnamed area is created for it. As a consequence of the long time to actually parse an XML map file I have enhanced the progress dialog that was originally used to track the map file download. It is now retained until the file is completely imported and shows more information about the process - importantly it shows during the XMLimport::readRoom(...) the room id being processed - and THAT method is the time/cpu hog so seeing something happening during the time that Mudlet otherwise appears to hang is useful feedback even if it adds a few seconds to the overall duration (may be more than a minute). This dialog is now also used during the other routes that involve reading an XML file and there is now a bit of consistence with the on-screen messages. Whilst inspecting XMLimport class I found there was some uncertain initialisation which I have tidied up. In summary: Added: * (bool) TConsole::importMap(const QString & location) * (void) TRoomDB::setAreaRooms(const int areaId, const QSet<int> & roomIds) * image file mudlet_map_download.png used as icon for download/import progress dialog * (bool) TMap::importMap(QFile & file) * (bool) TMap::readXmlMapFile(QFile & file) * (void) TMap::slot_downloadError(QNetworkReply::NetworkError error) * (void) TMap::reportStringToProgressDialog(const QString text) * (void) TMap::reportProgressToProgressDialog(const int current, const int maximum) Revised: * (int)TLuaInterpreter::loadMap( lua_State * ) * Moved XML map download code from dlgMapper class to the TMap one: + (void) dlgMapper::downloadMap() ==> (bool) TMap::downloadMap(const QString * remoteUrl, const QString * localFileName) + (void) dlgMapper::setDownloadProgress(qint64, qint64) ==> (void) TMap::slot_setDownloadProgress(qint64,qint64) + (void) dlgMapper::cancel() ==> (void) TMap::slot_downloadCancel() + (void) dlgMapper::replyFinished(QNetworkReply *) ==> (void) TMap::slot_replyFinished(QNetworkReply *) * Enhanced download progress indication to also include parsing which can take even more time than download! * Provide means to import local XML map file * Prevent trying to import/download more than one map at a time Renamed: * (void) XMLimport::readAreaNames() ==> XMLimport::readArea() - for consistency with related functions Commented out unused: * (void) XMLimport::readUnknownRoomElement() Note the movement of the map file download code to the TMap class does require making the latter a class with the Q_OBJECT macro (which removes the need for Q_DECLARE_TR_FUNCTIONS as a side-effect!) - though as another side-effect the TMap header needed a boost name specifier added to one identifier as that identifier ("property") exists in both boost and QObject classes!!! YOU MAY NEED TO RUN QMAKE ON THE PROJECT IF THE BUILD SYSTEM DOES NOT PICK UP THE ADDITION OF "Q_OBJECT" TO TMAP CLASS. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: Include missing #include, remove unused return value The absence of this was causing build errors on the Travis C.I. platform! Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: move TMap.h to mudlet_MOC_HDRS to fix CMake build issue As we have made TMap inherit from QOject - to have signal/slot functionality that class needs to be run through Qt's MOC - and to do that with the CMake project/build system it needs to be included in the files included in the projects *_MOC_HDRS {and removed from the *_HDRS} variable. Also spotted a trivial error in that specifying a const return value from method is ineffective and pointless - so removed it from: TMap::retrieveMapFileStats(QString,QString *,int *,int *,int *,int *) Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: clean up TMap initialisation/clearing actions Now restores the customEnvColors set up on initialisation but that was cleared when the map replaced with another one that is loaded {which subsequently replaces that element anyway} or imported {which merely writes over it, replacing any matching keys}. Initialises elements that when inspected on the entry to the constructor proper previously were not being set to a consistent value {booleans/ints/floats}. NOTE: This will now clear the map user data member when the map is cleared if the date is required to be saved when one map is loaded OR IMPORTED over an existing one then the data will need to be saved outside of the map - as is already need for areas and rooms user data! Also comment out or remove unused members/methods: * (void) TMap::getConnectedNodesGreaterThanX(int, int) * (void) TMap::getConnectedNodesSmallerThanX(int, int) * (void) TMap::getConnectedNodesGreaterThanY(int, int) * (void) TMap::getConnectedNodesSmallerThanY(int, int) * (void) TMap::astBreitenAnpassung(int, int) * (void) TMap::astHoehenAnpassung(int, int) * (void) TMap::exportMapToDatabase() * (void) TMap::importMapFromDatabase() * (QVector3D) TMap::span * (int) TMap::mViewArea * (QMap<QString, int>) TMap::pixNameTable * (QMap<int, QPixmap>) TMap::pixTable * (bool) TMap::isToDisplayAuditErrorsToConsole Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * ImplimentationFixes: activate a valid optimisation & remove redundant code Adding a true as a non-default 3rd argument to TRoomDB::addRoom(...) call in XMLimport::readRoom(...) enables a significant optimisation (skips a computationally expensive step when ADDING a room to new map) which dramatically reduces the time to parse an XML map file. It also pointed to the fact that the TRoomDB::entranceMap was already correctly being handled and didn't need to be regenerated in XMLimport::readRoom(...) so the code that was added in a previous commit was redundant and could be removed. A code error in TMap::slot_setDownloadProgress(...) that caused an issue that a reviewer found on test has been fixed - the total download filesize that was being sent by the Qt system signal that is connected to this slot was a -1 value (as IS DOCUMENTED) when the Qt system does NOT know the size of a QNetworkReply in advance of reaching the end of the download was incorrectly handled in a previous commit in this change set. Also found during testing that there is no need for an error message for the QNetworkReply::OperationCanceledError case in TMap::slot_replayFinished(...) as it is already handled in the TMap::slot_downloadCancel() slot. Changed the text put up onto the progress widget during the XML room parsing to be a room count - which is likely more useful and to only do it for every hundredth room - which reduces any delay "wasted" in writing to the display - combined, the effects seem satisfactory IMHO. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: provide error messages for TLuaInterpreter::loadMap(...) Errors for the XML map file importing process as initiated from the Lua command should be returned to that command rather than plastered onto the main profile console - this commit attempts to perform that effect. In testing found that there was no error handling for failure to find or open the nominated file so messages for that have been added as well. Due to the previous program logic the action of creating a mapper widget using the main toolbar button automatically loaded the "default" (the newest Mudlet Map file format file from the currently active profile's map sub-directory). Under some previous situations it looked as though a map might be loaded twice as mudlet::slot_mapper() was called both directly and via signal/slot action. These were resolved by turning that slot into a wrapper that now calls the body of code formerly within to a new method mudlet::createMapper( bool isToLoadDefaultMapFile = true ) with a the default value as an argument. This allows other usages of the body of code to be called directly with a suitable argument, which for the TConsole::loadMap() & TConsole::importMap() and the dlgProfilePreferences::downloadMap() cases is false as they are all do not want the "default" map! Also: * spotted a word "area" missing from an advisory text in TRoom::auditRooms(...). Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: fix minor bug, correct a spelling, undo a few capitalisations Under certain, unanticipated (error with no error message) conditions TLuaInterpreter::loadMap(...) would push both a nil and then a false value onto the stack for return {wrong} but only indicate one value {correct}. The textual matters were found during peer review. off-by: Stephen Lyons <slysven@virginmedia.com>
2016-10-13 09:18:48 +01:00
return;
}
if (error != QNetworkReply::OperationCanceledError) {
Enhance: fix map downloading code, add manual XML map importing (#326) * Enhance: fix map downloading code, add manual XML map importing A recent move by I.R.E. to using SSL for their public MUD map URLs broke the ability for Mudlet to download those XML format files. This commit addresses this issue (as mentioned in, but not the original problem referred to in https://bugs.launchpad.net/mudlet/+bug/1427364) the revision to the code does now use "https://www.<MUD URL>/maps/map.xml" as a default name for the I.R.E. MUDS - however the method that initiates the download which was moved to TMap class from the dlgMapper one (see below) is now: (bool) TMap::downloadMap( const QString * remoteUrl = Q_NULLPTR, const QString * localFileName = Q_NULLPTR ) which if not supplied with any arguments behaves as before. However the remoteUrl argument may be given as a full QString including the scheme (the bit of the URL at the beginning before the ':') to override that and a second argument may be used to provide a different name to use for the local file name which if is a RELATIVE pathFileName will be resolved in relation to the profile directory. At present no use is made of this additional functionality but it may be useful for use with other MUDs if they should choose to provide XML map files with other remote locations and scripts using a different local filename. As a long-standing thing that needed doing I have finally provided a means to import a map XML file that - for instance - has already been download. It had been noted that there was no way to read those I.R.E. map files even if they had been obtained from a web browser able to correctly handle https: URLs - now both the TLuaInterpreter::loadMap() and the dlgProfilePreference "loadMap" button {NOT the IRE only "map download" one} will both handle files ending in ".xml" (not case sensitive so it'll work MacOS platforms as well!} For the loadMap case it will be necessary to change the filetype filter on the File Selection dialog to select "xml" files. During testing it became clear to me that it was possible to try and read one or more XML files via several mechanisms simultaneously with "unhelpful" consequences. As well as hitting the dlgProfilePreferences IRE "map download" multiple times, the TLuaInterpreter::loadMap() does NOT block until the map has been loaded and as the import time {running of XMLinport::readPackage(...)} is of significant duration for a large map (a debug, without optimisation, build on my 1.8GHz Quad-core took over two minutes to process the current Achaea map file) it is very possible to get conditions where the same profile will try to run XMLinport::readPackage(...) asynchronously - given that a profile only supports ONE map at a time it was necessary to fit a QMutex to prevent the part of the XMLinport class relating to XML Map files being called from different places in the map related code. This means that if a map download is started further downloads and any local map imports will fail until that first download has completed or aborted. Similarly a local import will prevent a download being started. As a side effect this cures: https://bugs.launchpad.net/mudlet/+bug/852861 - "Map download button starts another download thread if one is already going" The previous XML import code was not adding the rooms that it parsed to the relevant TArea::rooms member - although this would be picked-up and fixed by TMap::audit() later on, this would be accompanied by an error message about every single room. The code now builds up this information while parsing the rooms' details and inserts it so that this does not cause report-able problems during the TMap::audit() execution - the data gathered also allows missing areas to be spotted so that if a room claimed to belong to an area that was not included in the preceding areas' data an unnamed area is created for it. As a consequence of the long time to actually parse an XML map file I have enhanced the progress dialog that was originally used to track the map file download. It is now retained until the file is completely imported and shows more information about the process - importantly it shows during the XMLimport::readRoom(...) the room id being processed - and THAT method is the time/cpu hog so seeing something happening during the time that Mudlet otherwise appears to hang is useful feedback even if it adds a few seconds to the overall duration (may be more than a minute). This dialog is now also used during the other routes that involve reading an XML file and there is now a bit of consistence with the on-screen messages. Whilst inspecting XMLimport class I found there was some uncertain initialisation which I have tidied up. In summary: Added: * (bool) TConsole::importMap(const QString & location) * (void) TRoomDB::setAreaRooms(const int areaId, const QSet<int> & roomIds) * image file mudlet_map_download.png used as icon for download/import progress dialog * (bool) TMap::importMap(QFile & file) * (bool) TMap::readXmlMapFile(QFile & file) * (void) TMap::slot_downloadError(QNetworkReply::NetworkError error) * (void) TMap::reportStringToProgressDialog(const QString text) * (void) TMap::reportProgressToProgressDialog(const int current, const int maximum) Revised: * (int)TLuaInterpreter::loadMap( lua_State * ) * Moved XML map download code from dlgMapper class to the TMap one: + (void) dlgMapper::downloadMap() ==> (bool) TMap::downloadMap(const QString * remoteUrl, const QString * localFileName) + (void) dlgMapper::setDownloadProgress(qint64, qint64) ==> (void) TMap::slot_setDownloadProgress(qint64,qint64) + (void) dlgMapper::cancel() ==> (void) TMap::slot_downloadCancel() + (void) dlgMapper::replyFinished(QNetworkReply *) ==> (void) TMap::slot_replyFinished(QNetworkReply *) * Enhanced download progress indication to also include parsing which can take even more time than download! * Provide means to import local XML map file * Prevent trying to import/download more than one map at a time Renamed: * (void) XMLimport::readAreaNames() ==> XMLimport::readArea() - for consistency with related functions Commented out unused: * (void) XMLimport::readUnknownRoomElement() Note the movement of the map file download code to the TMap class does require making the latter a class with the Q_OBJECT macro (which removes the need for Q_DECLARE_TR_FUNCTIONS as a side-effect!) - though as another side-effect the TMap header needed a boost name specifier added to one identifier as that identifier ("property") exists in both boost and QObject classes!!! YOU MAY NEED TO RUN QMAKE ON THE PROJECT IF THE BUILD SYSTEM DOES NOT PICK UP THE ADDITION OF "Q_OBJECT" TO TMAP CLASS. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: Include missing #include, remove unused return value The absence of this was causing build errors on the Travis C.I. platform! Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: move TMap.h to mudlet_MOC_HDRS to fix CMake build issue As we have made TMap inherit from QOject - to have signal/slot functionality that class needs to be run through Qt's MOC - and to do that with the CMake project/build system it needs to be included in the files included in the projects *_MOC_HDRS {and removed from the *_HDRS} variable. Also spotted a trivial error in that specifying a const return value from method is ineffective and pointless - so removed it from: TMap::retrieveMapFileStats(QString,QString *,int *,int *,int *,int *) Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: clean up TMap initialisation/clearing actions Now restores the customEnvColors set up on initialisation but that was cleared when the map replaced with another one that is loaded {which subsequently replaces that element anyway} or imported {which merely writes over it, replacing any matching keys}. Initialises elements that when inspected on the entry to the constructor proper previously were not being set to a consistent value {booleans/ints/floats}. NOTE: This will now clear the map user data member when the map is cleared if the date is required to be saved when one map is loaded OR IMPORTED over an existing one then the data will need to be saved outside of the map - as is already need for areas and rooms user data! Also comment out or remove unused members/methods: * (void) TMap::getConnectedNodesGreaterThanX(int, int) * (void) TMap::getConnectedNodesSmallerThanX(int, int) * (void) TMap::getConnectedNodesGreaterThanY(int, int) * (void) TMap::getConnectedNodesSmallerThanY(int, int) * (void) TMap::astBreitenAnpassung(int, int) * (void) TMap::astHoehenAnpassung(int, int) * (void) TMap::exportMapToDatabase() * (void) TMap::importMapFromDatabase() * (QVector3D) TMap::span * (int) TMap::mViewArea * (QMap<QString, int>) TMap::pixNameTable * (QMap<int, QPixmap>) TMap::pixTable * (bool) TMap::isToDisplayAuditErrorsToConsole Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * ImplimentationFixes: activate a valid optimisation & remove redundant code Adding a true as a non-default 3rd argument to TRoomDB::addRoom(...) call in XMLimport::readRoom(...) enables a significant optimisation (skips a computationally expensive step when ADDING a room to new map) which dramatically reduces the time to parse an XML map file. It also pointed to the fact that the TRoomDB::entranceMap was already correctly being handled and didn't need to be regenerated in XMLimport::readRoom(...) so the code that was added in a previous commit was redundant and could be removed. A code error in TMap::slot_setDownloadProgress(...) that caused an issue that a reviewer found on test has been fixed - the total download filesize that was being sent by the Qt system signal that is connected to this slot was a -1 value (as IS DOCUMENTED) when the Qt system does NOT know the size of a QNetworkReply in advance of reaching the end of the download was incorrectly handled in a previous commit in this change set. Also found during testing that there is no need for an error message for the QNetworkReply::OperationCanceledError case in TMap::slot_replayFinished(...) as it is already handled in the TMap::slot_downloadCancel() slot. Changed the text put up onto the progress widget during the XML room parsing to be a room count - which is likely more useful and to only do it for every hundredth room - which reduces any delay "wasted" in writing to the display - combined, the effects seem satisfactory IMHO. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: provide error messages for TLuaInterpreter::loadMap(...) Errors for the XML map file importing process as initiated from the Lua command should be returned to that command rather than plastered onto the main profile console - this commit attempts to perform that effect. In testing found that there was no error handling for failure to find or open the nominated file so messages for that have been added as well. Due to the previous program logic the action of creating a mapper widget using the main toolbar button automatically loaded the "default" (the newest Mudlet Map file format file from the currently active profile's map sub-directory). Under some previous situations it looked as though a map might be loaded twice as mudlet::slot_mapper() was called both directly and via signal/slot action. These were resolved by turning that slot into a wrapper that now calls the body of code formerly within to a new method mudlet::createMapper( bool isToLoadDefaultMapFile = true ) with a the default value as an argument. This allows other usages of the body of code to be called directly with a suitable argument, which for the TConsole::loadMap() & TConsole::importMap() and the dlgProfilePreferences::downloadMap() cases is false as they are all do not want the "default" map! Also: * spotted a word "area" missing from an advisory text in TRoom::auditRooms(...). Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: fix minor bug, correct a spelling, undo a few capitalisations Under certain, unanticipated (error with no error message) conditions TLuaInterpreter::loadMap(...) would push both a nil and then a false value onto the stack for return {wrong} but only indicate one value {correct}. The textual matters were found during peer review. off-by: Stephen Lyons <slysven@virginmedia.com>
2016-10-13 09:18:48 +01:00
// No point in reporting Cancel as that is handled elsewhere
QString errMsg = tr("[ ERROR ] - Map download encountered an error:\n%1.").arg(mpNetworkReply->errorString());
postMessage(errMsg);
Enhance: fix map downloading code, add manual XML map importing (#326) * Enhance: fix map downloading code, add manual XML map importing A recent move by I.R.E. to using SSL for their public MUD map URLs broke the ability for Mudlet to download those XML format files. This commit addresses this issue (as mentioned in, but not the original problem referred to in https://bugs.launchpad.net/mudlet/+bug/1427364) the revision to the code does now use "https://www.<MUD URL>/maps/map.xml" as a default name for the I.R.E. MUDS - however the method that initiates the download which was moved to TMap class from the dlgMapper one (see below) is now: (bool) TMap::downloadMap( const QString * remoteUrl = Q_NULLPTR, const QString * localFileName = Q_NULLPTR ) which if not supplied with any arguments behaves as before. However the remoteUrl argument may be given as a full QString including the scheme (the bit of the URL at the beginning before the ':') to override that and a second argument may be used to provide a different name to use for the local file name which if is a RELATIVE pathFileName will be resolved in relation to the profile directory. At present no use is made of this additional functionality but it may be useful for use with other MUDs if they should choose to provide XML map files with other remote locations and scripts using a different local filename. As a long-standing thing that needed doing I have finally provided a means to import a map XML file that - for instance - has already been download. It had been noted that there was no way to read those I.R.E. map files even if they had been obtained from a web browser able to correctly handle https: URLs - now both the TLuaInterpreter::loadMap() and the dlgProfilePreference "loadMap" button {NOT the IRE only "map download" one} will both handle files ending in ".xml" (not case sensitive so it'll work MacOS platforms as well!} For the loadMap case it will be necessary to change the filetype filter on the File Selection dialog to select "xml" files. During testing it became clear to me that it was possible to try and read one or more XML files via several mechanisms simultaneously with "unhelpful" consequences. As well as hitting the dlgProfilePreferences IRE "map download" multiple times, the TLuaInterpreter::loadMap() does NOT block until the map has been loaded and as the import time {running of XMLinport::readPackage(...)} is of significant duration for a large map (a debug, without optimisation, build on my 1.8GHz Quad-core took over two minutes to process the current Achaea map file) it is very possible to get conditions where the same profile will try to run XMLinport::readPackage(...) asynchronously - given that a profile only supports ONE map at a time it was necessary to fit a QMutex to prevent the part of the XMLinport class relating to XML Map files being called from different places in the map related code. This means that if a map download is started further downloads and any local map imports will fail until that first download has completed or aborted. Similarly a local import will prevent a download being started. As a side effect this cures: https://bugs.launchpad.net/mudlet/+bug/852861 - "Map download button starts another download thread if one is already going" The previous XML import code was not adding the rooms that it parsed to the relevant TArea::rooms member - although this would be picked-up and fixed by TMap::audit() later on, this would be accompanied by an error message about every single room. The code now builds up this information while parsing the rooms' details and inserts it so that this does not cause report-able problems during the TMap::audit() execution - the data gathered also allows missing areas to be spotted so that if a room claimed to belong to an area that was not included in the preceding areas' data an unnamed area is created for it. As a consequence of the long time to actually parse an XML map file I have enhanced the progress dialog that was originally used to track the map file download. It is now retained until the file is completely imported and shows more information about the process - importantly it shows during the XMLimport::readRoom(...) the room id being processed - and THAT method is the time/cpu hog so seeing something happening during the time that Mudlet otherwise appears to hang is useful feedback even if it adds a few seconds to the overall duration (may be more than a minute). This dialog is now also used during the other routes that involve reading an XML file and there is now a bit of consistence with the on-screen messages. Whilst inspecting XMLimport class I found there was some uncertain initialisation which I have tidied up. In summary: Added: * (bool) TConsole::importMap(const QString & location) * (void) TRoomDB::setAreaRooms(const int areaId, const QSet<int> & roomIds) * image file mudlet_map_download.png used as icon for download/import progress dialog * (bool) TMap::importMap(QFile & file) * (bool) TMap::readXmlMapFile(QFile & file) * (void) TMap::slot_downloadError(QNetworkReply::NetworkError error) * (void) TMap::reportStringToProgressDialog(const QString text) * (void) TMap::reportProgressToProgressDialog(const int current, const int maximum) Revised: * (int)TLuaInterpreter::loadMap( lua_State * ) * Moved XML map download code from dlgMapper class to the TMap one: + (void) dlgMapper::downloadMap() ==> (bool) TMap::downloadMap(const QString * remoteUrl, const QString * localFileName) + (void) dlgMapper::setDownloadProgress(qint64, qint64) ==> (void) TMap::slot_setDownloadProgress(qint64,qint64) + (void) dlgMapper::cancel() ==> (void) TMap::slot_downloadCancel() + (void) dlgMapper::replyFinished(QNetworkReply *) ==> (void) TMap::slot_replyFinished(QNetworkReply *) * Enhanced download progress indication to also include parsing which can take even more time than download! * Provide means to import local XML map file * Prevent trying to import/download more than one map at a time Renamed: * (void) XMLimport::readAreaNames() ==> XMLimport::readArea() - for consistency with related functions Commented out unused: * (void) XMLimport::readUnknownRoomElement() Note the movement of the map file download code to the TMap class does require making the latter a class with the Q_OBJECT macro (which removes the need for Q_DECLARE_TR_FUNCTIONS as a side-effect!) - though as another side-effect the TMap header needed a boost name specifier added to one identifier as that identifier ("property") exists in both boost and QObject classes!!! YOU MAY NEED TO RUN QMAKE ON THE PROJECT IF THE BUILD SYSTEM DOES NOT PICK UP THE ADDITION OF "Q_OBJECT" TO TMAP CLASS. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: Include missing #include, remove unused return value The absence of this was causing build errors on the Travis C.I. platform! Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: move TMap.h to mudlet_MOC_HDRS to fix CMake build issue As we have made TMap inherit from QOject - to have signal/slot functionality that class needs to be run through Qt's MOC - and to do that with the CMake project/build system it needs to be included in the files included in the projects *_MOC_HDRS {and removed from the *_HDRS} variable. Also spotted a trivial error in that specifying a const return value from method is ineffective and pointless - so removed it from: TMap::retrieveMapFileStats(QString,QString *,int *,int *,int *,int *) Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: clean up TMap initialisation/clearing actions Now restores the customEnvColors set up on initialisation but that was cleared when the map replaced with another one that is loaded {which subsequently replaces that element anyway} or imported {which merely writes over it, replacing any matching keys}. Initialises elements that when inspected on the entry to the constructor proper previously were not being set to a consistent value {booleans/ints/floats}. NOTE: This will now clear the map user data member when the map is cleared if the date is required to be saved when one map is loaded OR IMPORTED over an existing one then the data will need to be saved outside of the map - as is already need for areas and rooms user data! Also comment out or remove unused members/methods: * (void) TMap::getConnectedNodesGreaterThanX(int, int) * (void) TMap::getConnectedNodesSmallerThanX(int, int) * (void) TMap::getConnectedNodesGreaterThanY(int, int) * (void) TMap::getConnectedNodesSmallerThanY(int, int) * (void) TMap::astBreitenAnpassung(int, int) * (void) TMap::astHoehenAnpassung(int, int) * (void) TMap::exportMapToDatabase() * (void) TMap::importMapFromDatabase() * (QVector3D) TMap::span * (int) TMap::mViewArea * (QMap<QString, int>) TMap::pixNameTable * (QMap<int, QPixmap>) TMap::pixTable * (bool) TMap::isToDisplayAuditErrorsToConsole Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * ImplimentationFixes: activate a valid optimisation & remove redundant code Adding a true as a non-default 3rd argument to TRoomDB::addRoom(...) call in XMLimport::readRoom(...) enables a significant optimisation (skips a computationally expensive step when ADDING a room to new map) which dramatically reduces the time to parse an XML map file. It also pointed to the fact that the TRoomDB::entranceMap was already correctly being handled and didn't need to be regenerated in XMLimport::readRoom(...) so the code that was added in a previous commit was redundant and could be removed. A code error in TMap::slot_setDownloadProgress(...) that caused an issue that a reviewer found on test has been fixed - the total download filesize that was being sent by the Qt system signal that is connected to this slot was a -1 value (as IS DOCUMENTED) when the Qt system does NOT know the size of a QNetworkReply in advance of reaching the end of the download was incorrectly handled in a previous commit in this change set. Also found during testing that there is no need for an error message for the QNetworkReply::OperationCanceledError case in TMap::slot_replayFinished(...) as it is already handled in the TMap::slot_downloadCancel() slot. Changed the text put up onto the progress widget during the XML room parsing to be a room count - which is likely more useful and to only do it for every hundredth room - which reduces any delay "wasted" in writing to the display - combined, the effects seem satisfactory IMHO. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: provide error messages for TLuaInterpreter::loadMap(...) Errors for the XML map file importing process as initiated from the Lua command should be returned to that command rather than plastered onto the main profile console - this commit attempts to perform that effect. In testing found that there was no error handling for failure to find or open the nominated file so messages for that have been added as well. Due to the previous program logic the action of creating a mapper widget using the main toolbar button automatically loaded the "default" (the newest Mudlet Map file format file from the currently active profile's map sub-directory). Under some previous situations it looked as though a map might be loaded twice as mudlet::slot_mapper() was called both directly and via signal/slot action. These were resolved by turning that slot into a wrapper that now calls the body of code formerly within to a new method mudlet::createMapper( bool isToLoadDefaultMapFile = true ) with a the default value as an argument. This allows other usages of the body of code to be called directly with a suitable argument, which for the TConsole::loadMap() & TConsole::importMap() and the dlgProfilePreferences::downloadMap() cases is false as they are all do not want the "default" map! Also: * spotted a word "area" missing from an advisory text in TRoom::auditRooms(...). Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: fix minor bug, correct a spelling, undo a few capitalisations Under certain, unanticipated (error with no error message) conditions TLuaInterpreter::loadMap(...) would push both a nil and then a false value onto the stack for return {wrong} but only indicate one value {correct}. The textual matters were found during peer review. off-by: Stephen Lyons <slysven@virginmedia.com>
2016-10-13 09:18:48 +01:00
}
}
void TMap::slot_replyFinished(QNetworkReply* reply)
Enhance: fix map downloading code, add manual XML map importing (#326) * Enhance: fix map downloading code, add manual XML map importing A recent move by I.R.E. to using SSL for their public MUD map URLs broke the ability for Mudlet to download those XML format files. This commit addresses this issue (as mentioned in, but not the original problem referred to in https://bugs.launchpad.net/mudlet/+bug/1427364) the revision to the code does now use "https://www.<MUD URL>/maps/map.xml" as a default name for the I.R.E. MUDS - however the method that initiates the download which was moved to TMap class from the dlgMapper one (see below) is now: (bool) TMap::downloadMap( const QString * remoteUrl = Q_NULLPTR, const QString * localFileName = Q_NULLPTR ) which if not supplied with any arguments behaves as before. However the remoteUrl argument may be given as a full QString including the scheme (the bit of the URL at the beginning before the ':') to override that and a second argument may be used to provide a different name to use for the local file name which if is a RELATIVE pathFileName will be resolved in relation to the profile directory. At present no use is made of this additional functionality but it may be useful for use with other MUDs if they should choose to provide XML map files with other remote locations and scripts using a different local filename. As a long-standing thing that needed doing I have finally provided a means to import a map XML file that - for instance - has already been download. It had been noted that there was no way to read those I.R.E. map files even if they had been obtained from a web browser able to correctly handle https: URLs - now both the TLuaInterpreter::loadMap() and the dlgProfilePreference "loadMap" button {NOT the IRE only "map download" one} will both handle files ending in ".xml" (not case sensitive so it'll work MacOS platforms as well!} For the loadMap case it will be necessary to change the filetype filter on the File Selection dialog to select "xml" files. During testing it became clear to me that it was possible to try and read one or more XML files via several mechanisms simultaneously with "unhelpful" consequences. As well as hitting the dlgProfilePreferences IRE "map download" multiple times, the TLuaInterpreter::loadMap() does NOT block until the map has been loaded and as the import time {running of XMLinport::readPackage(...)} is of significant duration for a large map (a debug, without optimisation, build on my 1.8GHz Quad-core took over two minutes to process the current Achaea map file) it is very possible to get conditions where the same profile will try to run XMLinport::readPackage(...) asynchronously - given that a profile only supports ONE map at a time it was necessary to fit a QMutex to prevent the part of the XMLinport class relating to XML Map files being called from different places in the map related code. This means that if a map download is started further downloads and any local map imports will fail until that first download has completed or aborted. Similarly a local import will prevent a download being started. As a side effect this cures: https://bugs.launchpad.net/mudlet/+bug/852861 - "Map download button starts another download thread if one is already going" The previous XML import code was not adding the rooms that it parsed to the relevant TArea::rooms member - although this would be picked-up and fixed by TMap::audit() later on, this would be accompanied by an error message about every single room. The code now builds up this information while parsing the rooms' details and inserts it so that this does not cause report-able problems during the TMap::audit() execution - the data gathered also allows missing areas to be spotted so that if a room claimed to belong to an area that was not included in the preceding areas' data an unnamed area is created for it. As a consequence of the long time to actually parse an XML map file I have enhanced the progress dialog that was originally used to track the map file download. It is now retained until the file is completely imported and shows more information about the process - importantly it shows during the XMLimport::readRoom(...) the room id being processed - and THAT method is the time/cpu hog so seeing something happening during the time that Mudlet otherwise appears to hang is useful feedback even if it adds a few seconds to the overall duration (may be more than a minute). This dialog is now also used during the other routes that involve reading an XML file and there is now a bit of consistence with the on-screen messages. Whilst inspecting XMLimport class I found there was some uncertain initialisation which I have tidied up. In summary: Added: * (bool) TConsole::importMap(const QString & location) * (void) TRoomDB::setAreaRooms(const int areaId, const QSet<int> & roomIds) * image file mudlet_map_download.png used as icon for download/import progress dialog * (bool) TMap::importMap(QFile & file) * (bool) TMap::readXmlMapFile(QFile & file) * (void) TMap::slot_downloadError(QNetworkReply::NetworkError error) * (void) TMap::reportStringToProgressDialog(const QString text) * (void) TMap::reportProgressToProgressDialog(const int current, const int maximum) Revised: * (int)TLuaInterpreter::loadMap( lua_State * ) * Moved XML map download code from dlgMapper class to the TMap one: + (void) dlgMapper::downloadMap() ==> (bool) TMap::downloadMap(const QString * remoteUrl, const QString * localFileName) + (void) dlgMapper::setDownloadProgress(qint64, qint64) ==> (void) TMap::slot_setDownloadProgress(qint64,qint64) + (void) dlgMapper::cancel() ==> (void) TMap::slot_downloadCancel() + (void) dlgMapper::replyFinished(QNetworkReply *) ==> (void) TMap::slot_replyFinished(QNetworkReply *) * Enhanced download progress indication to also include parsing which can take even more time than download! * Provide means to import local XML map file * Prevent trying to import/download more than one map at a time Renamed: * (void) XMLimport::readAreaNames() ==> XMLimport::readArea() - for consistency with related functions Commented out unused: * (void) XMLimport::readUnknownRoomElement() Note the movement of the map file download code to the TMap class does require making the latter a class with the Q_OBJECT macro (which removes the need for Q_DECLARE_TR_FUNCTIONS as a side-effect!) - though as another side-effect the TMap header needed a boost name specifier added to one identifier as that identifier ("property") exists in both boost and QObject classes!!! YOU MAY NEED TO RUN QMAKE ON THE PROJECT IF THE BUILD SYSTEM DOES NOT PICK UP THE ADDITION OF "Q_OBJECT" TO TMAP CLASS. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: Include missing #include, remove unused return value The absence of this was causing build errors on the Travis C.I. platform! Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: move TMap.h to mudlet_MOC_HDRS to fix CMake build issue As we have made TMap inherit from QOject - to have signal/slot functionality that class needs to be run through Qt's MOC - and to do that with the CMake project/build system it needs to be included in the files included in the projects *_MOC_HDRS {and removed from the *_HDRS} variable. Also spotted a trivial error in that specifying a const return value from method is ineffective and pointless - so removed it from: TMap::retrieveMapFileStats(QString,QString *,int *,int *,int *,int *) Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: clean up TMap initialisation/clearing actions Now restores the customEnvColors set up on initialisation but that was cleared when the map replaced with another one that is loaded {which subsequently replaces that element anyway} or imported {which merely writes over it, replacing any matching keys}. Initialises elements that when inspected on the entry to the constructor proper previously were not being set to a consistent value {booleans/ints/floats}. NOTE: This will now clear the map user data member when the map is cleared if the date is required to be saved when one map is loaded OR IMPORTED over an existing one then the data will need to be saved outside of the map - as is already need for areas and rooms user data! Also comment out or remove unused members/methods: * (void) TMap::getConnectedNodesGreaterThanX(int, int) * (void) TMap::getConnectedNodesSmallerThanX(int, int) * (void) TMap::getConnectedNodesGreaterThanY(int, int) * (void) TMap::getConnectedNodesSmallerThanY(int, int) * (void) TMap::astBreitenAnpassung(int, int) * (void) TMap::astHoehenAnpassung(int, int) * (void) TMap::exportMapToDatabase() * (void) TMap::importMapFromDatabase() * (QVector3D) TMap::span * (int) TMap::mViewArea * (QMap<QString, int>) TMap::pixNameTable * (QMap<int, QPixmap>) TMap::pixTable * (bool) TMap::isToDisplayAuditErrorsToConsole Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * ImplimentationFixes: activate a valid optimisation & remove redundant code Adding a true as a non-default 3rd argument to TRoomDB::addRoom(...) call in XMLimport::readRoom(...) enables a significant optimisation (skips a computationally expensive step when ADDING a room to new map) which dramatically reduces the time to parse an XML map file. It also pointed to the fact that the TRoomDB::entranceMap was already correctly being handled and didn't need to be regenerated in XMLimport::readRoom(...) so the code that was added in a previous commit was redundant and could be removed. A code error in TMap::slot_setDownloadProgress(...) that caused an issue that a reviewer found on test has been fixed - the total download filesize that was being sent by the Qt system signal that is connected to this slot was a -1 value (as IS DOCUMENTED) when the Qt system does NOT know the size of a QNetworkReply in advance of reaching the end of the download was incorrectly handled in a previous commit in this change set. Also found during testing that there is no need for an error message for the QNetworkReply::OperationCanceledError case in TMap::slot_replayFinished(...) as it is already handled in the TMap::slot_downloadCancel() slot. Changed the text put up onto the progress widget during the XML room parsing to be a room count - which is likely more useful and to only do it for every hundredth room - which reduces any delay "wasted" in writing to the display - combined, the effects seem satisfactory IMHO. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: provide error messages for TLuaInterpreter::loadMap(...) Errors for the XML map file importing process as initiated from the Lua command should be returned to that command rather than plastered onto the main profile console - this commit attempts to perform that effect. In testing found that there was no error handling for failure to find or open the nominated file so messages for that have been added as well. Due to the previous program logic the action of creating a mapper widget using the main toolbar button automatically loaded the "default" (the newest Mudlet Map file format file from the currently active profile's map sub-directory). Under some previous situations it looked as though a map might be loaded twice as mudlet::slot_mapper() was called both directly and via signal/slot action. These were resolved by turning that slot into a wrapper that now calls the body of code formerly within to a new method mudlet::createMapper( bool isToLoadDefaultMapFile = true ) with a the default value as an argument. This allows other usages of the body of code to be called directly with a suitable argument, which for the TConsole::loadMap() & TConsole::importMap() and the dlgProfilePreferences::downloadMap() cases is false as they are all do not want the "default" map! Also: * spotted a word "area" missing from an advisory text in TRoom::auditRooms(...). Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: fix minor bug, correct a spelling, undo a few capitalisations Under certain, unanticipated (error with no error message) conditions TLuaInterpreter::loadMap(...) would push both a nil and then a false value onto the stack for return {wrong} but only indicate one value {correct}. The textual matters were found during peer review. off-by: Stephen Lyons <slysven@virginmedia.com>
2016-10-13 09:18:48 +01:00
{
if (reply != mpNetworkReply) {
Enhance: fix map downloading code, add manual XML map importing (#326) * Enhance: fix map downloading code, add manual XML map importing A recent move by I.R.E. to using SSL for their public MUD map URLs broke the ability for Mudlet to download those XML format files. This commit addresses this issue (as mentioned in, but not the original problem referred to in https://bugs.launchpad.net/mudlet/+bug/1427364) the revision to the code does now use "https://www.<MUD URL>/maps/map.xml" as a default name for the I.R.E. MUDS - however the method that initiates the download which was moved to TMap class from the dlgMapper one (see below) is now: (bool) TMap::downloadMap( const QString * remoteUrl = Q_NULLPTR, const QString * localFileName = Q_NULLPTR ) which if not supplied with any arguments behaves as before. However the remoteUrl argument may be given as a full QString including the scheme (the bit of the URL at the beginning before the ':') to override that and a second argument may be used to provide a different name to use for the local file name which if is a RELATIVE pathFileName will be resolved in relation to the profile directory. At present no use is made of this additional functionality but it may be useful for use with other MUDs if they should choose to provide XML map files with other remote locations and scripts using a different local filename. As a long-standing thing that needed doing I have finally provided a means to import a map XML file that - for instance - has already been download. It had been noted that there was no way to read those I.R.E. map files even if they had been obtained from a web browser able to correctly handle https: URLs - now both the TLuaInterpreter::loadMap() and the dlgProfilePreference "loadMap" button {NOT the IRE only "map download" one} will both handle files ending in ".xml" (not case sensitive so it'll work MacOS platforms as well!} For the loadMap case it will be necessary to change the filetype filter on the File Selection dialog to select "xml" files. During testing it became clear to me that it was possible to try and read one or more XML files via several mechanisms simultaneously with "unhelpful" consequences. As well as hitting the dlgProfilePreferences IRE "map download" multiple times, the TLuaInterpreter::loadMap() does NOT block until the map has been loaded and as the import time {running of XMLinport::readPackage(...)} is of significant duration for a large map (a debug, without optimisation, build on my 1.8GHz Quad-core took over two minutes to process the current Achaea map file) it is very possible to get conditions where the same profile will try to run XMLinport::readPackage(...) asynchronously - given that a profile only supports ONE map at a time it was necessary to fit a QMutex to prevent the part of the XMLinport class relating to XML Map files being called from different places in the map related code. This means that if a map download is started further downloads and any local map imports will fail until that first download has completed or aborted. Similarly a local import will prevent a download being started. As a side effect this cures: https://bugs.launchpad.net/mudlet/+bug/852861 - "Map download button starts another download thread if one is already going" The previous XML import code was not adding the rooms that it parsed to the relevant TArea::rooms member - although this would be picked-up and fixed by TMap::audit() later on, this would be accompanied by an error message about every single room. The code now builds up this information while parsing the rooms' details and inserts it so that this does not cause report-able problems during the TMap::audit() execution - the data gathered also allows missing areas to be spotted so that if a room claimed to belong to an area that was not included in the preceding areas' data an unnamed area is created for it. As a consequence of the long time to actually parse an XML map file I have enhanced the progress dialog that was originally used to track the map file download. It is now retained until the file is completely imported and shows more information about the process - importantly it shows during the XMLimport::readRoom(...) the room id being processed - and THAT method is the time/cpu hog so seeing something happening during the time that Mudlet otherwise appears to hang is useful feedback even if it adds a few seconds to the overall duration (may be more than a minute). This dialog is now also used during the other routes that involve reading an XML file and there is now a bit of consistence with the on-screen messages. Whilst inspecting XMLimport class I found there was some uncertain initialisation which I have tidied up. In summary: Added: * (bool) TConsole::importMap(const QString & location) * (void) TRoomDB::setAreaRooms(const int areaId, const QSet<int> & roomIds) * image file mudlet_map_download.png used as icon for download/import progress dialog * (bool) TMap::importMap(QFile & file) * (bool) TMap::readXmlMapFile(QFile & file) * (void) TMap::slot_downloadError(QNetworkReply::NetworkError error) * (void) TMap::reportStringToProgressDialog(const QString text) * (void) TMap::reportProgressToProgressDialog(const int current, const int maximum) Revised: * (int)TLuaInterpreter::loadMap( lua_State * ) * Moved XML map download code from dlgMapper class to the TMap one: + (void) dlgMapper::downloadMap() ==> (bool) TMap::downloadMap(const QString * remoteUrl, const QString * localFileName) + (void) dlgMapper::setDownloadProgress(qint64, qint64) ==> (void) TMap::slot_setDownloadProgress(qint64,qint64) + (void) dlgMapper::cancel() ==> (void) TMap::slot_downloadCancel() + (void) dlgMapper::replyFinished(QNetworkReply *) ==> (void) TMap::slot_replyFinished(QNetworkReply *) * Enhanced download progress indication to also include parsing which can take even more time than download! * Provide means to import local XML map file * Prevent trying to import/download more than one map at a time Renamed: * (void) XMLimport::readAreaNames() ==> XMLimport::readArea() - for consistency with related functions Commented out unused: * (void) XMLimport::readUnknownRoomElement() Note the movement of the map file download code to the TMap class does require making the latter a class with the Q_OBJECT macro (which removes the need for Q_DECLARE_TR_FUNCTIONS as a side-effect!) - though as another side-effect the TMap header needed a boost name specifier added to one identifier as that identifier ("property") exists in both boost and QObject classes!!! YOU MAY NEED TO RUN QMAKE ON THE PROJECT IF THE BUILD SYSTEM DOES NOT PICK UP THE ADDITION OF "Q_OBJECT" TO TMAP CLASS. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: Include missing #include, remove unused return value The absence of this was causing build errors on the Travis C.I. platform! Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: move TMap.h to mudlet_MOC_HDRS to fix CMake build issue As we have made TMap inherit from QOject - to have signal/slot functionality that class needs to be run through Qt's MOC - and to do that with the CMake project/build system it needs to be included in the files included in the projects *_MOC_HDRS {and removed from the *_HDRS} variable. Also spotted a trivial error in that specifying a const return value from method is ineffective and pointless - so removed it from: TMap::retrieveMapFileStats(QString,QString *,int *,int *,int *,int *) Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: clean up TMap initialisation/clearing actions Now restores the customEnvColors set up on initialisation but that was cleared when the map replaced with another one that is loaded {which subsequently replaces that element anyway} or imported {which merely writes over it, replacing any matching keys}. Initialises elements that when inspected on the entry to the constructor proper previously were not being set to a consistent value {booleans/ints/floats}. NOTE: This will now clear the map user data member when the map is cleared if the date is required to be saved when one map is loaded OR IMPORTED over an existing one then the data will need to be saved outside of the map - as is already need for areas and rooms user data! Also comment out or remove unused members/methods: * (void) TMap::getConnectedNodesGreaterThanX(int, int) * (void) TMap::getConnectedNodesSmallerThanX(int, int) * (void) TMap::getConnectedNodesGreaterThanY(int, int) * (void) TMap::getConnectedNodesSmallerThanY(int, int) * (void) TMap::astBreitenAnpassung(int, int) * (void) TMap::astHoehenAnpassung(int, int) * (void) TMap::exportMapToDatabase() * (void) TMap::importMapFromDatabase() * (QVector3D) TMap::span * (int) TMap::mViewArea * (QMap<QString, int>) TMap::pixNameTable * (QMap<int, QPixmap>) TMap::pixTable * (bool) TMap::isToDisplayAuditErrorsToConsole Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * ImplimentationFixes: activate a valid optimisation & remove redundant code Adding a true as a non-default 3rd argument to TRoomDB::addRoom(...) call in XMLimport::readRoom(...) enables a significant optimisation (skips a computationally expensive step when ADDING a room to new map) which dramatically reduces the time to parse an XML map file. It also pointed to the fact that the TRoomDB::entranceMap was already correctly being handled and didn't need to be regenerated in XMLimport::readRoom(...) so the code that was added in a previous commit was redundant and could be removed. A code error in TMap::slot_setDownloadProgress(...) that caused an issue that a reviewer found on test has been fixed - the total download filesize that was being sent by the Qt system signal that is connected to this slot was a -1 value (as IS DOCUMENTED) when the Qt system does NOT know the size of a QNetworkReply in advance of reaching the end of the download was incorrectly handled in a previous commit in this change set. Also found during testing that there is no need for an error message for the QNetworkReply::OperationCanceledError case in TMap::slot_replayFinished(...) as it is already handled in the TMap::slot_downloadCancel() slot. Changed the text put up onto the progress widget during the XML room parsing to be a room count - which is likely more useful and to only do it for every hundredth room - which reduces any delay "wasted" in writing to the display - combined, the effects seem satisfactory IMHO. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: provide error messages for TLuaInterpreter::loadMap(...) Errors for the XML map file importing process as initiated from the Lua command should be returned to that command rather than plastered onto the main profile console - this commit attempts to perform that effect. In testing found that there was no error handling for failure to find or open the nominated file so messages for that have been added as well. Due to the previous program logic the action of creating a mapper widget using the main toolbar button automatically loaded the "default" (the newest Mudlet Map file format file from the currently active profile's map sub-directory). Under some previous situations it looked as though a map might be loaded twice as mudlet::slot_mapper() was called both directly and via signal/slot action. These were resolved by turning that slot into a wrapper that now calls the body of code formerly within to a new method mudlet::createMapper( bool isToLoadDefaultMapFile = true ) with a the default value as an argument. This allows other usages of the body of code to be called directly with a suitable argument, which for the TConsole::loadMap() & TConsole::importMap() and the dlgProfilePreferences::downloadMap() cases is false as they are all do not want the "default" map! Also: * spotted a word "area" missing from an advisory text in TRoom::auditRooms(...). Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: fix minor bug, correct a spelling, undo a few capitalisations Under certain, unanticipated (error with no error message) conditions TLuaInterpreter::loadMap(...) would push both a nil and then a false value onto the stack for return {wrong} but only indicate one value {correct}. The textual matters were found during peer review. off-by: Stephen Lyons <slysven@virginmedia.com>
2016-10-13 09:18:48 +01:00
qWarning() << "TMap::slot_replyFinished( QNetworkReply * ) ERROR - received argument was not the expected stored pointer.";
}
if (reply->error() != QNetworkReply::NoError) {
if (reply->error() != QNetworkReply::OperationCanceledError) {
Enhance: fix map downloading code, add manual XML map importing (#326) * Enhance: fix map downloading code, add manual XML map importing A recent move by I.R.E. to using SSL for their public MUD map URLs broke the ability for Mudlet to download those XML format files. This commit addresses this issue (as mentioned in, but not the original problem referred to in https://bugs.launchpad.net/mudlet/+bug/1427364) the revision to the code does now use "https://www.<MUD URL>/maps/map.xml" as a default name for the I.R.E. MUDS - however the method that initiates the download which was moved to TMap class from the dlgMapper one (see below) is now: (bool) TMap::downloadMap( const QString * remoteUrl = Q_NULLPTR, const QString * localFileName = Q_NULLPTR ) which if not supplied with any arguments behaves as before. However the remoteUrl argument may be given as a full QString including the scheme (the bit of the URL at the beginning before the ':') to override that and a second argument may be used to provide a different name to use for the local file name which if is a RELATIVE pathFileName will be resolved in relation to the profile directory. At present no use is made of this additional functionality but it may be useful for use with other MUDs if they should choose to provide XML map files with other remote locations and scripts using a different local filename. As a long-standing thing that needed doing I have finally provided a means to import a map XML file that - for instance - has already been download. It had been noted that there was no way to read those I.R.E. map files even if they had been obtained from a web browser able to correctly handle https: URLs - now both the TLuaInterpreter::loadMap() and the dlgProfilePreference "loadMap" button {NOT the IRE only "map download" one} will both handle files ending in ".xml" (not case sensitive so it'll work MacOS platforms as well!} For the loadMap case it will be necessary to change the filetype filter on the File Selection dialog to select "xml" files. During testing it became clear to me that it was possible to try and read one or more XML files via several mechanisms simultaneously with "unhelpful" consequences. As well as hitting the dlgProfilePreferences IRE "map download" multiple times, the TLuaInterpreter::loadMap() does NOT block until the map has been loaded and as the import time {running of XMLinport::readPackage(...)} is of significant duration for a large map (a debug, without optimisation, build on my 1.8GHz Quad-core took over two minutes to process the current Achaea map file) it is very possible to get conditions where the same profile will try to run XMLinport::readPackage(...) asynchronously - given that a profile only supports ONE map at a time it was necessary to fit a QMutex to prevent the part of the XMLinport class relating to XML Map files being called from different places in the map related code. This means that if a map download is started further downloads and any local map imports will fail until that first download has completed or aborted. Similarly a local import will prevent a download being started. As a side effect this cures: https://bugs.launchpad.net/mudlet/+bug/852861 - "Map download button starts another download thread if one is already going" The previous XML import code was not adding the rooms that it parsed to the relevant TArea::rooms member - although this would be picked-up and fixed by TMap::audit() later on, this would be accompanied by an error message about every single room. The code now builds up this information while parsing the rooms' details and inserts it so that this does not cause report-able problems during the TMap::audit() execution - the data gathered also allows missing areas to be spotted so that if a room claimed to belong to an area that was not included in the preceding areas' data an unnamed area is created for it. As a consequence of the long time to actually parse an XML map file I have enhanced the progress dialog that was originally used to track the map file download. It is now retained until the file is completely imported and shows more information about the process - importantly it shows during the XMLimport::readRoom(...) the room id being processed - and THAT method is the time/cpu hog so seeing something happening during the time that Mudlet otherwise appears to hang is useful feedback even if it adds a few seconds to the overall duration (may be more than a minute). This dialog is now also used during the other routes that involve reading an XML file and there is now a bit of consistence with the on-screen messages. Whilst inspecting XMLimport class I found there was some uncertain initialisation which I have tidied up. In summary: Added: * (bool) TConsole::importMap(const QString & location) * (void) TRoomDB::setAreaRooms(const int areaId, const QSet<int> & roomIds) * image file mudlet_map_download.png used as icon for download/import progress dialog * (bool) TMap::importMap(QFile & file) * (bool) TMap::readXmlMapFile(QFile & file) * (void) TMap::slot_downloadError(QNetworkReply::NetworkError error) * (void) TMap::reportStringToProgressDialog(const QString text) * (void) TMap::reportProgressToProgressDialog(const int current, const int maximum) Revised: * (int)TLuaInterpreter::loadMap( lua_State * ) * Moved XML map download code from dlgMapper class to the TMap one: + (void) dlgMapper::downloadMap() ==> (bool) TMap::downloadMap(const QString * remoteUrl, const QString * localFileName) + (void) dlgMapper::setDownloadProgress(qint64, qint64) ==> (void) TMap::slot_setDownloadProgress(qint64,qint64) + (void) dlgMapper::cancel() ==> (void) TMap::slot_downloadCancel() + (void) dlgMapper::replyFinished(QNetworkReply *) ==> (void) TMap::slot_replyFinished(QNetworkReply *) * Enhanced download progress indication to also include parsing which can take even more time than download! * Provide means to import local XML map file * Prevent trying to import/download more than one map at a time Renamed: * (void) XMLimport::readAreaNames() ==> XMLimport::readArea() - for consistency with related functions Commented out unused: * (void) XMLimport::readUnknownRoomElement() Note the movement of the map file download code to the TMap class does require making the latter a class with the Q_OBJECT macro (which removes the need for Q_DECLARE_TR_FUNCTIONS as a side-effect!) - though as another side-effect the TMap header needed a boost name specifier added to one identifier as that identifier ("property") exists in both boost and QObject classes!!! YOU MAY NEED TO RUN QMAKE ON THE PROJECT IF THE BUILD SYSTEM DOES NOT PICK UP THE ADDITION OF "Q_OBJECT" TO TMAP CLASS. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: Include missing #include, remove unused return value The absence of this was causing build errors on the Travis C.I. platform! Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: move TMap.h to mudlet_MOC_HDRS to fix CMake build issue As we have made TMap inherit from QOject - to have signal/slot functionality that class needs to be run through Qt's MOC - and to do that with the CMake project/build system it needs to be included in the files included in the projects *_MOC_HDRS {and removed from the *_HDRS} variable. Also spotted a trivial error in that specifying a const return value from method is ineffective and pointless - so removed it from: TMap::retrieveMapFileStats(QString,QString *,int *,int *,int *,int *) Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: clean up TMap initialisation/clearing actions Now restores the customEnvColors set up on initialisation but that was cleared when the map replaced with another one that is loaded {which subsequently replaces that element anyway} or imported {which merely writes over it, replacing any matching keys}. Initialises elements that when inspected on the entry to the constructor proper previously were not being set to a consistent value {booleans/ints/floats}. NOTE: This will now clear the map user data member when the map is cleared if the date is required to be saved when one map is loaded OR IMPORTED over an existing one then the data will need to be saved outside of the map - as is already need for areas and rooms user data! Also comment out or remove unused members/methods: * (void) TMap::getConnectedNodesGreaterThanX(int, int) * (void) TMap::getConnectedNodesSmallerThanX(int, int) * (void) TMap::getConnectedNodesGreaterThanY(int, int) * (void) TMap::getConnectedNodesSmallerThanY(int, int) * (void) TMap::astBreitenAnpassung(int, int) * (void) TMap::astHoehenAnpassung(int, int) * (void) TMap::exportMapToDatabase() * (void) TMap::importMapFromDatabase() * (QVector3D) TMap::span * (int) TMap::mViewArea * (QMap<QString, int>) TMap::pixNameTable * (QMap<int, QPixmap>) TMap::pixTable * (bool) TMap::isToDisplayAuditErrorsToConsole Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * ImplimentationFixes: activate a valid optimisation & remove redundant code Adding a true as a non-default 3rd argument to TRoomDB::addRoom(...) call in XMLimport::readRoom(...) enables a significant optimisation (skips a computationally expensive step when ADDING a room to new map) which dramatically reduces the time to parse an XML map file. It also pointed to the fact that the TRoomDB::entranceMap was already correctly being handled and didn't need to be regenerated in XMLimport::readRoom(...) so the code that was added in a previous commit was redundant and could be removed. A code error in TMap::slot_setDownloadProgress(...) that caused an issue that a reviewer found on test has been fixed - the total download filesize that was being sent by the Qt system signal that is connected to this slot was a -1 value (as IS DOCUMENTED) when the Qt system does NOT know the size of a QNetworkReply in advance of reaching the end of the download was incorrectly handled in a previous commit in this change set. Also found during testing that there is no need for an error message for the QNetworkReply::OperationCanceledError case in TMap::slot_replayFinished(...) as it is already handled in the TMap::slot_downloadCancel() slot. Changed the text put up onto the progress widget during the XML room parsing to be a room count - which is likely more useful and to only do it for every hundredth room - which reduces any delay "wasted" in writing to the display - combined, the effects seem satisfactory IMHO. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: provide error messages for TLuaInterpreter::loadMap(...) Errors for the XML map file importing process as initiated from the Lua command should be returned to that command rather than plastered onto the main profile console - this commit attempts to perform that effect. In testing found that there was no error handling for failure to find or open the nominated file so messages for that have been added as well. Due to the previous program logic the action of creating a mapper widget using the main toolbar button automatically loaded the "default" (the newest Mudlet Map file format file from the currently active profile's map sub-directory). Under some previous situations it looked as though a map might be loaded twice as mudlet::slot_mapper() was called both directly and via signal/slot action. These were resolved by turning that slot into a wrapper that now calls the body of code formerly within to a new method mudlet::createMapper( bool isToLoadDefaultMapFile = true ) with a the default value as an argument. This allows other usages of the body of code to be called directly with a suitable argument, which for the TConsole::loadMap() & TConsole::importMap() and the dlgProfilePreferences::downloadMap() cases is false as they are all do not want the "default" map! Also: * spotted a word "area" missing from an advisory text in TRoom::auditRooms(...). Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: fix minor bug, correct a spelling, undo a few capitalisations Under certain, unanticipated (error with no error message) conditions TLuaInterpreter::loadMap(...) would push both a nil and then a false value onto the stack for return {wrong} but only indicate one value {correct}. The textual matters were found during peer review. off-by: Stephen Lyons <slysven@virginmedia.com>
2016-10-13 09:18:48 +01:00
// Don't post an error for the cancel case - it has already been done
QString alertMsg = tr("[ ALERT ] - Map download failed, error reported was:\n%1.").arg(reply->errorString());
postMessage(alertMsg);
Enhance: fix map downloading code, add manual XML map importing (#326) * Enhance: fix map downloading code, add manual XML map importing A recent move by I.R.E. to using SSL for their public MUD map URLs broke the ability for Mudlet to download those XML format files. This commit addresses this issue (as mentioned in, but not the original problem referred to in https://bugs.launchpad.net/mudlet/+bug/1427364) the revision to the code does now use "https://www.<MUD URL>/maps/map.xml" as a default name for the I.R.E. MUDS - however the method that initiates the download which was moved to TMap class from the dlgMapper one (see below) is now: (bool) TMap::downloadMap( const QString * remoteUrl = Q_NULLPTR, const QString * localFileName = Q_NULLPTR ) which if not supplied with any arguments behaves as before. However the remoteUrl argument may be given as a full QString including the scheme (the bit of the URL at the beginning before the ':') to override that and a second argument may be used to provide a different name to use for the local file name which if is a RELATIVE pathFileName will be resolved in relation to the profile directory. At present no use is made of this additional functionality but it may be useful for use with other MUDs if they should choose to provide XML map files with other remote locations and scripts using a different local filename. As a long-standing thing that needed doing I have finally provided a means to import a map XML file that - for instance - has already been download. It had been noted that there was no way to read those I.R.E. map files even if they had been obtained from a web browser able to correctly handle https: URLs - now both the TLuaInterpreter::loadMap() and the dlgProfilePreference "loadMap" button {NOT the IRE only "map download" one} will both handle files ending in ".xml" (not case sensitive so it'll work MacOS platforms as well!} For the loadMap case it will be necessary to change the filetype filter on the File Selection dialog to select "xml" files. During testing it became clear to me that it was possible to try and read one or more XML files via several mechanisms simultaneously with "unhelpful" consequences. As well as hitting the dlgProfilePreferences IRE "map download" multiple times, the TLuaInterpreter::loadMap() does NOT block until the map has been loaded and as the import time {running of XMLinport::readPackage(...)} is of significant duration for a large map (a debug, without optimisation, build on my 1.8GHz Quad-core took over two minutes to process the current Achaea map file) it is very possible to get conditions where the same profile will try to run XMLinport::readPackage(...) asynchronously - given that a profile only supports ONE map at a time it was necessary to fit a QMutex to prevent the part of the XMLinport class relating to XML Map files being called from different places in the map related code. This means that if a map download is started further downloads and any local map imports will fail until that first download has completed or aborted. Similarly a local import will prevent a download being started. As a side effect this cures: https://bugs.launchpad.net/mudlet/+bug/852861 - "Map download button starts another download thread if one is already going" The previous XML import code was not adding the rooms that it parsed to the relevant TArea::rooms member - although this would be picked-up and fixed by TMap::audit() later on, this would be accompanied by an error message about every single room. The code now builds up this information while parsing the rooms' details and inserts it so that this does not cause report-able problems during the TMap::audit() execution - the data gathered also allows missing areas to be spotted so that if a room claimed to belong to an area that was not included in the preceding areas' data an unnamed area is created for it. As a consequence of the long time to actually parse an XML map file I have enhanced the progress dialog that was originally used to track the map file download. It is now retained until the file is completely imported and shows more information about the process - importantly it shows during the XMLimport::readRoom(...) the room id being processed - and THAT method is the time/cpu hog so seeing something happening during the time that Mudlet otherwise appears to hang is useful feedback even if it adds a few seconds to the overall duration (may be more than a minute). This dialog is now also used during the other routes that involve reading an XML file and there is now a bit of consistence with the on-screen messages. Whilst inspecting XMLimport class I found there was some uncertain initialisation which I have tidied up. In summary: Added: * (bool) TConsole::importMap(const QString & location) * (void) TRoomDB::setAreaRooms(const int areaId, const QSet<int> & roomIds) * image file mudlet_map_download.png used as icon for download/import progress dialog * (bool) TMap::importMap(QFile & file) * (bool) TMap::readXmlMapFile(QFile & file) * (void) TMap::slot_downloadError(QNetworkReply::NetworkError error) * (void) TMap::reportStringToProgressDialog(const QString text) * (void) TMap::reportProgressToProgressDialog(const int current, const int maximum) Revised: * (int)TLuaInterpreter::loadMap( lua_State * ) * Moved XML map download code from dlgMapper class to the TMap one: + (void) dlgMapper::downloadMap() ==> (bool) TMap::downloadMap(const QString * remoteUrl, const QString * localFileName) + (void) dlgMapper::setDownloadProgress(qint64, qint64) ==> (void) TMap::slot_setDownloadProgress(qint64,qint64) + (void) dlgMapper::cancel() ==> (void) TMap::slot_downloadCancel() + (void) dlgMapper::replyFinished(QNetworkReply *) ==> (void) TMap::slot_replyFinished(QNetworkReply *) * Enhanced download progress indication to also include parsing which can take even more time than download! * Provide means to import local XML map file * Prevent trying to import/download more than one map at a time Renamed: * (void) XMLimport::readAreaNames() ==> XMLimport::readArea() - for consistency with related functions Commented out unused: * (void) XMLimport::readUnknownRoomElement() Note the movement of the map file download code to the TMap class does require making the latter a class with the Q_OBJECT macro (which removes the need for Q_DECLARE_TR_FUNCTIONS as a side-effect!) - though as another side-effect the TMap header needed a boost name specifier added to one identifier as that identifier ("property") exists in both boost and QObject classes!!! YOU MAY NEED TO RUN QMAKE ON THE PROJECT IF THE BUILD SYSTEM DOES NOT PICK UP THE ADDITION OF "Q_OBJECT" TO TMAP CLASS. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: Include missing #include, remove unused return value The absence of this was causing build errors on the Travis C.I. platform! Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: move TMap.h to mudlet_MOC_HDRS to fix CMake build issue As we have made TMap inherit from QOject - to have signal/slot functionality that class needs to be run through Qt's MOC - and to do that with the CMake project/build system it needs to be included in the files included in the projects *_MOC_HDRS {and removed from the *_HDRS} variable. Also spotted a trivial error in that specifying a const return value from method is ineffective and pointless - so removed it from: TMap::retrieveMapFileStats(QString,QString *,int *,int *,int *,int *) Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: clean up TMap initialisation/clearing actions Now restores the customEnvColors set up on initialisation but that was cleared when the map replaced with another one that is loaded {which subsequently replaces that element anyway} or imported {which merely writes over it, replacing any matching keys}. Initialises elements that when inspected on the entry to the constructor proper previously were not being set to a consistent value {booleans/ints/floats}. NOTE: This will now clear the map user data member when the map is cleared if the date is required to be saved when one map is loaded OR IMPORTED over an existing one then the data will need to be saved outside of the map - as is already need for areas and rooms user data! Also comment out or remove unused members/methods: * (void) TMap::getConnectedNodesGreaterThanX(int, int) * (void) TMap::getConnectedNodesSmallerThanX(int, int) * (void) TMap::getConnectedNodesGreaterThanY(int, int) * (void) TMap::getConnectedNodesSmallerThanY(int, int) * (void) TMap::astBreitenAnpassung(int, int) * (void) TMap::astHoehenAnpassung(int, int) * (void) TMap::exportMapToDatabase() * (void) TMap::importMapFromDatabase() * (QVector3D) TMap::span * (int) TMap::mViewArea * (QMap<QString, int>) TMap::pixNameTable * (QMap<int, QPixmap>) TMap::pixTable * (bool) TMap::isToDisplayAuditErrorsToConsole Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * ImplimentationFixes: activate a valid optimisation & remove redundant code Adding a true as a non-default 3rd argument to TRoomDB::addRoom(...) call in XMLimport::readRoom(...) enables a significant optimisation (skips a computationally expensive step when ADDING a room to new map) which dramatically reduces the time to parse an XML map file. It also pointed to the fact that the TRoomDB::entranceMap was already correctly being handled and didn't need to be regenerated in XMLimport::readRoom(...) so the code that was added in a previous commit was redundant and could be removed. A code error in TMap::slot_setDownloadProgress(...) that caused an issue that a reviewer found on test has been fixed - the total download filesize that was being sent by the Qt system signal that is connected to this slot was a -1 value (as IS DOCUMENTED) when the Qt system does NOT know the size of a QNetworkReply in advance of reaching the end of the download was incorrectly handled in a previous commit in this change set. Also found during testing that there is no need for an error message for the QNetworkReply::OperationCanceledError case in TMap::slot_replayFinished(...) as it is already handled in the TMap::slot_downloadCancel() slot. Changed the text put up onto the progress widget during the XML room parsing to be a room count - which is likely more useful and to only do it for every hundredth room - which reduces any delay "wasted" in writing to the display - combined, the effects seem satisfactory IMHO. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: provide error messages for TLuaInterpreter::loadMap(...) Errors for the XML map file importing process as initiated from the Lua command should be returned to that command rather than plastered onto the main profile console - this commit attempts to perform that effect. In testing found that there was no error handling for failure to find or open the nominated file so messages for that have been added as well. Due to the previous program logic the action of creating a mapper widget using the main toolbar button automatically loaded the "default" (the newest Mudlet Map file format file from the currently active profile's map sub-directory). Under some previous situations it looked as though a map might be loaded twice as mudlet::slot_mapper() was called both directly and via signal/slot action. These were resolved by turning that slot into a wrapper that now calls the body of code formerly within to a new method mudlet::createMapper( bool isToLoadDefaultMapFile = true ) with a the default value as an argument. This allows other usages of the body of code to be called directly with a suitable argument, which for the TConsole::loadMap() & TConsole::importMap() and the dlgProfilePreferences::downloadMap() cases is false as they are all do not want the "default" map! Also: * spotted a word "area" missing from an advisory text in TRoom::auditRooms(...). Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: fix minor bug, correct a spelling, undo a few capitalisations Under certain, unanticipated (error with no error message) conditions TLuaInterpreter::loadMap(...) would push both a nil and then a false value onto the stack for return {wrong} but only indicate one value {correct}. The textual matters were found during peer review. off-by: Stephen Lyons <slysven@virginmedia.com>
2016-10-13 09:18:48 +01:00
}
// else was QNetworkReply::OperationCanceledError and we already handle
// THAT in slot_downloadCancel()
} else {
QFile file(mLocalMapFileName);
if (!file.open(QFile::WriteOnly)) {
QString alertMsg = tr("[ ALERT ] - Map download failed, unable to open destination file:\n%1.").arg(mLocalMapFileName);
postMessage(alertMsg);
} else {
Enhance: fix map downloading code, add manual XML map importing (#329) A recent move by I.R.E. to using SSL for their public MUD map URLs broke the ability for Mudlet to download those XML format files. This commit addresses this issue (as mentioned in, but not the original problem referred to in https://bugs.launchpad.net/mudlet/+bug/1427364) the revision to the code does now use "https://www.<MUD URL>/maps/map.xml" as a default name for the I.R.E. MUDS - however the method that initiates the download which was moved to TMap class from the dlgMapper one (see below) is now: (bool) TMap::downloadMap( const QString * remoteUrl = Q_NULLPTR, const QString * localFileName = Q_NULLPTR ) which if not supplied with any arguments behaves as before. However the remoteUrl argument may be given as a full QString including the scheme (the bit of the URL at the beginning before the ':') to override that and a second argument may be used to provide a different name to use for the local file name which if is a RELATIVE pathFileName will be resolved in relation to the profile directory. At present no use is made of this additional functionality but it may be useful for use with other MUDs if they should choose to provide XML map files with other remote locations and scripts using a different local filename. As a long-standing thing that needed doing I have finally provided a means to import a map XML file that - for instance - has already been download. It had been noted that there was no way to read those I.R.E. map files even if they had been obtained from a web browser able to correctly handle https: URLs - now both the TLuaInterpreter::loadMap() and the dlgProfilePreference "loadMap" button {NOT the IRE only "map download" one} will both handle files ending in ".xml" (not case sensitive so it'll work MacOS platforms as well!} For the loadMap case it will be necessary to change the filetype filter on the File Selection dialog to select "xml" files. During testing it became clear to me that it was possible to try and read one or more XML files via several mechanisms simultaneously with "unhelpful" consequences. As well as hitting the dlgProfilePreferences IRE "map download" multiple times, the TLuaInterpreter::loadMap() does NOT block until the map has been loaded and as the import time {running of XMLinport::readPackage(...)} is of significant duration for a large map (a debug, without optimisation, build on my 1.8GHz Quad-core took over two minutes to process the current Achaea map file) it is very possible to get conditions where the same profile will try to run XMLinport::readPackage(...) asynchronously - given that a profile only supports ONE map at a time it was necessary to fit a QMutex to prevent the part of the XMLinport class relating to XML Map files being called from different places in the map related code. This means that if a map download is started further downloads and any local map imports will fail until that first download has completed or aborted. Similarly a local import will prevent a download being started. As a side effect this cures: https://bugs.launchpad.net/mudlet/+bug/852861 - "Map download button starts another download thread if one is already going" The previous XML import code was not adding the rooms that it parsed to the relevant TArea::rooms member - although this would be picked-up and fixed by TMap::audit() later on, this would be accompanied by an error message about every single room. The code now builds up this information while parsing the rooms' details and inserts it so that this does not cause report-able problems during the TMap::audit() execution - the data gathered also allows missing areas to be spotted so that if a room claimed to belong to an area that was not included in the preceding areas' data an unnamed area is created for it. As a consequence of time to actually parse an XML map file I have enhanced the progress dialog that was originally used to track the map file download. It is now retained until the file is completely imported and shows more information about the process - importantly it shows during the XMLimport::readRoom(...) a count of 100's of rooms processed. This dialog is now also used during the other routes that involve reading an XML file and there is now a bit of consistence with the on-screen messages. However errors for the XML map file importing process as initiated from the Lua command are generally returned to that command rather than plastered onto the main profile console. Adding a true as a non-default 3rd argument to TRoomDB::addRoom(...) call in XMLimport::readRoom(...) enables a significant optimisation (skips a computationally expensive step when ADDING a room to new map) which dramatically reduces the time to parse an XML map file. Whilst inspecting XMLimport class I found there was some uncertain initialisation which I have tidied up. Note the movement of the map file download code to the TMap class does require making the latter a class with the Q_OBJECT macro (which removes the need for Q_DECLARE_TR_FUNCTIONS as a side-effect!) - though as another side-effect the TMap header needed a boost name specifier added to one identifier as that identifier ("property") exists in both boost and QObject classes!!! YOU MAY NEED TO RUN QMAKE ON THE PROJECT IF THE BUILD SYSTEM DOES NOT PICK UP THE ADDITION OF "Q_OBJECT" TO TMAP CLASS. Also spotted a trivial error in that specifying a const return value from method is ineffective and pointless - so removed it from: TMap::retrieveMapFileStats(QString,QString *,int *,int *,int *,int *) Now restores the customEnvColors set up on initialisation but that was cleared when the map replaced with another one that is loaded {which subsequently replaces that element anyway} or imported {which merely writes over it, replacing any matching keys}. Initialises elements that when inspected on the entry to the constructor proper previously were not being set to a consistent value {booleans/ints/floats}. NOTE: This will now clear the map user data member when the map is cleared if the date is required to be saved when one map is loaded OR IMPORTED over an existing one then the data will need to be saved outside of the map - as is already need for areas and rooms user data! Due to the previous program logic the action of creating a mapper widget using the main toolbar button automatically loaded the "default" (the newest Mudlet Map file format file from the currently active profile's map sub-directory). Under some previous situations it looked as though a map might be loaded twice as mudlet::slot_mapper() was called both directly and via signal/slot action. These were resolved by turning that slot into a wrapper that now calls the body of code formerly within to a new method mudlet::createMapper( bool isToLoadDefaultMapFile = true ) with a the default value as an argument. This allows other usages of the body of code to be called directly with a suitable argument, which for the TConsole::loadMap() & TConsole::importMap() and the dlgProfilePreferences::downloadMap() cases is false as they are all do not want the "default" map! Also: * spotted a word "area" missing from an advisory text in TRoom::auditRooms(...). In summary: Added: * (bool) TConsole::importMap(const QString & location) * (void) TRoomDB::setAreaRooms(const int areaId, const QSet<int> & roomIds) * image file mudlet_map_download.png used as icon for download/import progress dialog * (bool) TMap::importMap(QFile & file) * (bool) TMap::readXmlMapFile(QFile & file) * (void) TMap::slot_downloadError(QNetworkReply::NetworkError error) * (void) TMap::reportStringToProgressDialog(const QString text) * (void) TMap::reportProgressToProgressDialog(const int current, const int maximum) Revised: * (int)TLuaInterpreter::loadMap( lua_State * ) * Moved XML map download code from dlgMapper class to the TMap one: + (void) dlgMapper::downloadMap() ==> (bool) TMap::downloadMap(const QString * remoteUrl, const QString * localFileName) + (void) dlgMapper::setDownloadProgress(qint64, qint64) ==> (void) TMap::slot_setDownloadProgress(qint64,qint64) + (void) dlgMapper::cancel() ==> (void) TMap::slot_downloadCancel() + (void) dlgMapper::replyFinished(QNetworkReply *) ==> (void) TMap::slot_replyFinished(QNetworkReply *) Renamed: * (void) XMLimport::readAreaNames() ==> XMLimport::readArea() - for consistency with related functions Commented out unused: * (void) XMLimport::readUnknownRoomElement() * (void) TMap::getConnectedNodesGreaterThanX(int, int) * (void) TMap::getConnectedNodesSmallerThanX(int, int) * (void) TMap::getConnectedNodesGreaterThanY(int, int) * (void) TMap::getConnectedNodesSmallerThanY(int, int) * (void) TMap::astBreitenAnpassung(int, int) * (void) TMap::astHoehenAnpassung(int, int) * (void) TMap::exportMapToDatabase() * (void) TMap::importMapFromDatabase() * (QVector3D) TMap::span * (int) TMap::mViewArea * (QMap<QString, int>) TMap::pixNameTable * (QMap<int, QPixmap>) TMap::pixTable * (bool) TMap::isToDisplayAuditErrorsToConsole Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2016-10-13 08:03:42 +01:00
// The QNetworkReply is Ok here:
if (file.write(reply->readAll()) == -1) {
QString alertMsg = tr("[ ALERT ] - Map download failed, unable to write destination file:\n%1.").arg(mLocalMapFileName);
postMessage(alertMsg);
} else {
Enhance: fix map downloading code, add manual XML map importing (#326) * Enhance: fix map downloading code, add manual XML map importing A recent move by I.R.E. to using SSL for their public MUD map URLs broke the ability for Mudlet to download those XML format files. This commit addresses this issue (as mentioned in, but not the original problem referred to in https://bugs.launchpad.net/mudlet/+bug/1427364) the revision to the code does now use "https://www.<MUD URL>/maps/map.xml" as a default name for the I.R.E. MUDS - however the method that initiates the download which was moved to TMap class from the dlgMapper one (see below) is now: (bool) TMap::downloadMap( const QString * remoteUrl = Q_NULLPTR, const QString * localFileName = Q_NULLPTR ) which if not supplied with any arguments behaves as before. However the remoteUrl argument may be given as a full QString including the scheme (the bit of the URL at the beginning before the ':') to override that and a second argument may be used to provide a different name to use for the local file name which if is a RELATIVE pathFileName will be resolved in relation to the profile directory. At present no use is made of this additional functionality but it may be useful for use with other MUDs if they should choose to provide XML map files with other remote locations and scripts using a different local filename. As a long-standing thing that needed doing I have finally provided a means to import a map XML file that - for instance - has already been download. It had been noted that there was no way to read those I.R.E. map files even if they had been obtained from a web browser able to correctly handle https: URLs - now both the TLuaInterpreter::loadMap() and the dlgProfilePreference "loadMap" button {NOT the IRE only "map download" one} will both handle files ending in ".xml" (not case sensitive so it'll work MacOS platforms as well!} For the loadMap case it will be necessary to change the filetype filter on the File Selection dialog to select "xml" files. During testing it became clear to me that it was possible to try and read one or more XML files via several mechanisms simultaneously with "unhelpful" consequences. As well as hitting the dlgProfilePreferences IRE "map download" multiple times, the TLuaInterpreter::loadMap() does NOT block until the map has been loaded and as the import time {running of XMLinport::readPackage(...)} is of significant duration for a large map (a debug, without optimisation, build on my 1.8GHz Quad-core took over two minutes to process the current Achaea map file) it is very possible to get conditions where the same profile will try to run XMLinport::readPackage(...) asynchronously - given that a profile only supports ONE map at a time it was necessary to fit a QMutex to prevent the part of the XMLinport class relating to XML Map files being called from different places in the map related code. This means that if a map download is started further downloads and any local map imports will fail until that first download has completed or aborted. Similarly a local import will prevent a download being started. As a side effect this cures: https://bugs.launchpad.net/mudlet/+bug/852861 - "Map download button starts another download thread if one is already going" The previous XML import code was not adding the rooms that it parsed to the relevant TArea::rooms member - although this would be picked-up and fixed by TMap::audit() later on, this would be accompanied by an error message about every single room. The code now builds up this information while parsing the rooms' details and inserts it so that this does not cause report-able problems during the TMap::audit() execution - the data gathered also allows missing areas to be spotted so that if a room claimed to belong to an area that was not included in the preceding areas' data an unnamed area is created for it. As a consequence of the long time to actually parse an XML map file I have enhanced the progress dialog that was originally used to track the map file download. It is now retained until the file is completely imported and shows more information about the process - importantly it shows during the XMLimport::readRoom(...) the room id being processed - and THAT method is the time/cpu hog so seeing something happening during the time that Mudlet otherwise appears to hang is useful feedback even if it adds a few seconds to the overall duration (may be more than a minute). This dialog is now also used during the other routes that involve reading an XML file and there is now a bit of consistence with the on-screen messages. Whilst inspecting XMLimport class I found there was some uncertain initialisation which I have tidied up. In summary: Added: * (bool) TConsole::importMap(const QString & location) * (void) TRoomDB::setAreaRooms(const int areaId, const QSet<int> & roomIds) * image file mudlet_map_download.png used as icon for download/import progress dialog * (bool) TMap::importMap(QFile & file) * (bool) TMap::readXmlMapFile(QFile & file) * (void) TMap::slot_downloadError(QNetworkReply::NetworkError error) * (void) TMap::reportStringToProgressDialog(const QString text) * (void) TMap::reportProgressToProgressDialog(const int current, const int maximum) Revised: * (int)TLuaInterpreter::loadMap( lua_State * ) * Moved XML map download code from dlgMapper class to the TMap one: + (void) dlgMapper::downloadMap() ==> (bool) TMap::downloadMap(const QString * remoteUrl, const QString * localFileName) + (void) dlgMapper::setDownloadProgress(qint64, qint64) ==> (void) TMap::slot_setDownloadProgress(qint64,qint64) + (void) dlgMapper::cancel() ==> (void) TMap::slot_downloadCancel() + (void) dlgMapper::replyFinished(QNetworkReply *) ==> (void) TMap::slot_replyFinished(QNetworkReply *) * Enhanced download progress indication to also include parsing which can take even more time than download! * Provide means to import local XML map file * Prevent trying to import/download more than one map at a time Renamed: * (void) XMLimport::readAreaNames() ==> XMLimport::readArea() - for consistency with related functions Commented out unused: * (void) XMLimport::readUnknownRoomElement() Note the movement of the map file download code to the TMap class does require making the latter a class with the Q_OBJECT macro (which removes the need for Q_DECLARE_TR_FUNCTIONS as a side-effect!) - though as another side-effect the TMap header needed a boost name specifier added to one identifier as that identifier ("property") exists in both boost and QObject classes!!! YOU MAY NEED TO RUN QMAKE ON THE PROJECT IF THE BUILD SYSTEM DOES NOT PICK UP THE ADDITION OF "Q_OBJECT" TO TMAP CLASS. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: Include missing #include, remove unused return value The absence of this was causing build errors on the Travis C.I. platform! Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: move TMap.h to mudlet_MOC_HDRS to fix CMake build issue As we have made TMap inherit from QOject - to have signal/slot functionality that class needs to be run through Qt's MOC - and to do that with the CMake project/build system it needs to be included in the files included in the projects *_MOC_HDRS {and removed from the *_HDRS} variable. Also spotted a trivial error in that specifying a const return value from method is ineffective and pointless - so removed it from: TMap::retrieveMapFileStats(QString,QString *,int *,int *,int *,int *) Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: clean up TMap initialisation/clearing actions Now restores the customEnvColors set up on initialisation but that was cleared when the map replaced with another one that is loaded {which subsequently replaces that element anyway} or imported {which merely writes over it, replacing any matching keys}. Initialises elements that when inspected on the entry to the constructor proper previously were not being set to a consistent value {booleans/ints/floats}. NOTE: This will now clear the map user data member when the map is cleared if the date is required to be saved when one map is loaded OR IMPORTED over an existing one then the data will need to be saved outside of the map - as is already need for areas and rooms user data! Also comment out or remove unused members/methods: * (void) TMap::getConnectedNodesGreaterThanX(int, int) * (void) TMap::getConnectedNodesSmallerThanX(int, int) * (void) TMap::getConnectedNodesGreaterThanY(int, int) * (void) TMap::getConnectedNodesSmallerThanY(int, int) * (void) TMap::astBreitenAnpassung(int, int) * (void) TMap::astHoehenAnpassung(int, int) * (void) TMap::exportMapToDatabase() * (void) TMap::importMapFromDatabase() * (QVector3D) TMap::span * (int) TMap::mViewArea * (QMap<QString, int>) TMap::pixNameTable * (QMap<int, QPixmap>) TMap::pixTable * (bool) TMap::isToDisplayAuditErrorsToConsole Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * ImplimentationFixes: activate a valid optimisation & remove redundant code Adding a true as a non-default 3rd argument to TRoomDB::addRoom(...) call in XMLimport::readRoom(...) enables a significant optimisation (skips a computationally expensive step when ADDING a room to new map) which dramatically reduces the time to parse an XML map file. It also pointed to the fact that the TRoomDB::entranceMap was already correctly being handled and didn't need to be regenerated in XMLimport::readRoom(...) so the code that was added in a previous commit was redundant and could be removed. A code error in TMap::slot_setDownloadProgress(...) that caused an issue that a reviewer found on test has been fixed - the total download filesize that was being sent by the Qt system signal that is connected to this slot was a -1 value (as IS DOCUMENTED) when the Qt system does NOT know the size of a QNetworkReply in advance of reaching the end of the download was incorrectly handled in a previous commit in this change set. Also found during testing that there is no need for an error message for the QNetworkReply::OperationCanceledError case in TMap::slot_replayFinished(...) as it is already handled in the TMap::slot_downloadCancel() slot. Changed the text put up onto the progress widget during the XML room parsing to be a room count - which is likely more useful and to only do it for every hundredth room - which reduces any delay "wasted" in writing to the display - combined, the effects seem satisfactory IMHO. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: provide error messages for TLuaInterpreter::loadMap(...) Errors for the XML map file importing process as initiated from the Lua command should be returned to that command rather than plastered onto the main profile console - this commit attempts to perform that effect. In testing found that there was no error handling for failure to find or open the nominated file so messages for that have been added as well. Due to the previous program logic the action of creating a mapper widget using the main toolbar button automatically loaded the "default" (the newest Mudlet Map file format file from the currently active profile's map sub-directory). Under some previous situations it looked as though a map might be loaded twice as mudlet::slot_mapper() was called both directly and via signal/slot action. These were resolved by turning that slot into a wrapper that now calls the body of code formerly within to a new method mudlet::createMapper( bool isToLoadDefaultMapFile = true ) with a the default value as an argument. This allows other usages of the body of code to be called directly with a suitable argument, which for the TConsole::loadMap() & TConsole::importMap() and the dlgProfilePreferences::downloadMap() cases is false as they are all do not want the "default" map! Also: * spotted a word "area" missing from an advisory text in TRoom::auditRooms(...). Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: fix minor bug, correct a spelling, undo a few capitalisations Under certain, unanticipated (error with no error message) conditions TLuaInterpreter::loadMap(...) would push both a nil and then a false value onto the stack for return {wrong} but only indicate one value {correct}. The textual matters were found during peer review. off-by: Stephen Lyons <slysven@virginmedia.com>
2016-10-13 09:18:48 +01:00
file.flush();
file.close();
if (file.open(QFile::ReadOnly | QFile::Text)) {
QString infoMsg = tr("[ INFO ] - ... map downloaded and stored, now parsing it...");
postMessage(infoMsg);
Enhance: fix map downloading code, add manual XML map importing (#326) * Enhance: fix map downloading code, add manual XML map importing A recent move by I.R.E. to using SSL for their public MUD map URLs broke the ability for Mudlet to download those XML format files. This commit addresses this issue (as mentioned in, but not the original problem referred to in https://bugs.launchpad.net/mudlet/+bug/1427364) the revision to the code does now use "https://www.<MUD URL>/maps/map.xml" as a default name for the I.R.E. MUDS - however the method that initiates the download which was moved to TMap class from the dlgMapper one (see below) is now: (bool) TMap::downloadMap( const QString * remoteUrl = Q_NULLPTR, const QString * localFileName = Q_NULLPTR ) which if not supplied with any arguments behaves as before. However the remoteUrl argument may be given as a full QString including the scheme (the bit of the URL at the beginning before the ':') to override that and a second argument may be used to provide a different name to use for the local file name which if is a RELATIVE pathFileName will be resolved in relation to the profile directory. At present no use is made of this additional functionality but it may be useful for use with other MUDs if they should choose to provide XML map files with other remote locations and scripts using a different local filename. As a long-standing thing that needed doing I have finally provided a means to import a map XML file that - for instance - has already been download. It had been noted that there was no way to read those I.R.E. map files even if they had been obtained from a web browser able to correctly handle https: URLs - now both the TLuaInterpreter::loadMap() and the dlgProfilePreference "loadMap" button {NOT the IRE only "map download" one} will both handle files ending in ".xml" (not case sensitive so it'll work MacOS platforms as well!} For the loadMap case it will be necessary to change the filetype filter on the File Selection dialog to select "xml" files. During testing it became clear to me that it was possible to try and read one or more XML files via several mechanisms simultaneously with "unhelpful" consequences. As well as hitting the dlgProfilePreferences IRE "map download" multiple times, the TLuaInterpreter::loadMap() does NOT block until the map has been loaded and as the import time {running of XMLinport::readPackage(...)} is of significant duration for a large map (a debug, without optimisation, build on my 1.8GHz Quad-core took over two minutes to process the current Achaea map file) it is very possible to get conditions where the same profile will try to run XMLinport::readPackage(...) asynchronously - given that a profile only supports ONE map at a time it was necessary to fit a QMutex to prevent the part of the XMLinport class relating to XML Map files being called from different places in the map related code. This means that if a map download is started further downloads and any local map imports will fail until that first download has completed or aborted. Similarly a local import will prevent a download being started. As a side effect this cures: https://bugs.launchpad.net/mudlet/+bug/852861 - "Map download button starts another download thread if one is already going" The previous XML import code was not adding the rooms that it parsed to the relevant TArea::rooms member - although this would be picked-up and fixed by TMap::audit() later on, this would be accompanied by an error message about every single room. The code now builds up this information while parsing the rooms' details and inserts it so that this does not cause report-able problems during the TMap::audit() execution - the data gathered also allows missing areas to be spotted so that if a room claimed to belong to an area that was not included in the preceding areas' data an unnamed area is created for it. As a consequence of the long time to actually parse an XML map file I have enhanced the progress dialog that was originally used to track the map file download. It is now retained until the file is completely imported and shows more information about the process - importantly it shows during the XMLimport::readRoom(...) the room id being processed - and THAT method is the time/cpu hog so seeing something happening during the time that Mudlet otherwise appears to hang is useful feedback even if it adds a few seconds to the overall duration (may be more than a minute). This dialog is now also used during the other routes that involve reading an XML file and there is now a bit of consistence with the on-screen messages. Whilst inspecting XMLimport class I found there was some uncertain initialisation which I have tidied up. In summary: Added: * (bool) TConsole::importMap(const QString & location) * (void) TRoomDB::setAreaRooms(const int areaId, const QSet<int> & roomIds) * image file mudlet_map_download.png used as icon for download/import progress dialog * (bool) TMap::importMap(QFile & file) * (bool) TMap::readXmlMapFile(QFile & file) * (void) TMap::slot_downloadError(QNetworkReply::NetworkError error) * (void) TMap::reportStringToProgressDialog(const QString text) * (void) TMap::reportProgressToProgressDialog(const int current, const int maximum) Revised: * (int)TLuaInterpreter::loadMap( lua_State * ) * Moved XML map download code from dlgMapper class to the TMap one: + (void) dlgMapper::downloadMap() ==> (bool) TMap::downloadMap(const QString * remoteUrl, const QString * localFileName) + (void) dlgMapper::setDownloadProgress(qint64, qint64) ==> (void) TMap::slot_setDownloadProgress(qint64,qint64) + (void) dlgMapper::cancel() ==> (void) TMap::slot_downloadCancel() + (void) dlgMapper::replyFinished(QNetworkReply *) ==> (void) TMap::slot_replyFinished(QNetworkReply *) * Enhanced download progress indication to also include parsing which can take even more time than download! * Provide means to import local XML map file * Prevent trying to import/download more than one map at a time Renamed: * (void) XMLimport::readAreaNames() ==> XMLimport::readArea() - for consistency with related functions Commented out unused: * (void) XMLimport::readUnknownRoomElement() Note the movement of the map file download code to the TMap class does require making the latter a class with the Q_OBJECT macro (which removes the need for Q_DECLARE_TR_FUNCTIONS as a side-effect!) - though as another side-effect the TMap header needed a boost name specifier added to one identifier as that identifier ("property") exists in both boost and QObject classes!!! YOU MAY NEED TO RUN QMAKE ON THE PROJECT IF THE BUILD SYSTEM DOES NOT PICK UP THE ADDITION OF "Q_OBJECT" TO TMAP CLASS. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: Include missing #include, remove unused return value The absence of this was causing build errors on the Travis C.I. platform! Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: move TMap.h to mudlet_MOC_HDRS to fix CMake build issue As we have made TMap inherit from QOject - to have signal/slot functionality that class needs to be run through Qt's MOC - and to do that with the CMake project/build system it needs to be included in the files included in the projects *_MOC_HDRS {and removed from the *_HDRS} variable. Also spotted a trivial error in that specifying a const return value from method is ineffective and pointless - so removed it from: TMap::retrieveMapFileStats(QString,QString *,int *,int *,int *,int *) Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: clean up TMap initialisation/clearing actions Now restores the customEnvColors set up on initialisation but that was cleared when the map replaced with another one that is loaded {which subsequently replaces that element anyway} or imported {which merely writes over it, replacing any matching keys}. Initialises elements that when inspected on the entry to the constructor proper previously were not being set to a consistent value {booleans/ints/floats}. NOTE: This will now clear the map user data member when the map is cleared if the date is required to be saved when one map is loaded OR IMPORTED over an existing one then the data will need to be saved outside of the map - as is already need for areas and rooms user data! Also comment out or remove unused members/methods: * (void) TMap::getConnectedNodesGreaterThanX(int, int) * (void) TMap::getConnectedNodesSmallerThanX(int, int) * (void) TMap::getConnectedNodesGreaterThanY(int, int) * (void) TMap::getConnectedNodesSmallerThanY(int, int) * (void) TMap::astBreitenAnpassung(int, int) * (void) TMap::astHoehenAnpassung(int, int) * (void) TMap::exportMapToDatabase() * (void) TMap::importMapFromDatabase() * (QVector3D) TMap::span * (int) TMap::mViewArea * (QMap<QString, int>) TMap::pixNameTable * (QMap<int, QPixmap>) TMap::pixTable * (bool) TMap::isToDisplayAuditErrorsToConsole Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * ImplimentationFixes: activate a valid optimisation & remove redundant code Adding a true as a non-default 3rd argument to TRoomDB::addRoom(...) call in XMLimport::readRoom(...) enables a significant optimisation (skips a computationally expensive step when ADDING a room to new map) which dramatically reduces the time to parse an XML map file. It also pointed to the fact that the TRoomDB::entranceMap was already correctly being handled and didn't need to be regenerated in XMLimport::readRoom(...) so the code that was added in a previous commit was redundant and could be removed. A code error in TMap::slot_setDownloadProgress(...) that caused an issue that a reviewer found on test has been fixed - the total download filesize that was being sent by the Qt system signal that is connected to this slot was a -1 value (as IS DOCUMENTED) when the Qt system does NOT know the size of a QNetworkReply in advance of reaching the end of the download was incorrectly handled in a previous commit in this change set. Also found during testing that there is no need for an error message for the QNetworkReply::OperationCanceledError case in TMap::slot_replayFinished(...) as it is already handled in the TMap::slot_downloadCancel() slot. Changed the text put up onto the progress widget during the XML room parsing to be a room count - which is likely more useful and to only do it for every hundredth room - which reduces any delay "wasted" in writing to the display - combined, the effects seem satisfactory IMHO. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: provide error messages for TLuaInterpreter::loadMap(...) Errors for the XML map file importing process as initiated from the Lua command should be returned to that command rather than plastered onto the main profile console - this commit attempts to perform that effect. In testing found that there was no error handling for failure to find or open the nominated file so messages for that have been added as well. Due to the previous program logic the action of creating a mapper widget using the main toolbar button automatically loaded the "default" (the newest Mudlet Map file format file from the currently active profile's map sub-directory). Under some previous situations it looked as though a map might be loaded twice as mudlet::slot_mapper() was called both directly and via signal/slot action. These were resolved by turning that slot into a wrapper that now calls the body of code formerly within to a new method mudlet::createMapper( bool isToLoadDefaultMapFile = true ) with a the default value as an argument. This allows other usages of the body of code to be called directly with a suitable argument, which for the TConsole::loadMap() & TConsole::importMap() and the dlgProfilePreferences::downloadMap() cases is false as they are all do not want the "default" map! Also: * spotted a word "area" missing from an advisory text in TRoom::auditRooms(...). Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: fix minor bug, correct a spelling, undo a few capitalisations Under certain, unanticipated (error with no error message) conditions TLuaInterpreter::loadMap(...) would push both a nil and then a false value onto the stack for return {wrong} but only indicate one value {correct}. The textual matters were found during peer review. off-by: Stephen Lyons <slysven@virginmedia.com>
2016-10-13 09:18:48 +01:00
Host* pHost = mpHost;
if (!pHost) {
Enhance: fix map downloading code, add manual XML map importing (#326) * Enhance: fix map downloading code, add manual XML map importing A recent move by I.R.E. to using SSL for their public MUD map URLs broke the ability for Mudlet to download those XML format files. This commit addresses this issue (as mentioned in, but not the original problem referred to in https://bugs.launchpad.net/mudlet/+bug/1427364) the revision to the code does now use "https://www.<MUD URL>/maps/map.xml" as a default name for the I.R.E. MUDS - however the method that initiates the download which was moved to TMap class from the dlgMapper one (see below) is now: (bool) TMap::downloadMap( const QString * remoteUrl = Q_NULLPTR, const QString * localFileName = Q_NULLPTR ) which if not supplied with any arguments behaves as before. However the remoteUrl argument may be given as a full QString including the scheme (the bit of the URL at the beginning before the ':') to override that and a second argument may be used to provide a different name to use for the local file name which if is a RELATIVE pathFileName will be resolved in relation to the profile directory. At present no use is made of this additional functionality but it may be useful for use with other MUDs if they should choose to provide XML map files with other remote locations and scripts using a different local filename. As a long-standing thing that needed doing I have finally provided a means to import a map XML file that - for instance - has already been download. It had been noted that there was no way to read those I.R.E. map files even if they had been obtained from a web browser able to correctly handle https: URLs - now both the TLuaInterpreter::loadMap() and the dlgProfilePreference "loadMap" button {NOT the IRE only "map download" one} will both handle files ending in ".xml" (not case sensitive so it'll work MacOS platforms as well!} For the loadMap case it will be necessary to change the filetype filter on the File Selection dialog to select "xml" files. During testing it became clear to me that it was possible to try and read one or more XML files via several mechanisms simultaneously with "unhelpful" consequences. As well as hitting the dlgProfilePreferences IRE "map download" multiple times, the TLuaInterpreter::loadMap() does NOT block until the map has been loaded and as the import time {running of XMLinport::readPackage(...)} is of significant duration for a large map (a debug, without optimisation, build on my 1.8GHz Quad-core took over two minutes to process the current Achaea map file) it is very possible to get conditions where the same profile will try to run XMLinport::readPackage(...) asynchronously - given that a profile only supports ONE map at a time it was necessary to fit a QMutex to prevent the part of the XMLinport class relating to XML Map files being called from different places in the map related code. This means that if a map download is started further downloads and any local map imports will fail until that first download has completed or aborted. Similarly a local import will prevent a download being started. As a side effect this cures: https://bugs.launchpad.net/mudlet/+bug/852861 - "Map download button starts another download thread if one is already going" The previous XML import code was not adding the rooms that it parsed to the relevant TArea::rooms member - although this would be picked-up and fixed by TMap::audit() later on, this would be accompanied by an error message about every single room. The code now builds up this information while parsing the rooms' details and inserts it so that this does not cause report-able problems during the TMap::audit() execution - the data gathered also allows missing areas to be spotted so that if a room claimed to belong to an area that was not included in the preceding areas' data an unnamed area is created for it. As a consequence of the long time to actually parse an XML map file I have enhanced the progress dialog that was originally used to track the map file download. It is now retained until the file is completely imported and shows more information about the process - importantly it shows during the XMLimport::readRoom(...) the room id being processed - and THAT method is the time/cpu hog so seeing something happening during the time that Mudlet otherwise appears to hang is useful feedback even if it adds a few seconds to the overall duration (may be more than a minute). This dialog is now also used during the other routes that involve reading an XML file and there is now a bit of consistence with the on-screen messages. Whilst inspecting XMLimport class I found there was some uncertain initialisation which I have tidied up. In summary: Added: * (bool) TConsole::importMap(const QString & location) * (void) TRoomDB::setAreaRooms(const int areaId, const QSet<int> & roomIds) * image file mudlet_map_download.png used as icon for download/import progress dialog * (bool) TMap::importMap(QFile & file) * (bool) TMap::readXmlMapFile(QFile & file) * (void) TMap::slot_downloadError(QNetworkReply::NetworkError error) * (void) TMap::reportStringToProgressDialog(const QString text) * (void) TMap::reportProgressToProgressDialog(const int current, const int maximum) Revised: * (int)TLuaInterpreter::loadMap( lua_State * ) * Moved XML map download code from dlgMapper class to the TMap one: + (void) dlgMapper::downloadMap() ==> (bool) TMap::downloadMap(const QString * remoteUrl, const QString * localFileName) + (void) dlgMapper::setDownloadProgress(qint64, qint64) ==> (void) TMap::slot_setDownloadProgress(qint64,qint64) + (void) dlgMapper::cancel() ==> (void) TMap::slot_downloadCancel() + (void) dlgMapper::replyFinished(QNetworkReply *) ==> (void) TMap::slot_replyFinished(QNetworkReply *) * Enhanced download progress indication to also include parsing which can take even more time than download! * Provide means to import local XML map file * Prevent trying to import/download more than one map at a time Renamed: * (void) XMLimport::readAreaNames() ==> XMLimport::readArea() - for consistency with related functions Commented out unused: * (void) XMLimport::readUnknownRoomElement() Note the movement of the map file download code to the TMap class does require making the latter a class with the Q_OBJECT macro (which removes the need for Q_DECLARE_TR_FUNCTIONS as a side-effect!) - though as another side-effect the TMap header needed a boost name specifier added to one identifier as that identifier ("property") exists in both boost and QObject classes!!! YOU MAY NEED TO RUN QMAKE ON THE PROJECT IF THE BUILD SYSTEM DOES NOT PICK UP THE ADDITION OF "Q_OBJECT" TO TMAP CLASS. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: Include missing #include, remove unused return value The absence of this was causing build errors on the Travis C.I. platform! Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: move TMap.h to mudlet_MOC_HDRS to fix CMake build issue As we have made TMap inherit from QOject - to have signal/slot functionality that class needs to be run through Qt's MOC - and to do that with the CMake project/build system it needs to be included in the files included in the projects *_MOC_HDRS {and removed from the *_HDRS} variable. Also spotted a trivial error in that specifying a const return value from method is ineffective and pointless - so removed it from: TMap::retrieveMapFileStats(QString,QString *,int *,int *,int *,int *) Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: clean up TMap initialisation/clearing actions Now restores the customEnvColors set up on initialisation but that was cleared when the map replaced with another one that is loaded {which subsequently replaces that element anyway} or imported {which merely writes over it, replacing any matching keys}. Initialises elements that when inspected on the entry to the constructor proper previously were not being set to a consistent value {booleans/ints/floats}. NOTE: This will now clear the map user data member when the map is cleared if the date is required to be saved when one map is loaded OR IMPORTED over an existing one then the data will need to be saved outside of the map - as is already need for areas and rooms user data! Also comment out or remove unused members/methods: * (void) TMap::getConnectedNodesGreaterThanX(int, int) * (void) TMap::getConnectedNodesSmallerThanX(int, int) * (void) TMap::getConnectedNodesGreaterThanY(int, int) * (void) TMap::getConnectedNodesSmallerThanY(int, int) * (void) TMap::astBreitenAnpassung(int, int) * (void) TMap::astHoehenAnpassung(int, int) * (void) TMap::exportMapToDatabase() * (void) TMap::importMapFromDatabase() * (QVector3D) TMap::span * (int) TMap::mViewArea * (QMap<QString, int>) TMap::pixNameTable * (QMap<int, QPixmap>) TMap::pixTable * (bool) TMap::isToDisplayAuditErrorsToConsole Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * ImplimentationFixes: activate a valid optimisation & remove redundant code Adding a true as a non-default 3rd argument to TRoomDB::addRoom(...) call in XMLimport::readRoom(...) enables a significant optimisation (skips a computationally expensive step when ADDING a room to new map) which dramatically reduces the time to parse an XML map file. It also pointed to the fact that the TRoomDB::entranceMap was already correctly being handled and didn't need to be regenerated in XMLimport::readRoom(...) so the code that was added in a previous commit was redundant and could be removed. A code error in TMap::slot_setDownloadProgress(...) that caused an issue that a reviewer found on test has been fixed - the total download filesize that was being sent by the Qt system signal that is connected to this slot was a -1 value (as IS DOCUMENTED) when the Qt system does NOT know the size of a QNetworkReply in advance of reaching the end of the download was incorrectly handled in a previous commit in this change set. Also found during testing that there is no need for an error message for the QNetworkReply::OperationCanceledError case in TMap::slot_replayFinished(...) as it is already handled in the TMap::slot_downloadCancel() slot. Changed the text put up onto the progress widget during the XML room parsing to be a room count - which is likely more useful and to only do it for every hundredth room - which reduces any delay "wasted" in writing to the display - combined, the effects seem satisfactory IMHO. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: provide error messages for TLuaInterpreter::loadMap(...) Errors for the XML map file importing process as initiated from the Lua command should be returned to that command rather than plastered onto the main profile console - this commit attempts to perform that effect. In testing found that there was no error handling for failure to find or open the nominated file so messages for that have been added as well. Due to the previous program logic the action of creating a mapper widget using the main toolbar button automatically loaded the "default" (the newest Mudlet Map file format file from the currently active profile's map sub-directory). Under some previous situations it looked as though a map might be loaded twice as mudlet::slot_mapper() was called both directly and via signal/slot action. These were resolved by turning that slot into a wrapper that now calls the body of code formerly within to a new method mudlet::createMapper( bool isToLoadDefaultMapFile = true ) with a the default value as an argument. This allows other usages of the body of code to be called directly with a suitable argument, which for the TConsole::loadMap() & TConsole::importMap() and the dlgProfilePreferences::downloadMap() cases is false as they are all do not want the "default" map! Also: * spotted a word "area" missing from an advisory text in TRoom::auditRooms(...). Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: fix minor bug, correct a spelling, undo a few capitalisations Under certain, unanticipated (error with no error message) conditions TLuaInterpreter::loadMap(...) would push both a nil and then a false value onto the stack for return {wrong} but only indicate one value {correct}. The textual matters were found during peer review. off-by: Stephen Lyons <slysven@virginmedia.com>
2016-10-13 09:18:48 +01:00
qWarning() << "TMap::slot_replyFinished( QNetworkReply * ) ERROR - NULL Host pointer - something is really wrong!";
mXmlImportMutex.unlock();
return;
}
// Since the download is complete but we do not offer to
// cancel the required post-processing we should now hide
// the cancel/abort button:
mpProgressDialog->setCancelButton(Q_NULLPTR);
Enhance: fix map downloading code, add manual XML map importing (#326) * Enhance: fix map downloading code, add manual XML map importing A recent move by I.R.E. to using SSL for their public MUD map URLs broke the ability for Mudlet to download those XML format files. This commit addresses this issue (as mentioned in, but not the original problem referred to in https://bugs.launchpad.net/mudlet/+bug/1427364) the revision to the code does now use "https://www.<MUD URL>/maps/map.xml" as a default name for the I.R.E. MUDS - however the method that initiates the download which was moved to TMap class from the dlgMapper one (see below) is now: (bool) TMap::downloadMap( const QString * remoteUrl = Q_NULLPTR, const QString * localFileName = Q_NULLPTR ) which if not supplied with any arguments behaves as before. However the remoteUrl argument may be given as a full QString including the scheme (the bit of the URL at the beginning before the ':') to override that and a second argument may be used to provide a different name to use for the local file name which if is a RELATIVE pathFileName will be resolved in relation to the profile directory. At present no use is made of this additional functionality but it may be useful for use with other MUDs if they should choose to provide XML map files with other remote locations and scripts using a different local filename. As a long-standing thing that needed doing I have finally provided a means to import a map XML file that - for instance - has already been download. It had been noted that there was no way to read those I.R.E. map files even if they had been obtained from a web browser able to correctly handle https: URLs - now both the TLuaInterpreter::loadMap() and the dlgProfilePreference "loadMap" button {NOT the IRE only "map download" one} will both handle files ending in ".xml" (not case sensitive so it'll work MacOS platforms as well!} For the loadMap case it will be necessary to change the filetype filter on the File Selection dialog to select "xml" files. During testing it became clear to me that it was possible to try and read one or more XML files via several mechanisms simultaneously with "unhelpful" consequences. As well as hitting the dlgProfilePreferences IRE "map download" multiple times, the TLuaInterpreter::loadMap() does NOT block until the map has been loaded and as the import time {running of XMLinport::readPackage(...)} is of significant duration for a large map (a debug, without optimisation, build on my 1.8GHz Quad-core took over two minutes to process the current Achaea map file) it is very possible to get conditions where the same profile will try to run XMLinport::readPackage(...) asynchronously - given that a profile only supports ONE map at a time it was necessary to fit a QMutex to prevent the part of the XMLinport class relating to XML Map files being called from different places in the map related code. This means that if a map download is started further downloads and any local map imports will fail until that first download has completed or aborted. Similarly a local import will prevent a download being started. As a side effect this cures: https://bugs.launchpad.net/mudlet/+bug/852861 - "Map download button starts another download thread if one is already going" The previous XML import code was not adding the rooms that it parsed to the relevant TArea::rooms member - although this would be picked-up and fixed by TMap::audit() later on, this would be accompanied by an error message about every single room. The code now builds up this information while parsing the rooms' details and inserts it so that this does not cause report-able problems during the TMap::audit() execution - the data gathered also allows missing areas to be spotted so that if a room claimed to belong to an area that was not included in the preceding areas' data an unnamed area is created for it. As a consequence of the long time to actually parse an XML map file I have enhanced the progress dialog that was originally used to track the map file download. It is now retained until the file is completely imported and shows more information about the process - importantly it shows during the XMLimport::readRoom(...) the room id being processed - and THAT method is the time/cpu hog so seeing something happening during the time that Mudlet otherwise appears to hang is useful feedback even if it adds a few seconds to the overall duration (may be more than a minute). This dialog is now also used during the other routes that involve reading an XML file and there is now a bit of consistence with the on-screen messages. Whilst inspecting XMLimport class I found there was some uncertain initialisation which I have tidied up. In summary: Added: * (bool) TConsole::importMap(const QString & location) * (void) TRoomDB::setAreaRooms(const int areaId, const QSet<int> & roomIds) * image file mudlet_map_download.png used as icon for download/import progress dialog * (bool) TMap::importMap(QFile & file) * (bool) TMap::readXmlMapFile(QFile & file) * (void) TMap::slot_downloadError(QNetworkReply::NetworkError error) * (void) TMap::reportStringToProgressDialog(const QString text) * (void) TMap::reportProgressToProgressDialog(const int current, const int maximum) Revised: * (int)TLuaInterpreter::loadMap( lua_State * ) * Moved XML map download code from dlgMapper class to the TMap one: + (void) dlgMapper::downloadMap() ==> (bool) TMap::downloadMap(const QString * remoteUrl, const QString * localFileName) + (void) dlgMapper::setDownloadProgress(qint64, qint64) ==> (void) TMap::slot_setDownloadProgress(qint64,qint64) + (void) dlgMapper::cancel() ==> (void) TMap::slot_downloadCancel() + (void) dlgMapper::replyFinished(QNetworkReply *) ==> (void) TMap::slot_replyFinished(QNetworkReply *) * Enhanced download progress indication to also include parsing which can take even more time than download! * Provide means to import local XML map file * Prevent trying to import/download more than one map at a time Renamed: * (void) XMLimport::readAreaNames() ==> XMLimport::readArea() - for consistency with related functions Commented out unused: * (void) XMLimport::readUnknownRoomElement() Note the movement of the map file download code to the TMap class does require making the latter a class with the Q_OBJECT macro (which removes the need for Q_DECLARE_TR_FUNCTIONS as a side-effect!) - though as another side-effect the TMap header needed a boost name specifier added to one identifier as that identifier ("property") exists in both boost and QObject classes!!! YOU MAY NEED TO RUN QMAKE ON THE PROJECT IF THE BUILD SYSTEM DOES NOT PICK UP THE ADDITION OF "Q_OBJECT" TO TMAP CLASS. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: Include missing #include, remove unused return value The absence of this was causing build errors on the Travis C.I. platform! Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: move TMap.h to mudlet_MOC_HDRS to fix CMake build issue As we have made TMap inherit from QOject - to have signal/slot functionality that class needs to be run through Qt's MOC - and to do that with the CMake project/build system it needs to be included in the files included in the projects *_MOC_HDRS {and removed from the *_HDRS} variable. Also spotted a trivial error in that specifying a const return value from method is ineffective and pointless - so removed it from: TMap::retrieveMapFileStats(QString,QString *,int *,int *,int *,int *) Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: clean up TMap initialisation/clearing actions Now restores the customEnvColors set up on initialisation but that was cleared when the map replaced with another one that is loaded {which subsequently replaces that element anyway} or imported {which merely writes over it, replacing any matching keys}. Initialises elements that when inspected on the entry to the constructor proper previously were not being set to a consistent value {booleans/ints/floats}. NOTE: This will now clear the map user data member when the map is cleared if the date is required to be saved when one map is loaded OR IMPORTED over an existing one then the data will need to be saved outside of the map - as is already need for areas and rooms user data! Also comment out or remove unused members/methods: * (void) TMap::getConnectedNodesGreaterThanX(int, int) * (void) TMap::getConnectedNodesSmallerThanX(int, int) * (void) TMap::getConnectedNodesGreaterThanY(int, int) * (void) TMap::getConnectedNodesSmallerThanY(int, int) * (void) TMap::astBreitenAnpassung(int, int) * (void) TMap::astHoehenAnpassung(int, int) * (void) TMap::exportMapToDatabase() * (void) TMap::importMapFromDatabase() * (QVector3D) TMap::span * (int) TMap::mViewArea * (QMap<QString, int>) TMap::pixNameTable * (QMap<int, QPixmap>) TMap::pixTable * (bool) TMap::isToDisplayAuditErrorsToConsole Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * ImplimentationFixes: activate a valid optimisation & remove redundant code Adding a true as a non-default 3rd argument to TRoomDB::addRoom(...) call in XMLimport::readRoom(...) enables a significant optimisation (skips a computationally expensive step when ADDING a room to new map) which dramatically reduces the time to parse an XML map file. It also pointed to the fact that the TRoomDB::entranceMap was already correctly being handled and didn't need to be regenerated in XMLimport::readRoom(...) so the code that was added in a previous commit was redundant and could be removed. A code error in TMap::slot_setDownloadProgress(...) that caused an issue that a reviewer found on test has been fixed - the total download filesize that was being sent by the Qt system signal that is connected to this slot was a -1 value (as IS DOCUMENTED) when the Qt system does NOT know the size of a QNetworkReply in advance of reaching the end of the download was incorrectly handled in a previous commit in this change set. Also found during testing that there is no need for an error message for the QNetworkReply::OperationCanceledError case in TMap::slot_replayFinished(...) as it is already handled in the TMap::slot_downloadCancel() slot. Changed the text put up onto the progress widget during the XML room parsing to be a room count - which is likely more useful and to only do it for every hundredth room - which reduces any delay "wasted" in writing to the display - combined, the effects seem satisfactory IMHO. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: provide error messages for TLuaInterpreter::loadMap(...) Errors for the XML map file importing process as initiated from the Lua command should be returned to that command rather than plastered onto the main profile console - this commit attempts to perform that effect. In testing found that there was no error handling for failure to find or open the nominated file so messages for that have been added as well. Due to the previous program logic the action of creating a mapper widget using the main toolbar button automatically loaded the "default" (the newest Mudlet Map file format file from the currently active profile's map sub-directory). Under some previous situations it looked as though a map might be loaded twice as mudlet::slot_mapper() was called both directly and via signal/slot action. These were resolved by turning that slot into a wrapper that now calls the body of code formerly within to a new method mudlet::createMapper( bool isToLoadDefaultMapFile = true ) with a the default value as an argument. This allows other usages of the body of code to be called directly with a suitable argument, which for the TConsole::loadMap() & TConsole::importMap() and the dlgProfilePreferences::downloadMap() cases is false as they are all do not want the "default" map! Also: * spotted a word "area" missing from an advisory text in TRoom::auditRooms(...). Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: fix minor bug, correct a spelling, undo a few capitalisations Under certain, unanticipated (error with no error message) conditions TLuaInterpreter::loadMap(...) would push both a nil and then a false value onto the stack for return {wrong} but only indicate one value {correct}. The textual matters were found during peer review. off-by: Stephen Lyons <slysven@virginmedia.com>
2016-10-13 09:18:48 +01:00
// The action to parse the XML file has been refactored to
// a separate method so that it can be shared with the
// direct importation of a local copy of a map file.
if (readXmlMapFile(file)) {
Enhance: fix map downloading code, add manual XML map importing (#326) * Enhance: fix map downloading code, add manual XML map importing A recent move by I.R.E. to using SSL for their public MUD map URLs broke the ability for Mudlet to download those XML format files. This commit addresses this issue (as mentioned in, but not the original problem referred to in https://bugs.launchpad.net/mudlet/+bug/1427364) the revision to the code does now use "https://www.<MUD URL>/maps/map.xml" as a default name for the I.R.E. MUDS - however the method that initiates the download which was moved to TMap class from the dlgMapper one (see below) is now: (bool) TMap::downloadMap( const QString * remoteUrl = Q_NULLPTR, const QString * localFileName = Q_NULLPTR ) which if not supplied with any arguments behaves as before. However the remoteUrl argument may be given as a full QString including the scheme (the bit of the URL at the beginning before the ':') to override that and a second argument may be used to provide a different name to use for the local file name which if is a RELATIVE pathFileName will be resolved in relation to the profile directory. At present no use is made of this additional functionality but it may be useful for use with other MUDs if they should choose to provide XML map files with other remote locations and scripts using a different local filename. As a long-standing thing that needed doing I have finally provided a means to import a map XML file that - for instance - has already been download. It had been noted that there was no way to read those I.R.E. map files even if they had been obtained from a web browser able to correctly handle https: URLs - now both the TLuaInterpreter::loadMap() and the dlgProfilePreference "loadMap" button {NOT the IRE only "map download" one} will both handle files ending in ".xml" (not case sensitive so it'll work MacOS platforms as well!} For the loadMap case it will be necessary to change the filetype filter on the File Selection dialog to select "xml" files. During testing it became clear to me that it was possible to try and read one or more XML files via several mechanisms simultaneously with "unhelpful" consequences. As well as hitting the dlgProfilePreferences IRE "map download" multiple times, the TLuaInterpreter::loadMap() does NOT block until the map has been loaded and as the import time {running of XMLinport::readPackage(...)} is of significant duration for a large map (a debug, without optimisation, build on my 1.8GHz Quad-core took over two minutes to process the current Achaea map file) it is very possible to get conditions where the same profile will try to run XMLinport::readPackage(...) asynchronously - given that a profile only supports ONE map at a time it was necessary to fit a QMutex to prevent the part of the XMLinport class relating to XML Map files being called from different places in the map related code. This means that if a map download is started further downloads and any local map imports will fail until that first download has completed or aborted. Similarly a local import will prevent a download being started. As a side effect this cures: https://bugs.launchpad.net/mudlet/+bug/852861 - "Map download button starts another download thread if one is already going" The previous XML import code was not adding the rooms that it parsed to the relevant TArea::rooms member - although this would be picked-up and fixed by TMap::audit() later on, this would be accompanied by an error message about every single room. The code now builds up this information while parsing the rooms' details and inserts it so that this does not cause report-able problems during the TMap::audit() execution - the data gathered also allows missing areas to be spotted so that if a room claimed to belong to an area that was not included in the preceding areas' data an unnamed area is created for it. As a consequence of the long time to actually parse an XML map file I have enhanced the progress dialog that was originally used to track the map file download. It is now retained until the file is completely imported and shows more information about the process - importantly it shows during the XMLimport::readRoom(...) the room id being processed - and THAT method is the time/cpu hog so seeing something happening during the time that Mudlet otherwise appears to hang is useful feedback even if it adds a few seconds to the overall duration (may be more than a minute). This dialog is now also used during the other routes that involve reading an XML file and there is now a bit of consistence with the on-screen messages. Whilst inspecting XMLimport class I found there was some uncertain initialisation which I have tidied up. In summary: Added: * (bool) TConsole::importMap(const QString & location) * (void) TRoomDB::setAreaRooms(const int areaId, const QSet<int> & roomIds) * image file mudlet_map_download.png used as icon for download/import progress dialog * (bool) TMap::importMap(QFile & file) * (bool) TMap::readXmlMapFile(QFile & file) * (void) TMap::slot_downloadError(QNetworkReply::NetworkError error) * (void) TMap::reportStringToProgressDialog(const QString text) * (void) TMap::reportProgressToProgressDialog(const int current, const int maximum) Revised: * (int)TLuaInterpreter::loadMap( lua_State * ) * Moved XML map download code from dlgMapper class to the TMap one: + (void) dlgMapper::downloadMap() ==> (bool) TMap::downloadMap(const QString * remoteUrl, const QString * localFileName) + (void) dlgMapper::setDownloadProgress(qint64, qint64) ==> (void) TMap::slot_setDownloadProgress(qint64,qint64) + (void) dlgMapper::cancel() ==> (void) TMap::slot_downloadCancel() + (void) dlgMapper::replyFinished(QNetworkReply *) ==> (void) TMap::slot_replyFinished(QNetworkReply *) * Enhanced download progress indication to also include parsing which can take even more time than download! * Provide means to import local XML map file * Prevent trying to import/download more than one map at a time Renamed: * (void) XMLimport::readAreaNames() ==> XMLimport::readArea() - for consistency with related functions Commented out unused: * (void) XMLimport::readUnknownRoomElement() Note the movement of the map file download code to the TMap class does require making the latter a class with the Q_OBJECT macro (which removes the need for Q_DECLARE_TR_FUNCTIONS as a side-effect!) - though as another side-effect the TMap header needed a boost name specifier added to one identifier as that identifier ("property") exists in both boost and QObject classes!!! YOU MAY NEED TO RUN QMAKE ON THE PROJECT IF THE BUILD SYSTEM DOES NOT PICK UP THE ADDITION OF "Q_OBJECT" TO TMAP CLASS. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: Include missing #include, remove unused return value The absence of this was causing build errors on the Travis C.I. platform! Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: move TMap.h to mudlet_MOC_HDRS to fix CMake build issue As we have made TMap inherit from QOject - to have signal/slot functionality that class needs to be run through Qt's MOC - and to do that with the CMake project/build system it needs to be included in the files included in the projects *_MOC_HDRS {and removed from the *_HDRS} variable. Also spotted a trivial error in that specifying a const return value from method is ineffective and pointless - so removed it from: TMap::retrieveMapFileStats(QString,QString *,int *,int *,int *,int *) Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: clean up TMap initialisation/clearing actions Now restores the customEnvColors set up on initialisation but that was cleared when the map replaced with another one that is loaded {which subsequently replaces that element anyway} or imported {which merely writes over it, replacing any matching keys}. Initialises elements that when inspected on the entry to the constructor proper previously were not being set to a consistent value {booleans/ints/floats}. NOTE: This will now clear the map user data member when the map is cleared if the date is required to be saved when one map is loaded OR IMPORTED over an existing one then the data will need to be saved outside of the map - as is already need for areas and rooms user data! Also comment out or remove unused members/methods: * (void) TMap::getConnectedNodesGreaterThanX(int, int) * (void) TMap::getConnectedNodesSmallerThanX(int, int) * (void) TMap::getConnectedNodesGreaterThanY(int, int) * (void) TMap::getConnectedNodesSmallerThanY(int, int) * (void) TMap::astBreitenAnpassung(int, int) * (void) TMap::astHoehenAnpassung(int, int) * (void) TMap::exportMapToDatabase() * (void) TMap::importMapFromDatabase() * (QVector3D) TMap::span * (int) TMap::mViewArea * (QMap<QString, int>) TMap::pixNameTable * (QMap<int, QPixmap>) TMap::pixTable * (bool) TMap::isToDisplayAuditErrorsToConsole Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * ImplimentationFixes: activate a valid optimisation & remove redundant code Adding a true as a non-default 3rd argument to TRoomDB::addRoom(...) call in XMLimport::readRoom(...) enables a significant optimisation (skips a computationally expensive step when ADDING a room to new map) which dramatically reduces the time to parse an XML map file. It also pointed to the fact that the TRoomDB::entranceMap was already correctly being handled and didn't need to be regenerated in XMLimport::readRoom(...) so the code that was added in a previous commit was redundant and could be removed. A code error in TMap::slot_setDownloadProgress(...) that caused an issue that a reviewer found on test has been fixed - the total download filesize that was being sent by the Qt system signal that is connected to this slot was a -1 value (as IS DOCUMENTED) when the Qt system does NOT know the size of a QNetworkReply in advance of reaching the end of the download was incorrectly handled in a previous commit in this change set. Also found during testing that there is no need for an error message for the QNetworkReply::OperationCanceledError case in TMap::slot_replayFinished(...) as it is already handled in the TMap::slot_downloadCancel() slot. Changed the text put up onto the progress widget during the XML room parsing to be a room count - which is likely more useful and to only do it for every hundredth room - which reduces any delay "wasted" in writing to the display - combined, the effects seem satisfactory IMHO. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: provide error messages for TLuaInterpreter::loadMap(...) Errors for the XML map file importing process as initiated from the Lua command should be returned to that command rather than plastered onto the main profile console - this commit attempts to perform that effect. In testing found that there was no error handling for failure to find or open the nominated file so messages for that have been added as well. Due to the previous program logic the action of creating a mapper widget using the main toolbar button automatically loaded the "default" (the newest Mudlet Map file format file from the currently active profile's map sub-directory). Under some previous situations it looked as though a map might be loaded twice as mudlet::slot_mapper() was called both directly and via signal/slot action. These were resolved by turning that slot into a wrapper that now calls the body of code formerly within to a new method mudlet::createMapper( bool isToLoadDefaultMapFile = true ) with a the default value as an argument. This allows other usages of the body of code to be called directly with a suitable argument, which for the TConsole::loadMap() & TConsole::importMap() and the dlgProfilePreferences::downloadMap() cases is false as they are all do not want the "default" map! Also: * spotted a word "area" missing from an advisory text in TRoom::auditRooms(...). Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: fix minor bug, correct a spelling, undo a few capitalisations Under certain, unanticipated (error with no error message) conditions TLuaInterpreter::loadMap(...) would push both a nil and then a false value onto the stack for return {wrong} but only indicate one value {correct}. The textual matters were found during peer review. off-by: Stephen Lyons <slysven@virginmedia.com>
2016-10-13 09:18:48 +01:00
TEvent mapDownloadEvent;
mapDownloadEvent.mArgumentList.append(QLatin1String("sysMapDownloadEvent"));
mapDownloadEvent.mArgumentTypeList.append(ARGUMENT_TYPE_STRING);
pHost->raiseEvent(mapDownloadEvent);
} else {
Enhance: fix map downloading code, add manual XML map importing (#326) * Enhance: fix map downloading code, add manual XML map importing A recent move by I.R.E. to using SSL for their public MUD map URLs broke the ability for Mudlet to download those XML format files. This commit addresses this issue (as mentioned in, but not the original problem referred to in https://bugs.launchpad.net/mudlet/+bug/1427364) the revision to the code does now use "https://www.<MUD URL>/maps/map.xml" as a default name for the I.R.E. MUDS - however the method that initiates the download which was moved to TMap class from the dlgMapper one (see below) is now: (bool) TMap::downloadMap( const QString * remoteUrl = Q_NULLPTR, const QString * localFileName = Q_NULLPTR ) which if not supplied with any arguments behaves as before. However the remoteUrl argument may be given as a full QString including the scheme (the bit of the URL at the beginning before the ':') to override that and a second argument may be used to provide a different name to use for the local file name which if is a RELATIVE pathFileName will be resolved in relation to the profile directory. At present no use is made of this additional functionality but it may be useful for use with other MUDs if they should choose to provide XML map files with other remote locations and scripts using a different local filename. As a long-standing thing that needed doing I have finally provided a means to import a map XML file that - for instance - has already been download. It had been noted that there was no way to read those I.R.E. map files even if they had been obtained from a web browser able to correctly handle https: URLs - now both the TLuaInterpreter::loadMap() and the dlgProfilePreference "loadMap" button {NOT the IRE only "map download" one} will both handle files ending in ".xml" (not case sensitive so it'll work MacOS platforms as well!} For the loadMap case it will be necessary to change the filetype filter on the File Selection dialog to select "xml" files. During testing it became clear to me that it was possible to try and read one or more XML files via several mechanisms simultaneously with "unhelpful" consequences. As well as hitting the dlgProfilePreferences IRE "map download" multiple times, the TLuaInterpreter::loadMap() does NOT block until the map has been loaded and as the import time {running of XMLinport::readPackage(...)} is of significant duration for a large map (a debug, without optimisation, build on my 1.8GHz Quad-core took over two minutes to process the current Achaea map file) it is very possible to get conditions where the same profile will try to run XMLinport::readPackage(...) asynchronously - given that a profile only supports ONE map at a time it was necessary to fit a QMutex to prevent the part of the XMLinport class relating to XML Map files being called from different places in the map related code. This means that if a map download is started further downloads and any local map imports will fail until that first download has completed or aborted. Similarly a local import will prevent a download being started. As a side effect this cures: https://bugs.launchpad.net/mudlet/+bug/852861 - "Map download button starts another download thread if one is already going" The previous XML import code was not adding the rooms that it parsed to the relevant TArea::rooms member - although this would be picked-up and fixed by TMap::audit() later on, this would be accompanied by an error message about every single room. The code now builds up this information while parsing the rooms' details and inserts it so that this does not cause report-able problems during the TMap::audit() execution - the data gathered also allows missing areas to be spotted so that if a room claimed to belong to an area that was not included in the preceding areas' data an unnamed area is created for it. As a consequence of the long time to actually parse an XML map file I have enhanced the progress dialog that was originally used to track the map file download. It is now retained until the file is completely imported and shows more information about the process - importantly it shows during the XMLimport::readRoom(...) the room id being processed - and THAT method is the time/cpu hog so seeing something happening during the time that Mudlet otherwise appears to hang is useful feedback even if it adds a few seconds to the overall duration (may be more than a minute). This dialog is now also used during the other routes that involve reading an XML file and there is now a bit of consistence with the on-screen messages. Whilst inspecting XMLimport class I found there was some uncertain initialisation which I have tidied up. In summary: Added: * (bool) TConsole::importMap(const QString & location) * (void) TRoomDB::setAreaRooms(const int areaId, const QSet<int> & roomIds) * image file mudlet_map_download.png used as icon for download/import progress dialog * (bool) TMap::importMap(QFile & file) * (bool) TMap::readXmlMapFile(QFile & file) * (void) TMap::slot_downloadError(QNetworkReply::NetworkError error) * (void) TMap::reportStringToProgressDialog(const QString text) * (void) TMap::reportProgressToProgressDialog(const int current, const int maximum) Revised: * (int)TLuaInterpreter::loadMap( lua_State * ) * Moved XML map download code from dlgMapper class to the TMap one: + (void) dlgMapper::downloadMap() ==> (bool) TMap::downloadMap(const QString * remoteUrl, const QString * localFileName) + (void) dlgMapper::setDownloadProgress(qint64, qint64) ==> (void) TMap::slot_setDownloadProgress(qint64,qint64) + (void) dlgMapper::cancel() ==> (void) TMap::slot_downloadCancel() + (void) dlgMapper::replyFinished(QNetworkReply *) ==> (void) TMap::slot_replyFinished(QNetworkReply *) * Enhanced download progress indication to also include parsing which can take even more time than download! * Provide means to import local XML map file * Prevent trying to import/download more than one map at a time Renamed: * (void) XMLimport::readAreaNames() ==> XMLimport::readArea() - for consistency with related functions Commented out unused: * (void) XMLimport::readUnknownRoomElement() Note the movement of the map file download code to the TMap class does require making the latter a class with the Q_OBJECT macro (which removes the need for Q_DECLARE_TR_FUNCTIONS as a side-effect!) - though as another side-effect the TMap header needed a boost name specifier added to one identifier as that identifier ("property") exists in both boost and QObject classes!!! YOU MAY NEED TO RUN QMAKE ON THE PROJECT IF THE BUILD SYSTEM DOES NOT PICK UP THE ADDITION OF "Q_OBJECT" TO TMAP CLASS. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: Include missing #include, remove unused return value The absence of this was causing build errors on the Travis C.I. platform! Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: move TMap.h to mudlet_MOC_HDRS to fix CMake build issue As we have made TMap inherit from QOject - to have signal/slot functionality that class needs to be run through Qt's MOC - and to do that with the CMake project/build system it needs to be included in the files included in the projects *_MOC_HDRS {and removed from the *_HDRS} variable. Also spotted a trivial error in that specifying a const return value from method is ineffective and pointless - so removed it from: TMap::retrieveMapFileStats(QString,QString *,int *,int *,int *,int *) Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: clean up TMap initialisation/clearing actions Now restores the customEnvColors set up on initialisation but that was cleared when the map replaced with another one that is loaded {which subsequently replaces that element anyway} or imported {which merely writes over it, replacing any matching keys}. Initialises elements that when inspected on the entry to the constructor proper previously were not being set to a consistent value {booleans/ints/floats}. NOTE: This will now clear the map user data member when the map is cleared if the date is required to be saved when one map is loaded OR IMPORTED over an existing one then the data will need to be saved outside of the map - as is already need for areas and rooms user data! Also comment out or remove unused members/methods: * (void) TMap::getConnectedNodesGreaterThanX(int, int) * (void) TMap::getConnectedNodesSmallerThanX(int, int) * (void) TMap::getConnectedNodesGreaterThanY(int, int) * (void) TMap::getConnectedNodesSmallerThanY(int, int) * (void) TMap::astBreitenAnpassung(int, int) * (void) TMap::astHoehenAnpassung(int, int) * (void) TMap::exportMapToDatabase() * (void) TMap::importMapFromDatabase() * (QVector3D) TMap::span * (int) TMap::mViewArea * (QMap<QString, int>) TMap::pixNameTable * (QMap<int, QPixmap>) TMap::pixTable * (bool) TMap::isToDisplayAuditErrorsToConsole Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * ImplimentationFixes: activate a valid optimisation & remove redundant code Adding a true as a non-default 3rd argument to TRoomDB::addRoom(...) call in XMLimport::readRoom(...) enables a significant optimisation (skips a computationally expensive step when ADDING a room to new map) which dramatically reduces the time to parse an XML map file. It also pointed to the fact that the TRoomDB::entranceMap was already correctly being handled and didn't need to be regenerated in XMLimport::readRoom(...) so the code that was added in a previous commit was redundant and could be removed. A code error in TMap::slot_setDownloadProgress(...) that caused an issue that a reviewer found on test has been fixed - the total download filesize that was being sent by the Qt system signal that is connected to this slot was a -1 value (as IS DOCUMENTED) when the Qt system does NOT know the size of a QNetworkReply in advance of reaching the end of the download was incorrectly handled in a previous commit in this change set. Also found during testing that there is no need for an error message for the QNetworkReply::OperationCanceledError case in TMap::slot_replayFinished(...) as it is already handled in the TMap::slot_downloadCancel() slot. Changed the text put up onto the progress widget during the XML room parsing to be a room count - which is likely more useful and to only do it for every hundredth room - which reduces any delay "wasted" in writing to the display - combined, the effects seem satisfactory IMHO. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: provide error messages for TLuaInterpreter::loadMap(...) Errors for the XML map file importing process as initiated from the Lua command should be returned to that command rather than plastered onto the main profile console - this commit attempts to perform that effect. In testing found that there was no error handling for failure to find or open the nominated file so messages for that have been added as well. Due to the previous program logic the action of creating a mapper widget using the main toolbar button automatically loaded the "default" (the newest Mudlet Map file format file from the currently active profile's map sub-directory). Under some previous situations it looked as though a map might be loaded twice as mudlet::slot_mapper() was called both directly and via signal/slot action. These were resolved by turning that slot into a wrapper that now calls the body of code formerly within to a new method mudlet::createMapper( bool isToLoadDefaultMapFile = true ) with a the default value as an argument. This allows other usages of the body of code to be called directly with a suitable argument, which for the TConsole::loadMap() & TConsole::importMap() and the dlgProfilePreferences::downloadMap() cases is false as they are all do not want the "default" map! Also: * spotted a word "area" missing from an advisory text in TRoom::auditRooms(...). Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: fix minor bug, correct a spelling, undo a few capitalisations Under certain, unanticipated (error with no error message) conditions TLuaInterpreter::loadMap(...) would push both a nil and then a false value onto the stack for return {wrong} but only indicate one value {correct}. The textual matters were found during peer review. off-by: Stephen Lyons <slysven@virginmedia.com>
2016-10-13 09:18:48 +01:00
// Failure in parse file...
QString alertMsg = tr("[ ERROR ] - Map download problem, failure in parsing destination file:\n%1.").arg(mLocalMapFileName);
postMessage(alertMsg);
Enhance: fix map downloading code, add manual XML map importing (#326) * Enhance: fix map downloading code, add manual XML map importing A recent move by I.R.E. to using SSL for their public MUD map URLs broke the ability for Mudlet to download those XML format files. This commit addresses this issue (as mentioned in, but not the original problem referred to in https://bugs.launchpad.net/mudlet/+bug/1427364) the revision to the code does now use "https://www.<MUD URL>/maps/map.xml" as a default name for the I.R.E. MUDS - however the method that initiates the download which was moved to TMap class from the dlgMapper one (see below) is now: (bool) TMap::downloadMap( const QString * remoteUrl = Q_NULLPTR, const QString * localFileName = Q_NULLPTR ) which if not supplied with any arguments behaves as before. However the remoteUrl argument may be given as a full QString including the scheme (the bit of the URL at the beginning before the ':') to override that and a second argument may be used to provide a different name to use for the local file name which if is a RELATIVE pathFileName will be resolved in relation to the profile directory. At present no use is made of this additional functionality but it may be useful for use with other MUDs if they should choose to provide XML map files with other remote locations and scripts using a different local filename. As a long-standing thing that needed doing I have finally provided a means to import a map XML file that - for instance - has already been download. It had been noted that there was no way to read those I.R.E. map files even if they had been obtained from a web browser able to correctly handle https: URLs - now both the TLuaInterpreter::loadMap() and the dlgProfilePreference "loadMap" button {NOT the IRE only "map download" one} will both handle files ending in ".xml" (not case sensitive so it'll work MacOS platforms as well!} For the loadMap case it will be necessary to change the filetype filter on the File Selection dialog to select "xml" files. During testing it became clear to me that it was possible to try and read one or more XML files via several mechanisms simultaneously with "unhelpful" consequences. As well as hitting the dlgProfilePreferences IRE "map download" multiple times, the TLuaInterpreter::loadMap() does NOT block until the map has been loaded and as the import time {running of XMLinport::readPackage(...)} is of significant duration for a large map (a debug, without optimisation, build on my 1.8GHz Quad-core took over two minutes to process the current Achaea map file) it is very possible to get conditions where the same profile will try to run XMLinport::readPackage(...) asynchronously - given that a profile only supports ONE map at a time it was necessary to fit a QMutex to prevent the part of the XMLinport class relating to XML Map files being called from different places in the map related code. This means that if a map download is started further downloads and any local map imports will fail until that first download has completed or aborted. Similarly a local import will prevent a download being started. As a side effect this cures: https://bugs.launchpad.net/mudlet/+bug/852861 - "Map download button starts another download thread if one is already going" The previous XML import code was not adding the rooms that it parsed to the relevant TArea::rooms member - although this would be picked-up and fixed by TMap::audit() later on, this would be accompanied by an error message about every single room. The code now builds up this information while parsing the rooms' details and inserts it so that this does not cause report-able problems during the TMap::audit() execution - the data gathered also allows missing areas to be spotted so that if a room claimed to belong to an area that was not included in the preceding areas' data an unnamed area is created for it. As a consequence of the long time to actually parse an XML map file I have enhanced the progress dialog that was originally used to track the map file download. It is now retained until the file is completely imported and shows more information about the process - importantly it shows during the XMLimport::readRoom(...) the room id being processed - and THAT method is the time/cpu hog so seeing something happening during the time that Mudlet otherwise appears to hang is useful feedback even if it adds a few seconds to the overall duration (may be more than a minute). This dialog is now also used during the other routes that involve reading an XML file and there is now a bit of consistence with the on-screen messages. Whilst inspecting XMLimport class I found there was some uncertain initialisation which I have tidied up. In summary: Added: * (bool) TConsole::importMap(const QString & location) * (void) TRoomDB::setAreaRooms(const int areaId, const QSet<int> & roomIds) * image file mudlet_map_download.png used as icon for download/import progress dialog * (bool) TMap::importMap(QFile & file) * (bool) TMap::readXmlMapFile(QFile & file) * (void) TMap::slot_downloadError(QNetworkReply::NetworkError error) * (void) TMap::reportStringToProgressDialog(const QString text) * (void) TMap::reportProgressToProgressDialog(const int current, const int maximum) Revised: * (int)TLuaInterpreter::loadMap( lua_State * ) * Moved XML map download code from dlgMapper class to the TMap one: + (void) dlgMapper::downloadMap() ==> (bool) TMap::downloadMap(const QString * remoteUrl, const QString * localFileName) + (void) dlgMapper::setDownloadProgress(qint64, qint64) ==> (void) TMap::slot_setDownloadProgress(qint64,qint64) + (void) dlgMapper::cancel() ==> (void) TMap::slot_downloadCancel() + (void) dlgMapper::replyFinished(QNetworkReply *) ==> (void) TMap::slot_replyFinished(QNetworkReply *) * Enhanced download progress indication to also include parsing which can take even more time than download! * Provide means to import local XML map file * Prevent trying to import/download more than one map at a time Renamed: * (void) XMLimport::readAreaNames() ==> XMLimport::readArea() - for consistency with related functions Commented out unused: * (void) XMLimport::readUnknownRoomElement() Note the movement of the map file download code to the TMap class does require making the latter a class with the Q_OBJECT macro (which removes the need for Q_DECLARE_TR_FUNCTIONS as a side-effect!) - though as another side-effect the TMap header needed a boost name specifier added to one identifier as that identifier ("property") exists in both boost and QObject classes!!! YOU MAY NEED TO RUN QMAKE ON THE PROJECT IF THE BUILD SYSTEM DOES NOT PICK UP THE ADDITION OF "Q_OBJECT" TO TMAP CLASS. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: Include missing #include, remove unused return value The absence of this was causing build errors on the Travis C.I. platform! Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: move TMap.h to mudlet_MOC_HDRS to fix CMake build issue As we have made TMap inherit from QOject - to have signal/slot functionality that class needs to be run through Qt's MOC - and to do that with the CMake project/build system it needs to be included in the files included in the projects *_MOC_HDRS {and removed from the *_HDRS} variable. Also spotted a trivial error in that specifying a const return value from method is ineffective and pointless - so removed it from: TMap::retrieveMapFileStats(QString,QString *,int *,int *,int *,int *) Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: clean up TMap initialisation/clearing actions Now restores the customEnvColors set up on initialisation but that was cleared when the map replaced with another one that is loaded {which subsequently replaces that element anyway} or imported {which merely writes over it, replacing any matching keys}. Initialises elements that when inspected on the entry to the constructor proper previously were not being set to a consistent value {booleans/ints/floats}. NOTE: This will now clear the map user data member when the map is cleared if the date is required to be saved when one map is loaded OR IMPORTED over an existing one then the data will need to be saved outside of the map - as is already need for areas and rooms user data! Also comment out or remove unused members/methods: * (void) TMap::getConnectedNodesGreaterThanX(int, int) * (void) TMap::getConnectedNodesSmallerThanX(int, int) * (void) TMap::getConnectedNodesGreaterThanY(int, int) * (void) TMap::getConnectedNodesSmallerThanY(int, int) * (void) TMap::astBreitenAnpassung(int, int) * (void) TMap::astHoehenAnpassung(int, int) * (void) TMap::exportMapToDatabase() * (void) TMap::importMapFromDatabase() * (QVector3D) TMap::span * (int) TMap::mViewArea * (QMap<QString, int>) TMap::pixNameTable * (QMap<int, QPixmap>) TMap::pixTable * (bool) TMap::isToDisplayAuditErrorsToConsole Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * ImplimentationFixes: activate a valid optimisation & remove redundant code Adding a true as a non-default 3rd argument to TRoomDB::addRoom(...) call in XMLimport::readRoom(...) enables a significant optimisation (skips a computationally expensive step when ADDING a room to new map) which dramatically reduces the time to parse an XML map file. It also pointed to the fact that the TRoomDB::entranceMap was already correctly being handled and didn't need to be regenerated in XMLimport::readRoom(...) so the code that was added in a previous commit was redundant and could be removed. A code error in TMap::slot_setDownloadProgress(...) that caused an issue that a reviewer found on test has been fixed - the total download filesize that was being sent by the Qt system signal that is connected to this slot was a -1 value (as IS DOCUMENTED) when the Qt system does NOT know the size of a QNetworkReply in advance of reaching the end of the download was incorrectly handled in a previous commit in this change set. Also found during testing that there is no need for an error message for the QNetworkReply::OperationCanceledError case in TMap::slot_replayFinished(...) as it is already handled in the TMap::slot_downloadCancel() slot. Changed the text put up onto the progress widget during the XML room parsing to be a room count - which is likely more useful and to only do it for every hundredth room - which reduces any delay "wasted" in writing to the display - combined, the effects seem satisfactory IMHO. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: provide error messages for TLuaInterpreter::loadMap(...) Errors for the XML map file importing process as initiated from the Lua command should be returned to that command rather than plastered onto the main profile console - this commit attempts to perform that effect. In testing found that there was no error handling for failure to find or open the nominated file so messages for that have been added as well. Due to the previous program logic the action of creating a mapper widget using the main toolbar button automatically loaded the "default" (the newest Mudlet Map file format file from the currently active profile's map sub-directory). Under some previous situations it looked as though a map might be loaded twice as mudlet::slot_mapper() was called both directly and via signal/slot action. These were resolved by turning that slot into a wrapper that now calls the body of code formerly within to a new method mudlet::createMapper( bool isToLoadDefaultMapFile = true ) with a the default value as an argument. This allows other usages of the body of code to be called directly with a suitable argument, which for the TConsole::loadMap() & TConsole::importMap() and the dlgProfilePreferences::downloadMap() cases is false as they are all do not want the "default" map! Also: * spotted a word "area" missing from an advisory text in TRoom::auditRooms(...). Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: fix minor bug, correct a spelling, undo a few capitalisations Under certain, unanticipated (error with no error message) conditions TLuaInterpreter::loadMap(...) would push both a nil and then a false value onto the stack for return {wrong} but only indicate one value {correct}. The textual matters were found during peer review. off-by: Stephen Lyons <slysven@virginmedia.com>
2016-10-13 09:18:48 +01:00
}
file.close();
} else {
QString alertMsg = tr("[ ERROR ] - Map download problem, unable to read destination file:\n%1.").arg(mLocalMapFileName);
postMessage(alertMsg);
Enhance: fix map downloading code, add manual XML map importing (#326) * Enhance: fix map downloading code, add manual XML map importing A recent move by I.R.E. to using SSL for their public MUD map URLs broke the ability for Mudlet to download those XML format files. This commit addresses this issue (as mentioned in, but not the original problem referred to in https://bugs.launchpad.net/mudlet/+bug/1427364) the revision to the code does now use "https://www.<MUD URL>/maps/map.xml" as a default name for the I.R.E. MUDS - however the method that initiates the download which was moved to TMap class from the dlgMapper one (see below) is now: (bool) TMap::downloadMap( const QString * remoteUrl = Q_NULLPTR, const QString * localFileName = Q_NULLPTR ) which if not supplied with any arguments behaves as before. However the remoteUrl argument may be given as a full QString including the scheme (the bit of the URL at the beginning before the ':') to override that and a second argument may be used to provide a different name to use for the local file name which if is a RELATIVE pathFileName will be resolved in relation to the profile directory. At present no use is made of this additional functionality but it may be useful for use with other MUDs if they should choose to provide XML map files with other remote locations and scripts using a different local filename. As a long-standing thing that needed doing I have finally provided a means to import a map XML file that - for instance - has already been download. It had been noted that there was no way to read those I.R.E. map files even if they had been obtained from a web browser able to correctly handle https: URLs - now both the TLuaInterpreter::loadMap() and the dlgProfilePreference "loadMap" button {NOT the IRE only "map download" one} will both handle files ending in ".xml" (not case sensitive so it'll work MacOS platforms as well!} For the loadMap case it will be necessary to change the filetype filter on the File Selection dialog to select "xml" files. During testing it became clear to me that it was possible to try and read one or more XML files via several mechanisms simultaneously with "unhelpful" consequences. As well as hitting the dlgProfilePreferences IRE "map download" multiple times, the TLuaInterpreter::loadMap() does NOT block until the map has been loaded and as the import time {running of XMLinport::readPackage(...)} is of significant duration for a large map (a debug, without optimisation, build on my 1.8GHz Quad-core took over two minutes to process the current Achaea map file) it is very possible to get conditions where the same profile will try to run XMLinport::readPackage(...) asynchronously - given that a profile only supports ONE map at a time it was necessary to fit a QMutex to prevent the part of the XMLinport class relating to XML Map files being called from different places in the map related code. This means that if a map download is started further downloads and any local map imports will fail until that first download has completed or aborted. Similarly a local import will prevent a download being started. As a side effect this cures: https://bugs.launchpad.net/mudlet/+bug/852861 - "Map download button starts another download thread if one is already going" The previous XML import code was not adding the rooms that it parsed to the relevant TArea::rooms member - although this would be picked-up and fixed by TMap::audit() later on, this would be accompanied by an error message about every single room. The code now builds up this information while parsing the rooms' details and inserts it so that this does not cause report-able problems during the TMap::audit() execution - the data gathered also allows missing areas to be spotted so that if a room claimed to belong to an area that was not included in the preceding areas' data an unnamed area is created for it. As a consequence of the long time to actually parse an XML map file I have enhanced the progress dialog that was originally used to track the map file download. It is now retained until the file is completely imported and shows more information about the process - importantly it shows during the XMLimport::readRoom(...) the room id being processed - and THAT method is the time/cpu hog so seeing something happening during the time that Mudlet otherwise appears to hang is useful feedback even if it adds a few seconds to the overall duration (may be more than a minute). This dialog is now also used during the other routes that involve reading an XML file and there is now a bit of consistence with the on-screen messages. Whilst inspecting XMLimport class I found there was some uncertain initialisation which I have tidied up. In summary: Added: * (bool) TConsole::importMap(const QString & location) * (void) TRoomDB::setAreaRooms(const int areaId, const QSet<int> & roomIds) * image file mudlet_map_download.png used as icon for download/import progress dialog * (bool) TMap::importMap(QFile & file) * (bool) TMap::readXmlMapFile(QFile & file) * (void) TMap::slot_downloadError(QNetworkReply::NetworkError error) * (void) TMap::reportStringToProgressDialog(const QString text) * (void) TMap::reportProgressToProgressDialog(const int current, const int maximum) Revised: * (int)TLuaInterpreter::loadMap( lua_State * ) * Moved XML map download code from dlgMapper class to the TMap one: + (void) dlgMapper::downloadMap() ==> (bool) TMap::downloadMap(const QString * remoteUrl, const QString * localFileName) + (void) dlgMapper::setDownloadProgress(qint64, qint64) ==> (void) TMap::slot_setDownloadProgress(qint64,qint64) + (void) dlgMapper::cancel() ==> (void) TMap::slot_downloadCancel() + (void) dlgMapper::replyFinished(QNetworkReply *) ==> (void) TMap::slot_replyFinished(QNetworkReply *) * Enhanced download progress indication to also include parsing which can take even more time than download! * Provide means to import local XML map file * Prevent trying to import/download more than one map at a time Renamed: * (void) XMLimport::readAreaNames() ==> XMLimport::readArea() - for consistency with related functions Commented out unused: * (void) XMLimport::readUnknownRoomElement() Note the movement of the map file download code to the TMap class does require making the latter a class with the Q_OBJECT macro (which removes the need for Q_DECLARE_TR_FUNCTIONS as a side-effect!) - though as another side-effect the TMap header needed a boost name specifier added to one identifier as that identifier ("property") exists in both boost and QObject classes!!! YOU MAY NEED TO RUN QMAKE ON THE PROJECT IF THE BUILD SYSTEM DOES NOT PICK UP THE ADDITION OF "Q_OBJECT" TO TMAP CLASS. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: Include missing #include, remove unused return value The absence of this was causing build errors on the Travis C.I. platform! Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: move TMap.h to mudlet_MOC_HDRS to fix CMake build issue As we have made TMap inherit from QOject - to have signal/slot functionality that class needs to be run through Qt's MOC - and to do that with the CMake project/build system it needs to be included in the files included in the projects *_MOC_HDRS {and removed from the *_HDRS} variable. Also spotted a trivial error in that specifying a const return value from method is ineffective and pointless - so removed it from: TMap::retrieveMapFileStats(QString,QString *,int *,int *,int *,int *) Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: clean up TMap initialisation/clearing actions Now restores the customEnvColors set up on initialisation but that was cleared when the map replaced with another one that is loaded {which subsequently replaces that element anyway} or imported {which merely writes over it, replacing any matching keys}. Initialises elements that when inspected on the entry to the constructor proper previously were not being set to a consistent value {booleans/ints/floats}. NOTE: This will now clear the map user data member when the map is cleared if the date is required to be saved when one map is loaded OR IMPORTED over an existing one then the data will need to be saved outside of the map - as is already need for areas and rooms user data! Also comment out or remove unused members/methods: * (void) TMap::getConnectedNodesGreaterThanX(int, int) * (void) TMap::getConnectedNodesSmallerThanX(int, int) * (void) TMap::getConnectedNodesGreaterThanY(int, int) * (void) TMap::getConnectedNodesSmallerThanY(int, int) * (void) TMap::astBreitenAnpassung(int, int) * (void) TMap::astHoehenAnpassung(int, int) * (void) TMap::exportMapToDatabase() * (void) TMap::importMapFromDatabase() * (QVector3D) TMap::span * (int) TMap::mViewArea * (QMap<QString, int>) TMap::pixNameTable * (QMap<int, QPixmap>) TMap::pixTable * (bool) TMap::isToDisplayAuditErrorsToConsole Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * ImplimentationFixes: activate a valid optimisation & remove redundant code Adding a true as a non-default 3rd argument to TRoomDB::addRoom(...) call in XMLimport::readRoom(...) enables a significant optimisation (skips a computationally expensive step when ADDING a room to new map) which dramatically reduces the time to parse an XML map file. It also pointed to the fact that the TRoomDB::entranceMap was already correctly being handled and didn't need to be regenerated in XMLimport::readRoom(...) so the code that was added in a previous commit was redundant and could be removed. A code error in TMap::slot_setDownloadProgress(...) that caused an issue that a reviewer found on test has been fixed - the total download filesize that was being sent by the Qt system signal that is connected to this slot was a -1 value (as IS DOCUMENTED) when the Qt system does NOT know the size of a QNetworkReply in advance of reaching the end of the download was incorrectly handled in a previous commit in this change set. Also found during testing that there is no need for an error message for the QNetworkReply::OperationCanceledError case in TMap::slot_replayFinished(...) as it is already handled in the TMap::slot_downloadCancel() slot. Changed the text put up onto the progress widget during the XML room parsing to be a room count - which is likely more useful and to only do it for every hundredth room - which reduces any delay "wasted" in writing to the display - combined, the effects seem satisfactory IMHO. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: provide error messages for TLuaInterpreter::loadMap(...) Errors for the XML map file importing process as initiated from the Lua command should be returned to that command rather than plastered onto the main profile console - this commit attempts to perform that effect. In testing found that there was no error handling for failure to find or open the nominated file so messages for that have been added as well. Due to the previous program logic the action of creating a mapper widget using the main toolbar button automatically loaded the "default" (the newest Mudlet Map file format file from the currently active profile's map sub-directory). Under some previous situations it looked as though a map might be loaded twice as mudlet::slot_mapper() was called both directly and via signal/slot action. These were resolved by turning that slot into a wrapper that now calls the body of code formerly within to a new method mudlet::createMapper( bool isToLoadDefaultMapFile = true ) with a the default value as an argument. This allows other usages of the body of code to be called directly with a suitable argument, which for the TConsole::loadMap() & TConsole::importMap() and the dlgProfilePreferences::downloadMap() cases is false as they are all do not want the "default" map! Also: * spotted a word "area" missing from an advisory text in TRoom::auditRooms(...). Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: fix minor bug, correct a spelling, undo a few capitalisations Under certain, unanticipated (error with no error message) conditions TLuaInterpreter::loadMap(...) would push both a nil and then a false value onto the stack for return {wrong} but only indicate one value {correct}. The textual matters were found during peer review. off-by: Stephen Lyons <slysven@virginmedia.com>
2016-10-13 09:18:48 +01:00
}
}
}
}
reply->deleteLater();
mpNetworkReply = Q_NULLPTR;
// We don't delete the progress dialog until here as we now use it to inform
// about post-download operations
mpProgressDialog->deleteLater();
mpProgressDialog = Q_NULLPTR; // Must reset this so it can be reused
mLocalMapFileName.clear();
mExpectedFileSize = 0;
// We have finished with the XMLimporter so must release the lock on it
mXmlImportMutex.unlock();
}
void TMap::reportStringToProgressDialog(const QString text)
Enhance: fix map downloading code, add manual XML map importing (#326) * Enhance: fix map downloading code, add manual XML map importing A recent move by I.R.E. to using SSL for their public MUD map URLs broke the ability for Mudlet to download those XML format files. This commit addresses this issue (as mentioned in, but not the original problem referred to in https://bugs.launchpad.net/mudlet/+bug/1427364) the revision to the code does now use "https://www.<MUD URL>/maps/map.xml" as a default name for the I.R.E. MUDS - however the method that initiates the download which was moved to TMap class from the dlgMapper one (see below) is now: (bool) TMap::downloadMap( const QString * remoteUrl = Q_NULLPTR, const QString * localFileName = Q_NULLPTR ) which if not supplied with any arguments behaves as before. However the remoteUrl argument may be given as a full QString including the scheme (the bit of the URL at the beginning before the ':') to override that and a second argument may be used to provide a different name to use for the local file name which if is a RELATIVE pathFileName will be resolved in relation to the profile directory. At present no use is made of this additional functionality but it may be useful for use with other MUDs if they should choose to provide XML map files with other remote locations and scripts using a different local filename. As a long-standing thing that needed doing I have finally provided a means to import a map XML file that - for instance - has already been download. It had been noted that there was no way to read those I.R.E. map files even if they had been obtained from a web browser able to correctly handle https: URLs - now both the TLuaInterpreter::loadMap() and the dlgProfilePreference "loadMap" button {NOT the IRE only "map download" one} will both handle files ending in ".xml" (not case sensitive so it'll work MacOS platforms as well!} For the loadMap case it will be necessary to change the filetype filter on the File Selection dialog to select "xml" files. During testing it became clear to me that it was possible to try and read one or more XML files via several mechanisms simultaneously with "unhelpful" consequences. As well as hitting the dlgProfilePreferences IRE "map download" multiple times, the TLuaInterpreter::loadMap() does NOT block until the map has been loaded and as the import time {running of XMLinport::readPackage(...)} is of significant duration for a large map (a debug, without optimisation, build on my 1.8GHz Quad-core took over two minutes to process the current Achaea map file) it is very possible to get conditions where the same profile will try to run XMLinport::readPackage(...) asynchronously - given that a profile only supports ONE map at a time it was necessary to fit a QMutex to prevent the part of the XMLinport class relating to XML Map files being called from different places in the map related code. This means that if a map download is started further downloads and any local map imports will fail until that first download has completed or aborted. Similarly a local import will prevent a download being started. As a side effect this cures: https://bugs.launchpad.net/mudlet/+bug/852861 - "Map download button starts another download thread if one is already going" The previous XML import code was not adding the rooms that it parsed to the relevant TArea::rooms member - although this would be picked-up and fixed by TMap::audit() later on, this would be accompanied by an error message about every single room. The code now builds up this information while parsing the rooms' details and inserts it so that this does not cause report-able problems during the TMap::audit() execution - the data gathered also allows missing areas to be spotted so that if a room claimed to belong to an area that was not included in the preceding areas' data an unnamed area is created for it. As a consequence of the long time to actually parse an XML map file I have enhanced the progress dialog that was originally used to track the map file download. It is now retained until the file is completely imported and shows more information about the process - importantly it shows during the XMLimport::readRoom(...) the room id being processed - and THAT method is the time/cpu hog so seeing something happening during the time that Mudlet otherwise appears to hang is useful feedback even if it adds a few seconds to the overall duration (may be more than a minute). This dialog is now also used during the other routes that involve reading an XML file and there is now a bit of consistence with the on-screen messages. Whilst inspecting XMLimport class I found there was some uncertain initialisation which I have tidied up. In summary: Added: * (bool) TConsole::importMap(const QString & location) * (void) TRoomDB::setAreaRooms(const int areaId, const QSet<int> & roomIds) * image file mudlet_map_download.png used as icon for download/import progress dialog * (bool) TMap::importMap(QFile & file) * (bool) TMap::readXmlMapFile(QFile & file) * (void) TMap::slot_downloadError(QNetworkReply::NetworkError error) * (void) TMap::reportStringToProgressDialog(const QString text) * (void) TMap::reportProgressToProgressDialog(const int current, const int maximum) Revised: * (int)TLuaInterpreter::loadMap( lua_State * ) * Moved XML map download code from dlgMapper class to the TMap one: + (void) dlgMapper::downloadMap() ==> (bool) TMap::downloadMap(const QString * remoteUrl, const QString * localFileName) + (void) dlgMapper::setDownloadProgress(qint64, qint64) ==> (void) TMap::slot_setDownloadProgress(qint64,qint64) + (void) dlgMapper::cancel() ==> (void) TMap::slot_downloadCancel() + (void) dlgMapper::replyFinished(QNetworkReply *) ==> (void) TMap::slot_replyFinished(QNetworkReply *) * Enhanced download progress indication to also include parsing which can take even more time than download! * Provide means to import local XML map file * Prevent trying to import/download more than one map at a time Renamed: * (void) XMLimport::readAreaNames() ==> XMLimport::readArea() - for consistency with related functions Commented out unused: * (void) XMLimport::readUnknownRoomElement() Note the movement of the map file download code to the TMap class does require making the latter a class with the Q_OBJECT macro (which removes the need for Q_DECLARE_TR_FUNCTIONS as a side-effect!) - though as another side-effect the TMap header needed a boost name specifier added to one identifier as that identifier ("property") exists in both boost and QObject classes!!! YOU MAY NEED TO RUN QMAKE ON THE PROJECT IF THE BUILD SYSTEM DOES NOT PICK UP THE ADDITION OF "Q_OBJECT" TO TMAP CLASS. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: Include missing #include, remove unused return value The absence of this was causing build errors on the Travis C.I. platform! Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: move TMap.h to mudlet_MOC_HDRS to fix CMake build issue As we have made TMap inherit from QOject - to have signal/slot functionality that class needs to be run through Qt's MOC - and to do that with the CMake project/build system it needs to be included in the files included in the projects *_MOC_HDRS {and removed from the *_HDRS} variable. Also spotted a trivial error in that specifying a const return value from method is ineffective and pointless - so removed it from: TMap::retrieveMapFileStats(QString,QString *,int *,int *,int *,int *) Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: clean up TMap initialisation/clearing actions Now restores the customEnvColors set up on initialisation but that was cleared when the map replaced with another one that is loaded {which subsequently replaces that element anyway} or imported {which merely writes over it, replacing any matching keys}. Initialises elements that when inspected on the entry to the constructor proper previously were not being set to a consistent value {booleans/ints/floats}. NOTE: This will now clear the map user data member when the map is cleared if the date is required to be saved when one map is loaded OR IMPORTED over an existing one then the data will need to be saved outside of the map - as is already need for areas and rooms user data! Also comment out or remove unused members/methods: * (void) TMap::getConnectedNodesGreaterThanX(int, int) * (void) TMap::getConnectedNodesSmallerThanX(int, int) * (void) TMap::getConnectedNodesGreaterThanY(int, int) * (void) TMap::getConnectedNodesSmallerThanY(int, int) * (void) TMap::astBreitenAnpassung(int, int) * (void) TMap::astHoehenAnpassung(int, int) * (void) TMap::exportMapToDatabase() * (void) TMap::importMapFromDatabase() * (QVector3D) TMap::span * (int) TMap::mViewArea * (QMap<QString, int>) TMap::pixNameTable * (QMap<int, QPixmap>) TMap::pixTable * (bool) TMap::isToDisplayAuditErrorsToConsole Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * ImplimentationFixes: activate a valid optimisation & remove redundant code Adding a true as a non-default 3rd argument to TRoomDB::addRoom(...) call in XMLimport::readRoom(...) enables a significant optimisation (skips a computationally expensive step when ADDING a room to new map) which dramatically reduces the time to parse an XML map file. It also pointed to the fact that the TRoomDB::entranceMap was already correctly being handled and didn't need to be regenerated in XMLimport::readRoom(...) so the code that was added in a previous commit was redundant and could be removed. A code error in TMap::slot_setDownloadProgress(...) that caused an issue that a reviewer found on test has been fixed - the total download filesize that was being sent by the Qt system signal that is connected to this slot was a -1 value (as IS DOCUMENTED) when the Qt system does NOT know the size of a QNetworkReply in advance of reaching the end of the download was incorrectly handled in a previous commit in this change set. Also found during testing that there is no need for an error message for the QNetworkReply::OperationCanceledError case in TMap::slot_replayFinished(...) as it is already handled in the TMap::slot_downloadCancel() slot. Changed the text put up onto the progress widget during the XML room parsing to be a room count - which is likely more useful and to only do it for every hundredth room - which reduces any delay "wasted" in writing to the display - combined, the effects seem satisfactory IMHO. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: provide error messages for TLuaInterpreter::loadMap(...) Errors for the XML map file importing process as initiated from the Lua command should be returned to that command rather than plastered onto the main profile console - this commit attempts to perform that effect. In testing found that there was no error handling for failure to find or open the nominated file so messages for that have been added as well. Due to the previous program logic the action of creating a mapper widget using the main toolbar button automatically loaded the "default" (the newest Mudlet Map file format file from the currently active profile's map sub-directory). Under some previous situations it looked as though a map might be loaded twice as mudlet::slot_mapper() was called both directly and via signal/slot action. These were resolved by turning that slot into a wrapper that now calls the body of code formerly within to a new method mudlet::createMapper( bool isToLoadDefaultMapFile = true ) with a the default value as an argument. This allows other usages of the body of code to be called directly with a suitable argument, which for the TConsole::loadMap() & TConsole::importMap() and the dlgProfilePreferences::downloadMap() cases is false as they are all do not want the "default" map! Also: * spotted a word "area" missing from an advisory text in TRoom::auditRooms(...). Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: fix minor bug, correct a spelling, undo a few capitalisations Under certain, unanticipated (error with no error message) conditions TLuaInterpreter::loadMap(...) would push both a nil and then a false value onto the stack for return {wrong} but only indicate one value {correct}. The textual matters were found during peer review. off-by: Stephen Lyons <slysven@virginmedia.com>
2016-10-13 09:18:48 +01:00
{
if (mpProgressDialog) {
mpProgressDialog->setLabelText(text);
Enhance: fix map downloading code, add manual XML map importing (#326) * Enhance: fix map downloading code, add manual XML map importing A recent move by I.R.E. to using SSL for their public MUD map URLs broke the ability for Mudlet to download those XML format files. This commit addresses this issue (as mentioned in, but not the original problem referred to in https://bugs.launchpad.net/mudlet/+bug/1427364) the revision to the code does now use "https://www.<MUD URL>/maps/map.xml" as a default name for the I.R.E. MUDS - however the method that initiates the download which was moved to TMap class from the dlgMapper one (see below) is now: (bool) TMap::downloadMap( const QString * remoteUrl = Q_NULLPTR, const QString * localFileName = Q_NULLPTR ) which if not supplied with any arguments behaves as before. However the remoteUrl argument may be given as a full QString including the scheme (the bit of the URL at the beginning before the ':') to override that and a second argument may be used to provide a different name to use for the local file name which if is a RELATIVE pathFileName will be resolved in relation to the profile directory. At present no use is made of this additional functionality but it may be useful for use with other MUDs if they should choose to provide XML map files with other remote locations and scripts using a different local filename. As a long-standing thing that needed doing I have finally provided a means to import a map XML file that - for instance - has already been download. It had been noted that there was no way to read those I.R.E. map files even if they had been obtained from a web browser able to correctly handle https: URLs - now both the TLuaInterpreter::loadMap() and the dlgProfilePreference "loadMap" button {NOT the IRE only "map download" one} will both handle files ending in ".xml" (not case sensitive so it'll work MacOS platforms as well!} For the loadMap case it will be necessary to change the filetype filter on the File Selection dialog to select "xml" files. During testing it became clear to me that it was possible to try and read one or more XML files via several mechanisms simultaneously with "unhelpful" consequences. As well as hitting the dlgProfilePreferences IRE "map download" multiple times, the TLuaInterpreter::loadMap() does NOT block until the map has been loaded and as the import time {running of XMLinport::readPackage(...)} is of significant duration for a large map (a debug, without optimisation, build on my 1.8GHz Quad-core took over two minutes to process the current Achaea map file) it is very possible to get conditions where the same profile will try to run XMLinport::readPackage(...) asynchronously - given that a profile only supports ONE map at a time it was necessary to fit a QMutex to prevent the part of the XMLinport class relating to XML Map files being called from different places in the map related code. This means that if a map download is started further downloads and any local map imports will fail until that first download has completed or aborted. Similarly a local import will prevent a download being started. As a side effect this cures: https://bugs.launchpad.net/mudlet/+bug/852861 - "Map download button starts another download thread if one is already going" The previous XML import code was not adding the rooms that it parsed to the relevant TArea::rooms member - although this would be picked-up and fixed by TMap::audit() later on, this would be accompanied by an error message about every single room. The code now builds up this information while parsing the rooms' details and inserts it so that this does not cause report-able problems during the TMap::audit() execution - the data gathered also allows missing areas to be spotted so that if a room claimed to belong to an area that was not included in the preceding areas' data an unnamed area is created for it. As a consequence of the long time to actually parse an XML map file I have enhanced the progress dialog that was originally used to track the map file download. It is now retained until the file is completely imported and shows more information about the process - importantly it shows during the XMLimport::readRoom(...) the room id being processed - and THAT method is the time/cpu hog so seeing something happening during the time that Mudlet otherwise appears to hang is useful feedback even if it adds a few seconds to the overall duration (may be more than a minute). This dialog is now also used during the other routes that involve reading an XML file and there is now a bit of consistence with the on-screen messages. Whilst inspecting XMLimport class I found there was some uncertain initialisation which I have tidied up. In summary: Added: * (bool) TConsole::importMap(const QString & location) * (void) TRoomDB::setAreaRooms(const int areaId, const QSet<int> & roomIds) * image file mudlet_map_download.png used as icon for download/import progress dialog * (bool) TMap::importMap(QFile & file) * (bool) TMap::readXmlMapFile(QFile & file) * (void) TMap::slot_downloadError(QNetworkReply::NetworkError error) * (void) TMap::reportStringToProgressDialog(const QString text) * (void) TMap::reportProgressToProgressDialog(const int current, const int maximum) Revised: * (int)TLuaInterpreter::loadMap( lua_State * ) * Moved XML map download code from dlgMapper class to the TMap one: + (void) dlgMapper::downloadMap() ==> (bool) TMap::downloadMap(const QString * remoteUrl, const QString * localFileName) + (void) dlgMapper::setDownloadProgress(qint64, qint64) ==> (void) TMap::slot_setDownloadProgress(qint64,qint64) + (void) dlgMapper::cancel() ==> (void) TMap::slot_downloadCancel() + (void) dlgMapper::replyFinished(QNetworkReply *) ==> (void) TMap::slot_replyFinished(QNetworkReply *) * Enhanced download progress indication to also include parsing which can take even more time than download! * Provide means to import local XML map file * Prevent trying to import/download more than one map at a time Renamed: * (void) XMLimport::readAreaNames() ==> XMLimport::readArea() - for consistency with related functions Commented out unused: * (void) XMLimport::readUnknownRoomElement() Note the movement of the map file download code to the TMap class does require making the latter a class with the Q_OBJECT macro (which removes the need for Q_DECLARE_TR_FUNCTIONS as a side-effect!) - though as another side-effect the TMap header needed a boost name specifier added to one identifier as that identifier ("property") exists in both boost and QObject classes!!! YOU MAY NEED TO RUN QMAKE ON THE PROJECT IF THE BUILD SYSTEM DOES NOT PICK UP THE ADDITION OF "Q_OBJECT" TO TMAP CLASS. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: Include missing #include, remove unused return value The absence of this was causing build errors on the Travis C.I. platform! Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: move TMap.h to mudlet_MOC_HDRS to fix CMake build issue As we have made TMap inherit from QOject - to have signal/slot functionality that class needs to be run through Qt's MOC - and to do that with the CMake project/build system it needs to be included in the files included in the projects *_MOC_HDRS {and removed from the *_HDRS} variable. Also spotted a trivial error in that specifying a const return value from method is ineffective and pointless - so removed it from: TMap::retrieveMapFileStats(QString,QString *,int *,int *,int *,int *) Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: clean up TMap initialisation/clearing actions Now restores the customEnvColors set up on initialisation but that was cleared when the map replaced with another one that is loaded {which subsequently replaces that element anyway} or imported {which merely writes over it, replacing any matching keys}. Initialises elements that when inspected on the entry to the constructor proper previously were not being set to a consistent value {booleans/ints/floats}. NOTE: This will now clear the map user data member when the map is cleared if the date is required to be saved when one map is loaded OR IMPORTED over an existing one then the data will need to be saved outside of the map - as is already need for areas and rooms user data! Also comment out or remove unused members/methods: * (void) TMap::getConnectedNodesGreaterThanX(int, int) * (void) TMap::getConnectedNodesSmallerThanX(int, int) * (void) TMap::getConnectedNodesGreaterThanY(int, int) * (void) TMap::getConnectedNodesSmallerThanY(int, int) * (void) TMap::astBreitenAnpassung(int, int) * (void) TMap::astHoehenAnpassung(int, int) * (void) TMap::exportMapToDatabase() * (void) TMap::importMapFromDatabase() * (QVector3D) TMap::span * (int) TMap::mViewArea * (QMap<QString, int>) TMap::pixNameTable * (QMap<int, QPixmap>) TMap::pixTable * (bool) TMap::isToDisplayAuditErrorsToConsole Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * ImplimentationFixes: activate a valid optimisation & remove redundant code Adding a true as a non-default 3rd argument to TRoomDB::addRoom(...) call in XMLimport::readRoom(...) enables a significant optimisation (skips a computationally expensive step when ADDING a room to new map) which dramatically reduces the time to parse an XML map file. It also pointed to the fact that the TRoomDB::entranceMap was already correctly being handled and didn't need to be regenerated in XMLimport::readRoom(...) so the code that was added in a previous commit was redundant and could be removed. A code error in TMap::slot_setDownloadProgress(...) that caused an issue that a reviewer found on test has been fixed - the total download filesize that was being sent by the Qt system signal that is connected to this slot was a -1 value (as IS DOCUMENTED) when the Qt system does NOT know the size of a QNetworkReply in advance of reaching the end of the download was incorrectly handled in a previous commit in this change set. Also found during testing that there is no need for an error message for the QNetworkReply::OperationCanceledError case in TMap::slot_replayFinished(...) as it is already handled in the TMap::slot_downloadCancel() slot. Changed the text put up onto the progress widget during the XML room parsing to be a room count - which is likely more useful and to only do it for every hundredth room - which reduces any delay "wasted" in writing to the display - combined, the effects seem satisfactory IMHO. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: provide error messages for TLuaInterpreter::loadMap(...) Errors for the XML map file importing process as initiated from the Lua command should be returned to that command rather than plastered onto the main profile console - this commit attempts to perform that effect. In testing found that there was no error handling for failure to find or open the nominated file so messages for that have been added as well. Due to the previous program logic the action of creating a mapper widget using the main toolbar button automatically loaded the "default" (the newest Mudlet Map file format file from the currently active profile's map sub-directory). Under some previous situations it looked as though a map might be loaded twice as mudlet::slot_mapper() was called both directly and via signal/slot action. These were resolved by turning that slot into a wrapper that now calls the body of code formerly within to a new method mudlet::createMapper( bool isToLoadDefaultMapFile = true ) with a the default value as an argument. This allows other usages of the body of code to be called directly with a suitable argument, which for the TConsole::loadMap() & TConsole::importMap() and the dlgProfilePreferences::downloadMap() cases is false as they are all do not want the "default" map! Also: * spotted a word "area" missing from an advisory text in TRoom::auditRooms(...). Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: fix minor bug, correct a spelling, undo a few capitalisations Under certain, unanticipated (error with no error message) conditions TLuaInterpreter::loadMap(...) would push both a nil and then a false value onto the stack for return {wrong} but only indicate one value {correct}. The textual matters were found during peer review. off-by: Stephen Lyons <slysven@virginmedia.com>
2016-10-13 09:18:48 +01:00
// Needed to make the changed text show, it does increase the overall
// time a little but as the main usage is when parsing XML room data
// and that can take MORE THAN A MINUTE the activity is essential to
// inform the user that something IS happening...
qApp->processEvents();
}
}
void TMap::reportProgressToProgressDialog(const int current, const int maximum)
Enhance: fix map downloading code, add manual XML map importing (#326) * Enhance: fix map downloading code, add manual XML map importing A recent move by I.R.E. to using SSL for their public MUD map URLs broke the ability for Mudlet to download those XML format files. This commit addresses this issue (as mentioned in, but not the original problem referred to in https://bugs.launchpad.net/mudlet/+bug/1427364) the revision to the code does now use "https://www.<MUD URL>/maps/map.xml" as a default name for the I.R.E. MUDS - however the method that initiates the download which was moved to TMap class from the dlgMapper one (see below) is now: (bool) TMap::downloadMap( const QString * remoteUrl = Q_NULLPTR, const QString * localFileName = Q_NULLPTR ) which if not supplied with any arguments behaves as before. However the remoteUrl argument may be given as a full QString including the scheme (the bit of the URL at the beginning before the ':') to override that and a second argument may be used to provide a different name to use for the local file name which if is a RELATIVE pathFileName will be resolved in relation to the profile directory. At present no use is made of this additional functionality but it may be useful for use with other MUDs if they should choose to provide XML map files with other remote locations and scripts using a different local filename. As a long-standing thing that needed doing I have finally provided a means to import a map XML file that - for instance - has already been download. It had been noted that there was no way to read those I.R.E. map files even if they had been obtained from a web browser able to correctly handle https: URLs - now both the TLuaInterpreter::loadMap() and the dlgProfilePreference "loadMap" button {NOT the IRE only "map download" one} will both handle files ending in ".xml" (not case sensitive so it'll work MacOS platforms as well!} For the loadMap case it will be necessary to change the filetype filter on the File Selection dialog to select "xml" files. During testing it became clear to me that it was possible to try and read one or more XML files via several mechanisms simultaneously with "unhelpful" consequences. As well as hitting the dlgProfilePreferences IRE "map download" multiple times, the TLuaInterpreter::loadMap() does NOT block until the map has been loaded and as the import time {running of XMLinport::readPackage(...)} is of significant duration for a large map (a debug, without optimisation, build on my 1.8GHz Quad-core took over two minutes to process the current Achaea map file) it is very possible to get conditions where the same profile will try to run XMLinport::readPackage(...) asynchronously - given that a profile only supports ONE map at a time it was necessary to fit a QMutex to prevent the part of the XMLinport class relating to XML Map files being called from different places in the map related code. This means that if a map download is started further downloads and any local map imports will fail until that first download has completed or aborted. Similarly a local import will prevent a download being started. As a side effect this cures: https://bugs.launchpad.net/mudlet/+bug/852861 - "Map download button starts another download thread if one is already going" The previous XML import code was not adding the rooms that it parsed to the relevant TArea::rooms member - although this would be picked-up and fixed by TMap::audit() later on, this would be accompanied by an error message about every single room. The code now builds up this information while parsing the rooms' details and inserts it so that this does not cause report-able problems during the TMap::audit() execution - the data gathered also allows missing areas to be spotted so that if a room claimed to belong to an area that was not included in the preceding areas' data an unnamed area is created for it. As a consequence of the long time to actually parse an XML map file I have enhanced the progress dialog that was originally used to track the map file download. It is now retained until the file is completely imported and shows more information about the process - importantly it shows during the XMLimport::readRoom(...) the room id being processed - and THAT method is the time/cpu hog so seeing something happening during the time that Mudlet otherwise appears to hang is useful feedback even if it adds a few seconds to the overall duration (may be more than a minute). This dialog is now also used during the other routes that involve reading an XML file and there is now a bit of consistence with the on-screen messages. Whilst inspecting XMLimport class I found there was some uncertain initialisation which I have tidied up. In summary: Added: * (bool) TConsole::importMap(const QString & location) * (void) TRoomDB::setAreaRooms(const int areaId, const QSet<int> & roomIds) * image file mudlet_map_download.png used as icon for download/import progress dialog * (bool) TMap::importMap(QFile & file) * (bool) TMap::readXmlMapFile(QFile & file) * (void) TMap::slot_downloadError(QNetworkReply::NetworkError error) * (void) TMap::reportStringToProgressDialog(const QString text) * (void) TMap::reportProgressToProgressDialog(const int current, const int maximum) Revised: * (int)TLuaInterpreter::loadMap( lua_State * ) * Moved XML map download code from dlgMapper class to the TMap one: + (void) dlgMapper::downloadMap() ==> (bool) TMap::downloadMap(const QString * remoteUrl, const QString * localFileName) + (void) dlgMapper::setDownloadProgress(qint64, qint64) ==> (void) TMap::slot_setDownloadProgress(qint64,qint64) + (void) dlgMapper::cancel() ==> (void) TMap::slot_downloadCancel() + (void) dlgMapper::replyFinished(QNetworkReply *) ==> (void) TMap::slot_replyFinished(QNetworkReply *) * Enhanced download progress indication to also include parsing which can take even more time than download! * Provide means to import local XML map file * Prevent trying to import/download more than one map at a time Renamed: * (void) XMLimport::readAreaNames() ==> XMLimport::readArea() - for consistency with related functions Commented out unused: * (void) XMLimport::readUnknownRoomElement() Note the movement of the map file download code to the TMap class does require making the latter a class with the Q_OBJECT macro (which removes the need for Q_DECLARE_TR_FUNCTIONS as a side-effect!) - though as another side-effect the TMap header needed a boost name specifier added to one identifier as that identifier ("property") exists in both boost and QObject classes!!! YOU MAY NEED TO RUN QMAKE ON THE PROJECT IF THE BUILD SYSTEM DOES NOT PICK UP THE ADDITION OF "Q_OBJECT" TO TMAP CLASS. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: Include missing #include, remove unused return value The absence of this was causing build errors on the Travis C.I. platform! Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: move TMap.h to mudlet_MOC_HDRS to fix CMake build issue As we have made TMap inherit from QOject - to have signal/slot functionality that class needs to be run through Qt's MOC - and to do that with the CMake project/build system it needs to be included in the files included in the projects *_MOC_HDRS {and removed from the *_HDRS} variable. Also spotted a trivial error in that specifying a const return value from method is ineffective and pointless - so removed it from: TMap::retrieveMapFileStats(QString,QString *,int *,int *,int *,int *) Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: clean up TMap initialisation/clearing actions Now restores the customEnvColors set up on initialisation but that was cleared when the map replaced with another one that is loaded {which subsequently replaces that element anyway} or imported {which merely writes over it, replacing any matching keys}. Initialises elements that when inspected on the entry to the constructor proper previously were not being set to a consistent value {booleans/ints/floats}. NOTE: This will now clear the map user data member when the map is cleared if the date is required to be saved when one map is loaded OR IMPORTED over an existing one then the data will need to be saved outside of the map - as is already need for areas and rooms user data! Also comment out or remove unused members/methods: * (void) TMap::getConnectedNodesGreaterThanX(int, int) * (void) TMap::getConnectedNodesSmallerThanX(int, int) * (void) TMap::getConnectedNodesGreaterThanY(int, int) * (void) TMap::getConnectedNodesSmallerThanY(int, int) * (void) TMap::astBreitenAnpassung(int, int) * (void) TMap::astHoehenAnpassung(int, int) * (void) TMap::exportMapToDatabase() * (void) TMap::importMapFromDatabase() * (QVector3D) TMap::span * (int) TMap::mViewArea * (QMap<QString, int>) TMap::pixNameTable * (QMap<int, QPixmap>) TMap::pixTable * (bool) TMap::isToDisplayAuditErrorsToConsole Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * ImplimentationFixes: activate a valid optimisation & remove redundant code Adding a true as a non-default 3rd argument to TRoomDB::addRoom(...) call in XMLimport::readRoom(...) enables a significant optimisation (skips a computationally expensive step when ADDING a room to new map) which dramatically reduces the time to parse an XML map file. It also pointed to the fact that the TRoomDB::entranceMap was already correctly being handled and didn't need to be regenerated in XMLimport::readRoom(...) so the code that was added in a previous commit was redundant and could be removed. A code error in TMap::slot_setDownloadProgress(...) that caused an issue that a reviewer found on test has been fixed - the total download filesize that was being sent by the Qt system signal that is connected to this slot was a -1 value (as IS DOCUMENTED) when the Qt system does NOT know the size of a QNetworkReply in advance of reaching the end of the download was incorrectly handled in a previous commit in this change set. Also found during testing that there is no need for an error message for the QNetworkReply::OperationCanceledError case in TMap::slot_replayFinished(...) as it is already handled in the TMap::slot_downloadCancel() slot. Changed the text put up onto the progress widget during the XML room parsing to be a room count - which is likely more useful and to only do it for every hundredth room - which reduces any delay "wasted" in writing to the display - combined, the effects seem satisfactory IMHO. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: provide error messages for TLuaInterpreter::loadMap(...) Errors for the XML map file importing process as initiated from the Lua command should be returned to that command rather than plastered onto the main profile console - this commit attempts to perform that effect. In testing found that there was no error handling for failure to find or open the nominated file so messages for that have been added as well. Due to the previous program logic the action of creating a mapper widget using the main toolbar button automatically loaded the "default" (the newest Mudlet Map file format file from the currently active profile's map sub-directory). Under some previous situations it looked as though a map might be loaded twice as mudlet::slot_mapper() was called both directly and via signal/slot action. These were resolved by turning that slot into a wrapper that now calls the body of code formerly within to a new method mudlet::createMapper( bool isToLoadDefaultMapFile = true ) with a the default value as an argument. This allows other usages of the body of code to be called directly with a suitable argument, which for the TConsole::loadMap() & TConsole::importMap() and the dlgProfilePreferences::downloadMap() cases is false as they are all do not want the "default" map! Also: * spotted a word "area" missing from an advisory text in TRoom::auditRooms(...). Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: fix minor bug, correct a spelling, undo a few capitalisations Under certain, unanticipated (error with no error message) conditions TLuaInterpreter::loadMap(...) would push both a nil and then a false value onto the stack for return {wrong} but only indicate one value {correct}. The textual matters were found during peer review. off-by: Stephen Lyons <slysven@virginmedia.com>
2016-10-13 09:18:48 +01:00
{
if (mpProgressDialog) {
if (mpProgressDialog->maximum() != maximum) {
mpProgressDialog->setMaximum(maximum);
Enhance: fix map downloading code, add manual XML map importing (#326) * Enhance: fix map downloading code, add manual XML map importing A recent move by I.R.E. to using SSL for their public MUD map URLs broke the ability for Mudlet to download those XML format files. This commit addresses this issue (as mentioned in, but not the original problem referred to in https://bugs.launchpad.net/mudlet/+bug/1427364) the revision to the code does now use "https://www.<MUD URL>/maps/map.xml" as a default name for the I.R.E. MUDS - however the method that initiates the download which was moved to TMap class from the dlgMapper one (see below) is now: (bool) TMap::downloadMap( const QString * remoteUrl = Q_NULLPTR, const QString * localFileName = Q_NULLPTR ) which if not supplied with any arguments behaves as before. However the remoteUrl argument may be given as a full QString including the scheme (the bit of the URL at the beginning before the ':') to override that and a second argument may be used to provide a different name to use for the local file name which if is a RELATIVE pathFileName will be resolved in relation to the profile directory. At present no use is made of this additional functionality but it may be useful for use with other MUDs if they should choose to provide XML map files with other remote locations and scripts using a different local filename. As a long-standing thing that needed doing I have finally provided a means to import a map XML file that - for instance - has already been download. It had been noted that there was no way to read those I.R.E. map files even if they had been obtained from a web browser able to correctly handle https: URLs - now both the TLuaInterpreter::loadMap() and the dlgProfilePreference "loadMap" button {NOT the IRE only "map download" one} will both handle files ending in ".xml" (not case sensitive so it'll work MacOS platforms as well!} For the loadMap case it will be necessary to change the filetype filter on the File Selection dialog to select "xml" files. During testing it became clear to me that it was possible to try and read one or more XML files via several mechanisms simultaneously with "unhelpful" consequences. As well as hitting the dlgProfilePreferences IRE "map download" multiple times, the TLuaInterpreter::loadMap() does NOT block until the map has been loaded and as the import time {running of XMLinport::readPackage(...)} is of significant duration for a large map (a debug, without optimisation, build on my 1.8GHz Quad-core took over two minutes to process the current Achaea map file) it is very possible to get conditions where the same profile will try to run XMLinport::readPackage(...) asynchronously - given that a profile only supports ONE map at a time it was necessary to fit a QMutex to prevent the part of the XMLinport class relating to XML Map files being called from different places in the map related code. This means that if a map download is started further downloads and any local map imports will fail until that first download has completed or aborted. Similarly a local import will prevent a download being started. As a side effect this cures: https://bugs.launchpad.net/mudlet/+bug/852861 - "Map download button starts another download thread if one is already going" The previous XML import code was not adding the rooms that it parsed to the relevant TArea::rooms member - although this would be picked-up and fixed by TMap::audit() later on, this would be accompanied by an error message about every single room. The code now builds up this information while parsing the rooms' details and inserts it so that this does not cause report-able problems during the TMap::audit() execution - the data gathered also allows missing areas to be spotted so that if a room claimed to belong to an area that was not included in the preceding areas' data an unnamed area is created for it. As a consequence of the long time to actually parse an XML map file I have enhanced the progress dialog that was originally used to track the map file download. It is now retained until the file is completely imported and shows more information about the process - importantly it shows during the XMLimport::readRoom(...) the room id being processed - and THAT method is the time/cpu hog so seeing something happening during the time that Mudlet otherwise appears to hang is useful feedback even if it adds a few seconds to the overall duration (may be more than a minute). This dialog is now also used during the other routes that involve reading an XML file and there is now a bit of consistence with the on-screen messages. Whilst inspecting XMLimport class I found there was some uncertain initialisation which I have tidied up. In summary: Added: * (bool) TConsole::importMap(const QString & location) * (void) TRoomDB::setAreaRooms(const int areaId, const QSet<int> & roomIds) * image file mudlet_map_download.png used as icon for download/import progress dialog * (bool) TMap::importMap(QFile & file) * (bool) TMap::readXmlMapFile(QFile & file) * (void) TMap::slot_downloadError(QNetworkReply::NetworkError error) * (void) TMap::reportStringToProgressDialog(const QString text) * (void) TMap::reportProgressToProgressDialog(const int current, const int maximum) Revised: * (int)TLuaInterpreter::loadMap( lua_State * ) * Moved XML map download code from dlgMapper class to the TMap one: + (void) dlgMapper::downloadMap() ==> (bool) TMap::downloadMap(const QString * remoteUrl, const QString * localFileName) + (void) dlgMapper::setDownloadProgress(qint64, qint64) ==> (void) TMap::slot_setDownloadProgress(qint64,qint64) + (void) dlgMapper::cancel() ==> (void) TMap::slot_downloadCancel() + (void) dlgMapper::replyFinished(QNetworkReply *) ==> (void) TMap::slot_replyFinished(QNetworkReply *) * Enhanced download progress indication to also include parsing which can take even more time than download! * Provide means to import local XML map file * Prevent trying to import/download more than one map at a time Renamed: * (void) XMLimport::readAreaNames() ==> XMLimport::readArea() - for consistency with related functions Commented out unused: * (void) XMLimport::readUnknownRoomElement() Note the movement of the map file download code to the TMap class does require making the latter a class with the Q_OBJECT macro (which removes the need for Q_DECLARE_TR_FUNCTIONS as a side-effect!) - though as another side-effect the TMap header needed a boost name specifier added to one identifier as that identifier ("property") exists in both boost and QObject classes!!! YOU MAY NEED TO RUN QMAKE ON THE PROJECT IF THE BUILD SYSTEM DOES NOT PICK UP THE ADDITION OF "Q_OBJECT" TO TMAP CLASS. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: Include missing #include, remove unused return value The absence of this was causing build errors on the Travis C.I. platform! Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: move TMap.h to mudlet_MOC_HDRS to fix CMake build issue As we have made TMap inherit from QOject - to have signal/slot functionality that class needs to be run through Qt's MOC - and to do that with the CMake project/build system it needs to be included in the files included in the projects *_MOC_HDRS {and removed from the *_HDRS} variable. Also spotted a trivial error in that specifying a const return value from method is ineffective and pointless - so removed it from: TMap::retrieveMapFileStats(QString,QString *,int *,int *,int *,int *) Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: clean up TMap initialisation/clearing actions Now restores the customEnvColors set up on initialisation but that was cleared when the map replaced with another one that is loaded {which subsequently replaces that element anyway} or imported {which merely writes over it, replacing any matching keys}. Initialises elements that when inspected on the entry to the constructor proper previously were not being set to a consistent value {booleans/ints/floats}. NOTE: This will now clear the map user data member when the map is cleared if the date is required to be saved when one map is loaded OR IMPORTED over an existing one then the data will need to be saved outside of the map - as is already need for areas and rooms user data! Also comment out or remove unused members/methods: * (void) TMap::getConnectedNodesGreaterThanX(int, int) * (void) TMap::getConnectedNodesSmallerThanX(int, int) * (void) TMap::getConnectedNodesGreaterThanY(int, int) * (void) TMap::getConnectedNodesSmallerThanY(int, int) * (void) TMap::astBreitenAnpassung(int, int) * (void) TMap::astHoehenAnpassung(int, int) * (void) TMap::exportMapToDatabase() * (void) TMap::importMapFromDatabase() * (QVector3D) TMap::span * (int) TMap::mViewArea * (QMap<QString, int>) TMap::pixNameTable * (QMap<int, QPixmap>) TMap::pixTable * (bool) TMap::isToDisplayAuditErrorsToConsole Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * ImplimentationFixes: activate a valid optimisation & remove redundant code Adding a true as a non-default 3rd argument to TRoomDB::addRoom(...) call in XMLimport::readRoom(...) enables a significant optimisation (skips a computationally expensive step when ADDING a room to new map) which dramatically reduces the time to parse an XML map file. It also pointed to the fact that the TRoomDB::entranceMap was already correctly being handled and didn't need to be regenerated in XMLimport::readRoom(...) so the code that was added in a previous commit was redundant and could be removed. A code error in TMap::slot_setDownloadProgress(...) that caused an issue that a reviewer found on test has been fixed - the total download filesize that was being sent by the Qt system signal that is connected to this slot was a -1 value (as IS DOCUMENTED) when the Qt system does NOT know the size of a QNetworkReply in advance of reaching the end of the download was incorrectly handled in a previous commit in this change set. Also found during testing that there is no need for an error message for the QNetworkReply::OperationCanceledError case in TMap::slot_replayFinished(...) as it is already handled in the TMap::slot_downloadCancel() slot. Changed the text put up onto the progress widget during the XML room parsing to be a room count - which is likely more useful and to only do it for every hundredth room - which reduces any delay "wasted" in writing to the display - combined, the effects seem satisfactory IMHO. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: provide error messages for TLuaInterpreter::loadMap(...) Errors for the XML map file importing process as initiated from the Lua command should be returned to that command rather than plastered onto the main profile console - this commit attempts to perform that effect. In testing found that there was no error handling for failure to find or open the nominated file so messages for that have been added as well. Due to the previous program logic the action of creating a mapper widget using the main toolbar button automatically loaded the "default" (the newest Mudlet Map file format file from the currently active profile's map sub-directory). Under some previous situations it looked as though a map might be loaded twice as mudlet::slot_mapper() was called both directly and via signal/slot action. These were resolved by turning that slot into a wrapper that now calls the body of code formerly within to a new method mudlet::createMapper( bool isToLoadDefaultMapFile = true ) with a the default value as an argument. This allows other usages of the body of code to be called directly with a suitable argument, which for the TConsole::loadMap() & TConsole::importMap() and the dlgProfilePreferences::downloadMap() cases is false as they are all do not want the "default" map! Also: * spotted a word "area" missing from an advisory text in TRoom::auditRooms(...). Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: fix minor bug, correct a spelling, undo a few capitalisations Under certain, unanticipated (error with no error message) conditions TLuaInterpreter::loadMap(...) would push both a nil and then a false value onto the stack for return {wrong} but only indicate one value {correct}. The textual matters were found during peer review. off-by: Stephen Lyons <slysven@virginmedia.com>
2016-10-13 09:18:48 +01:00
}
mpProgressDialog->setValue(current);
Enhance: fix map downloading code, add manual XML map importing (#326) * Enhance: fix map downloading code, add manual XML map importing A recent move by I.R.E. to using SSL for their public MUD map URLs broke the ability for Mudlet to download those XML format files. This commit addresses this issue (as mentioned in, but not the original problem referred to in https://bugs.launchpad.net/mudlet/+bug/1427364) the revision to the code does now use "https://www.<MUD URL>/maps/map.xml" as a default name for the I.R.E. MUDS - however the method that initiates the download which was moved to TMap class from the dlgMapper one (see below) is now: (bool) TMap::downloadMap( const QString * remoteUrl = Q_NULLPTR, const QString * localFileName = Q_NULLPTR ) which if not supplied with any arguments behaves as before. However the remoteUrl argument may be given as a full QString including the scheme (the bit of the URL at the beginning before the ':') to override that and a second argument may be used to provide a different name to use for the local file name which if is a RELATIVE pathFileName will be resolved in relation to the profile directory. At present no use is made of this additional functionality but it may be useful for use with other MUDs if they should choose to provide XML map files with other remote locations and scripts using a different local filename. As a long-standing thing that needed doing I have finally provided a means to import a map XML file that - for instance - has already been download. It had been noted that there was no way to read those I.R.E. map files even if they had been obtained from a web browser able to correctly handle https: URLs - now both the TLuaInterpreter::loadMap() and the dlgProfilePreference "loadMap" button {NOT the IRE only "map download" one} will both handle files ending in ".xml" (not case sensitive so it'll work MacOS platforms as well!} For the loadMap case it will be necessary to change the filetype filter on the File Selection dialog to select "xml" files. During testing it became clear to me that it was possible to try and read one or more XML files via several mechanisms simultaneously with "unhelpful" consequences. As well as hitting the dlgProfilePreferences IRE "map download" multiple times, the TLuaInterpreter::loadMap() does NOT block until the map has been loaded and as the import time {running of XMLinport::readPackage(...)} is of significant duration for a large map (a debug, without optimisation, build on my 1.8GHz Quad-core took over two minutes to process the current Achaea map file) it is very possible to get conditions where the same profile will try to run XMLinport::readPackage(...) asynchronously - given that a profile only supports ONE map at a time it was necessary to fit a QMutex to prevent the part of the XMLinport class relating to XML Map files being called from different places in the map related code. This means that if a map download is started further downloads and any local map imports will fail until that first download has completed or aborted. Similarly a local import will prevent a download being started. As a side effect this cures: https://bugs.launchpad.net/mudlet/+bug/852861 - "Map download button starts another download thread if one is already going" The previous XML import code was not adding the rooms that it parsed to the relevant TArea::rooms member - although this would be picked-up and fixed by TMap::audit() later on, this would be accompanied by an error message about every single room. The code now builds up this information while parsing the rooms' details and inserts it so that this does not cause report-able problems during the TMap::audit() execution - the data gathered also allows missing areas to be spotted so that if a room claimed to belong to an area that was not included in the preceding areas' data an unnamed area is created for it. As a consequence of the long time to actually parse an XML map file I have enhanced the progress dialog that was originally used to track the map file download. It is now retained until the file is completely imported and shows more information about the process - importantly it shows during the XMLimport::readRoom(...) the room id being processed - and THAT method is the time/cpu hog so seeing something happening during the time that Mudlet otherwise appears to hang is useful feedback even if it adds a few seconds to the overall duration (may be more than a minute). This dialog is now also used during the other routes that involve reading an XML file and there is now a bit of consistence with the on-screen messages. Whilst inspecting XMLimport class I found there was some uncertain initialisation which I have tidied up. In summary: Added: * (bool) TConsole::importMap(const QString & location) * (void) TRoomDB::setAreaRooms(const int areaId, const QSet<int> & roomIds) * image file mudlet_map_download.png used as icon for download/import progress dialog * (bool) TMap::importMap(QFile & file) * (bool) TMap::readXmlMapFile(QFile & file) * (void) TMap::slot_downloadError(QNetworkReply::NetworkError error) * (void) TMap::reportStringToProgressDialog(const QString text) * (void) TMap::reportProgressToProgressDialog(const int current, const int maximum) Revised: * (int)TLuaInterpreter::loadMap( lua_State * ) * Moved XML map download code from dlgMapper class to the TMap one: + (void) dlgMapper::downloadMap() ==> (bool) TMap::downloadMap(const QString * remoteUrl, const QString * localFileName) + (void) dlgMapper::setDownloadProgress(qint64, qint64) ==> (void) TMap::slot_setDownloadProgress(qint64,qint64) + (void) dlgMapper::cancel() ==> (void) TMap::slot_downloadCancel() + (void) dlgMapper::replyFinished(QNetworkReply *) ==> (void) TMap::slot_replyFinished(QNetworkReply *) * Enhanced download progress indication to also include parsing which can take even more time than download! * Provide means to import local XML map file * Prevent trying to import/download more than one map at a time Renamed: * (void) XMLimport::readAreaNames() ==> XMLimport::readArea() - for consistency with related functions Commented out unused: * (void) XMLimport::readUnknownRoomElement() Note the movement of the map file download code to the TMap class does require making the latter a class with the Q_OBJECT macro (which removes the need for Q_DECLARE_TR_FUNCTIONS as a side-effect!) - though as another side-effect the TMap header needed a boost name specifier added to one identifier as that identifier ("property") exists in both boost and QObject classes!!! YOU MAY NEED TO RUN QMAKE ON THE PROJECT IF THE BUILD SYSTEM DOES NOT PICK UP THE ADDITION OF "Q_OBJECT" TO TMAP CLASS. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: Include missing #include, remove unused return value The absence of this was causing build errors on the Travis C.I. platform! Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * BugFix: move TMap.h to mudlet_MOC_HDRS to fix CMake build issue As we have made TMap inherit from QOject - to have signal/slot functionality that class needs to be run through Qt's MOC - and to do that with the CMake project/build system it needs to be included in the files included in the projects *_MOC_HDRS {and removed from the *_HDRS} variable. Also spotted a trivial error in that specifying a const return value from method is ineffective and pointless - so removed it from: TMap::retrieveMapFileStats(QString,QString *,int *,int *,int *,int *) Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: clean up TMap initialisation/clearing actions Now restores the customEnvColors set up on initialisation but that was cleared when the map replaced with another one that is loaded {which subsequently replaces that element anyway} or imported {which merely writes over it, replacing any matching keys}. Initialises elements that when inspected on the entry to the constructor proper previously were not being set to a consistent value {booleans/ints/floats}. NOTE: This will now clear the map user data member when the map is cleared if the date is required to be saved when one map is loaded OR IMPORTED over an existing one then the data will need to be saved outside of the map - as is already need for areas and rooms user data! Also comment out or remove unused members/methods: * (void) TMap::getConnectedNodesGreaterThanX(int, int) * (void) TMap::getConnectedNodesSmallerThanX(int, int) * (void) TMap::getConnectedNodesGreaterThanY(int, int) * (void) TMap::getConnectedNodesSmallerThanY(int, int) * (void) TMap::astBreitenAnpassung(int, int) * (void) TMap::astHoehenAnpassung(int, int) * (void) TMap::exportMapToDatabase() * (void) TMap::importMapFromDatabase() * (QVector3D) TMap::span * (int) TMap::mViewArea * (QMap<QString, int>) TMap::pixNameTable * (QMap<int, QPixmap>) TMap::pixTable * (bool) TMap::isToDisplayAuditErrorsToConsole Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * ImplimentationFixes: activate a valid optimisation & remove redundant code Adding a true as a non-default 3rd argument to TRoomDB::addRoom(...) call in XMLimport::readRoom(...) enables a significant optimisation (skips a computationally expensive step when ADDING a room to new map) which dramatically reduces the time to parse an XML map file. It also pointed to the fact that the TRoomDB::entranceMap was already correctly being handled and didn't need to be regenerated in XMLimport::readRoom(...) so the code that was added in a previous commit was redundant and could be removed. A code error in TMap::slot_setDownloadProgress(...) that caused an issue that a reviewer found on test has been fixed - the total download filesize that was being sent by the Qt system signal that is connected to this slot was a -1 value (as IS DOCUMENTED) when the Qt system does NOT know the size of a QNetworkReply in advance of reaching the end of the download was incorrectly handled in a previous commit in this change set. Also found during testing that there is no need for an error message for the QNetworkReply::OperationCanceledError case in TMap::slot_replayFinished(...) as it is already handled in the TMap::slot_downloadCancel() slot. Changed the text put up onto the progress widget during the XML room parsing to be a room count - which is likely more useful and to only do it for every hundredth room - which reduces any delay "wasted" in writing to the display - combined, the effects seem satisfactory IMHO. Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: provide error messages for TLuaInterpreter::loadMap(...) Errors for the XML map file importing process as initiated from the Lua command should be returned to that command rather than plastered onto the main profile console - this commit attempts to perform that effect. In testing found that there was no error handling for failure to find or open the nominated file so messages for that have been added as well. Due to the previous program logic the action of creating a mapper widget using the main toolbar button automatically loaded the "default" (the newest Mudlet Map file format file from the currently active profile's map sub-directory). Under some previous situations it looked as though a map might be loaded twice as mudlet::slot_mapper() was called both directly and via signal/slot action. These were resolved by turning that slot into a wrapper that now calls the body of code formerly within to a new method mudlet::createMapper( bool isToLoadDefaultMapFile = true ) with a the default value as an argument. This allows other usages of the body of code to be called directly with a suitable argument, which for the TConsole::loadMap() & TConsole::importMap() and the dlgProfilePreferences::downloadMap() cases is false as they are all do not want the "default" map! Also: * spotted a word "area" missing from an advisory text in TRoom::auditRooms(...). Signed-off-by: Stephen Lyons <slysven@virginmedia.com> * Tweak: fix minor bug, correct a spelling, undo a few capitalisations Under certain, unanticipated (error with no error message) conditions TLuaInterpreter::loadMap(...) would push both a nil and then a false value onto the stack for return {wrong} but only indicate one value {correct}. The textual matters were found during peer review. off-by: Stephen Lyons <slysven@virginmedia.com>
2016-10-13 09:18:48 +01:00
}
}
Enhance: add ability to set any glyph as a room symbol (#1543) This is a squashed down commit containing several commits with messages - this is the edited combination of all the messages: As well as being able to use any grapheme it is possible to use a short word as well as anything printable from any of the Unicode Multiple Planes; although the former will become smaller to fit within both the square and round room shapes on the 2D mapper. Adds controls to the profile preference to set the (preferred) font to use to set the room symbols from and a checkbox to only use that font. Additionally a sub-dialog can be brought up which lists the details of all the different symbols on the map - showing the Unicode codepoint(s) for each and showing how they would be rendered if only the selected font is used and if any font is permitted, along with a count of the usages and the rooms that use each one... A status icon is also displayed showing whether the symbol can be rendered entirely with the selected font (green tick), only by using glyphs from other fonts (yellow ! warning) or not with the current fonts on the system (red/white cross). This allows a user to make a sensible selection of a font to use or whether they will have a problem (and a replacement by the replacement character '�') for any symbols. Updates Lua setRoomChar and getRoomChar to handle the wider range of things that can be used. getRoomChar NOW allows for an existing character to be cleared with an empty string or a space as the char attribute. The map format version has been incremented to allow the data needed to be saved directly into the binary file format but failback code is in place that means that this feature can be carried in map and room user data instead for map format versions down to 17 - the current default is 18 and there is limited support to fail gracefully down to the 16 that Mudlet 2.1 uses (all the room letter markings that are not supported will become '?', and the font data will be lost, but the correct room character data will still be in the room user data.) Following review: * I replaced some colour specifications (white and transparent) with Qt constants. * Use the same inline function flushSymbolPixmapCache() to clear the map symbol pixmap cache in all places where it might be useful. * Simplify a couple of places where an if(...) {...} else {...} can be replaced with the (...) ? (...) : (...) operator. * Limit the number of room numbers displayed for each symbol in the new widget - to avoid complications where there are huge numbers of rooms using a symbol. * Replace a use of QTableWidget::clearContents() with QTableWidgets::setRowCount(0) as I was getting some odd, deep in the Qt internal library issues {Fatal Seg. Faults!} with the former, which I suspect, but could not prove, might have been a re-entrancy issue caused by the method containing it being called indirectly by an asynchronous SIGNAL/SLOT originating in the value change from the map symbol font selection QFontComboBox... Revised to NOT do scaling when drawing room symbols from cache: the previous QPainter::drawPixmap(...) performed a scaling operation to make the symbol pixmap fit the specified rectangle. This is the cause behind the poor rendering of text characters as the scaling undoes the benefits of anti-aliasing and takes time to do. This should be faster now because the pixmaps are generated at the size/resolution they are needed (though they do have to be thrown away and regenerated if the zoom or other sizing factors change) - they do however look better to me! Also: * merged (int) TRoom::xzoom and TRoom::yzoom into TRoom::xyzoom. * added the symbol scaling "fudge-factor" to the "Special Options" tab of the "Profile preferences" dialog - it may be helpful to artificially over-size (> 1.00) or under-size (< 1.00) the symbols in some situations. * uses the word symbol rather than just glyph/grapheme in some texts. Also modified 2D mapper "Symbol" tooltip to observe that more than one letter/symbol can be used (although they will be drawn smaller so that they still fit). Add tool-tips to profile preferences dialog for font controls (except for "fudge factor" control (with range x0.50 to x2.00 for scaling of symbol to test rectangle used to fit it into the room shape)... I have consistently mispelled chosen as choosen but I have fixed that now...! Also added tooltips to map glyph usage table/widget. WorkAround: try to force a specific US mirror for zziplib on AppVeyor CI AppVeyor is based in Vancouver, Canada so the nearest SF Mirror is in the US so this commit forces the use of that mirror for that library for the CI build process as an attempt to get around the repeated, intermittent failures to get that library from SourceForge (it is now the only item that needs to be downloaded from there for such builds)... Also adds another CI file that was not mentioned before in the qmake project file and thus did not show up in the Qt IDE. Following extensive discussions it has been made clear that introducing replacements for the lua [gs]etRoomChar(...) is not going to happen. Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
2018-03-28 14:06:12 +01:00
QHash<QString, QSet<int>> TMap::roomSymbolsHash()
{
QHash<QString, QSet<int>> results;
QHashIterator<int, TRoom*> itRoom(mpRoomDB->getRoomMap());
while (itRoom.hasNext()) {
itRoom.next();
if (itRoom.value() && !itRoom.value()->mSymbol.isEmpty()) {
if (results.contains(itRoom.value()->mSymbol)) {
results[itRoom.value()->mSymbol].insert(itRoom.key());
} else {
QSet<int> newEntry;
newEntry << itRoom.key();
results.insert(itRoom.value()->mSymbol, newEntry);
}
}
}
return results;
}