player-visible changes
- removed text that showed up if you used the wrong hotkeys. no other
dfhack screen does this, and it seems unneeded. can add back if others
think otherwise, though
internal changes
- changed signature of lua-exported isPlannableBuilding to take subtype
and custom type in addition to building type. this is only used by
quickfort, and it already sends all three params in preparation for
this change
- added lua-exported scheduleCycle(), which is like doCycle(), but only
takes effect on the next non-paused frame. this lets quickfort
run only one buildingplan cycle regardless of how many #build
blueprints were run
- declared a few dfhack library methods and params const so buildingplan
could call them from const methods
- converted buildingplan internal debug logging fn to have a printf api
- reshaped buildingplan-planner API and refactored implementation in
preparation for upcoming core algorithm changes for supporing all
building types (no externally-visible functionality changes)
- changed df::building_type params to type, subtype, custom tuple keys
- introduced capability to return multiple filters per building type
(though the current buildings all only have one filter per)
- split monolith hook functions in buildingplan.cpp into one per scope.
this significantly cleans up the code and preps the hooks to handle
iterating through multiple item filters.
- got rid of send_key function and replaced with better reporting of
whether keys have been handled
The typedefs in the header foward-declared new structs of the same names in the DFHack namespace, e.g. DFHack::xlsxio_read_struct. Apparently the constructors that used these typedefs are not inlined on Windows, so libdfhack was compiled with a constructor taking a "DFHack::xlsxio_read_sheet_struct", and xlsxreader was looking for a constructor taking just a "xlsxio_read_sheet_struct", which didn't exist.
I refactored Filesystem::listdir_recursive to support removing the path
prefix from the returned files list. There are no current calls that
make use of the prefix parameter, so I converted it into a boolean.
Current usages will use the new default parameter and will not see any
changed behavior.
RemoteServer and PluginManager side would need complete redesign to be
data race free and concurrent. But as that would be unlikely to be
required from DFHack I decided simpler solution that is fixing data
ownership to a thread and all ServerConnection share a single lock which
allows access to PluginManager and Core.
Alter World to use Persistence instead of storing data in historical figures.
Fake historical figures will be converted to the new format when a world is loaded.
Added plugin_save and plugin_load functions to the plugin API.
Made the weird int7/int28 code that was in the old persistence API slightly safer.
This moves code intended to infer biome type currently living in a
couple of plugins into the Maps module, so that this code can be shared
more easily by multiple plugins, as discussed in #1392.
The runtime debug print filtering support dynamic debug print selection.
Tis patch only implements basic core support for filtering. The commands
to change the runtime filtering settings will be added in a following
patch.
But even with only this one can change filtering settings by editing
memory using a debugger. It can even be automated by using gdb break
point commands.
- Use port from remote-server.json in dfhack-run
- Make DFHACK_RUN environment variable take priority over remote-server.json
- Log current port to stderr
The bools could use acquire&release memory order or even relaxed but I
didn't think code was worth auditing for such low level optimizations.
Sequantial consistent is fast enough but much harder to use incorrectly.
The timeLast is protected by CoreSuspender lock. plugin_update is only
called when CoreSuspender lock is held.
The last_menu is protected by trackmenu_flg loads and stores.
The old CoreSuspender requires processing from Core::Update to allow
commands execute. But that causes issues if Core::Shutdown wants
quarentee cleanup order with std:🧵:join. Fixing shutdown ordering
adds too many branches to already fairly complex code.
I decided to try to refactor CoreSuspender to use simpler locking
locking using a std::recusive_muted as primary synchronization
primitive.
To help control when Core::Update unlocks the primary mutex there is
std::contition_variable_any and std::atomic<size_t> queue lenght
counter.
The last state variable is std::atomic<std:🧵:id> that is used to
keep track of owner thread for Core::IsSuspended query.
This should be merged only just after a release to make sure that it
gets maximum testing in develop branch before next release.
Fixes#1066
There is a minor chance that console or init thread would access already
freed memory when core is shutting down and cleaning up state. To avoid
any danger of having random bugs caused by the potential data race I
decided to make sure the shutdown code waits for the thread to exit
first.
Windows change is completely untested. It is purely based on msdn
documentation.
I noticed that tthread is missing some c++11 features that make thread
handling code a bit easier. To be able to use those features I decided
to convert Core.cpp to use equivalent standard classes.
This patch has no functional changes.
command-prompt viewscreen may affect command execution if they are
looking for UI state. To make commands execute simillary to hotkeys or
console commands the viewscreen needs to removed from the top position.
Fixes#1194
The Screen::show takes ownership of the screen pointer. I decided to
switch the parameter to std::unique_ptr to make the pointer ownership
explicit. The unique_ptr then provides automatic screen destruction in
Screen::show unless pointer is inserted or is already in the linked list
that is managed by df.
The map_block->designation.{dig,smooth} are reset to zeros when a job
posting is created for the designation. The job is then used to override
the designation state in the map_block. To make the new designation set
propogate to jobs the job structure would require updating. The update
would be possible a complex operation. The simple alternative is to
remove the job and let df create a new job in the next tick.
Fixes#1229
This makes jsoncpp a submodule that can be build directly from git
sources. This changes depends/jsoncpp to depends/jsoncpp-sub to avoid
filename conflict if someone tries to use git bisect.
jsoncpp library name changes to jsoncpp_lib_static.
jsoncpp version is the latest tagged release.
gcc supports type checks for printf parameters which can catch some hard
to reproduce bugs. Possible bugs happen when the parameter value is
intepreted differently to the variable value.
Example warnings follow
../library/LuaWrapper.cpp:1011:86: warning: format ‘%llu’ expects argument
of type ‘long long unsigned int’, but argument 3 has type ‘uint64_t
{aka long unsigned int}’ [-Wformat=]
../plugins/follow.cpp:159:35: warning: format not a string literal and no
format arguments [-Wformat-security]
This makes it easier for tools to properly handle designating and undesignating
trees for chopping and plants for gathering, which changed significantly in
0.40.20.
Ref #531 (?), #656, #1014, #1018, #1030, #1076
Job remove eliminates a job's worker & holder references, if any, puts
the worker on cd, if appropriate, removes the job's postings, eliminates
the job from the global linked list, and then finally deletes it. This
code was tested by incorporating it into autochop and it does make the
plugin work. However, chop jobs don't have holder building references,
and anyway, with DF being 90% edge case by volume, this could use a heck
of a lot more testing.
I saw elsewhere code that prevented worker removal if the job was a
special job, and that made me feel funny so I made the job remove method
not work if the job is a special job.
In some situations (e.g. 32-bit Linux), "intptr_t" is defined as "int", which is
equivalent to "int32_t", leading to issues with duplicate definitions. In other
situations with GCC, "intptr_t" is "long", which isn't covered by any intNN_t
types. Also, definitions for "long" already had to be added on Windows, because
no fixed-width types in MSVC are equivalent to "long".
Switching to non-fixed-width types should hopefully cover all of these
situations. If this doesn't cover any integer types that we need, it will
be caught quickly, e.g. by references to integer_traits<T> in LuaWrapper.cpp.
- Don't set in_building by default when use_mode is 0 (consistent with most vanilla DF items)
- make use_mode optional and default to 0 (including in Lua API)
Resolves#885
This requires plugins to pass plugin_self to Screen::show(), but
avoids the need to implement special checks in plugin_onstatechange
for the SC_BEGIN_UNLOAD event.
Without removing postings correctly, it was possible to end up with
multiple workers assigned to a job that workflow had suspended
multiple times, which caused crashes if more than one worker was
assigned to the same job by DF.
This adds an additional command, fix-job-postings, that runs
automatically when loading a world and fixes:
- Multiple job postings that point to the same job
- Job postings that point to a job where posting_index == -1
(i.e. jobs that should have no posting assigned)
Fixes#741
* Several fatal errors that occurred during core initialization didn't
stop initialization or set 'errorstate' properly, which caused
update hooks and other code to crash later. This has been fixed and
should address crashes like the one mentioned in #470.
* Errors when loading dfhack.lua now cause Lua::Open() to fail, which
triggers a fatal error in Core::Init()
* Failure to initialize the console no longer results in a call to
fatal() (since it didn't actually stop initialization previously)
This makes it possible for some plugins to detect the game state more
reliably - for example, prospector would previously fail when
embarking if the viewscreen_choose_start_sitest instance had any
children.
* load/unload/reload are no longer restricted to plugins that exist
on startup
* Names passed to DFHACK_PLUGIN must match the plugin's filename
(remotefortressreader vs RemoteFortressReader, counters vs probe)
* "plug" output lists all plugins and state/command information
* Deleted plugins can be reloaded again if they are replaced
* load/unload/reload don't fail silently with broken plugins
* Built-in commands are recognized internally (e.g. "help help"
does not display "help is not a recognized command"), although help
for them is not yet implemented
* New command: "type" (bash-like) - shows where/how a command is
implemented
* "plug" can accept multiple plugin names
* "ls" displays more information about unloaded/unrecognized plugins
* "load all" changed to "load -all" (or "load --all", "load -a", ...)
git is run every time 'make' is run, but the generated include file
is only updated when necessary. Plugins will be loaded successfully
if their DFHack version matches core's (assuming OpenLibrary()
succeeds), but will produce a warning if their git commit doesn't
match core's.