dfhack icon indicating copy to clipboard operation
dfhack copied to clipboard

Request and use new function pointers

Open myk002 opened this issue 3 years ago • 21 comments

It would reduce bugs and code duplication significantly if we had access to some key DF functions, including:

  • make (building/squad/unit/item)
  • complete building (see https://gist.github.com/ab9rf/9fedca12642859d68db44fd3dd529990)
  • assign to (e.g. unit to occupation in location)
  • add sizeof()s to the global table
  • chop tree (with and without producing logs)

myk002 avatar Jan 29 '23 04:01 myk002

Generating names is one that I'd love to see. I'm willing to bet that name generation has a lot going on under the hood, so dfhack created things are always going to be named differently to vanilla

20k avatar Jan 29 '23 04:01 20k

Not all of these things are likely to be instance methods - e.g. "make" is probably a constructor or static function, which can't easily be made virtual.

lethosor avatar Jan 29 '23 06:01 lethosor

that said, pretty much anything that only makes sense to call while a map is loaded can be (and honestly probably should be) a member function of the (singleton) world class. there's a lot of stuff that operates on globals that are nonetheless members of the world type or one of its unique members, which we can tell because the address of the global is loaded into RCX for the call (and then often unused in the implemention)

ab9rf avatar Jan 29 '23 06:01 ab9rf

one that i would love is world_data::getBiome or whatever it's called in toady's code (it's at 0x140b69a60 in 50.05-steam). we have an implementation in dfhack but it's reverse-engineered, and if we could just call the one in game we wouldn't have a risk of it being out of sync.

i suppose i could write a recognizer to find it with each release.

ab9rf avatar Jan 29 '23 22:01 ab9rf

Not all of these things are likely to be instance methods - e.g. "make" is probably a constructor or static function, which can't easily be made virtual.

I can all but guarantee that they're static functions - if you take a look at the source code for Kobold Quest, Toady used static "create" and "create_for_load" functions to create the various objects, and the DF disassembly shows the exact same pattern being used all over the place.

quietust avatar Jan 30 '23 23:01 quietust

world->jobs.cancel_job appears to cause crashes when called with DestroyBuilding jobs. We either need a different function or more information about how to call the one we have. We also have to do an inordinate amount of cleanup before calling this function, further implying that it's not the one we need.

myk002 avatar Feb 13 '23 08:02 myk002

buildingst::deconstruct

myk002 avatar Feb 16 '23 07:02 myk002

arena reset (especially with regards to restoring the terrain, removing/reinstating trees, etc.)

myk002 avatar Apr 28 '23 15:04 myk002

arena reset

I'm not sure that has a relevant class to attach a vmethod to (and IMO, is probably a lower priority).

lethosor avatar May 08 '23 15:05 lethosor

  • sell prices, given a caravan_state
  • item description given type, subtype, material, gloss, etc.
  • item description given item
  • unit description given unit
  • art form description given art form

myk002 avatar Jul 05 '23 23:07 myk002

For reference, what we call caravan_state looks to be what Toady calls plot_merchantst.

  • There are at least 4 different functions for getting item values:
    • one is an item method with 3 parameters (plot_merchantst * + entityst * + bool ignore_foreign) which recursively grabs container contents and calls the one below.
    • one is an item method with 2 parameters (plot_merchantst * + entityst *) which includes civ preferences + quality + improvements + wear + trade agreements + stack size after calling the one below
    • one is an item method with zero parameters which just calls the one below with the item's properties
    • one is a global function that takes item_type + subtype + material + matgloss which just multiplies the base value by the material value
  • The item method for "is wood derived" might be nice, given that "is animal derived" is already virtual

quietust avatar Jul 06 '23 02:07 quietust

I'm not sure that has a relevant class to attach a vmethod to (and IMO, is probably a lower priority).

there's no reason why toady can't just add a function pointer to the global "cheatsheet", especially now that (since we're firmly in 64-bit land) there aren't a plethora of calling conventions to deal with anymore. also, the compiler will notice that the function has had its address taken and will ensure that a callable version of its exists even if all of its other uses are inlined elsewhere

this is actually probably a better solution than artificially virtualizing things, since it avoids the overhead of forcing regular calls to that function from being forced through a vtable. it would mean that we couldn't easily interpose those functions though

ab9rf avatar Jul 08 '23 00:07 ab9rf

For classes that don't have subclasses, vmethod calls tend to get optimized out anyway, so we can't always interpose them (e.g. job_handler::cancel_job()). Or maybe that's only for instances of classes whose types are known at compile-time (e.g. globals). As long as DF can guarantee a stable calling convention for exposed function pointers, I would be ok with going that route. I think this is basically what Putnam/Myk had in mind when talking about exposing a rudimentary "API" for common tasks too.

lethosor avatar Jul 08 '23 23:07 lethosor

the C++ standard guarantees that any function whose address is taken with the & operator will be callable via the pointer generated in that manner, so if toady explicitly stores a pointer to a function into a global variable, that function is guaranteed to be callable

even greater genericism can be obtained using std::function, which can wrap pretty much any callable object and store it in a stable manner

ab9rf avatar Jul 09 '23 22:07 ab9rf

TranslateName()

myk002 avatar Aug 11 '23 17:08 myk002

convert cancel_job to a function pointer so the hack in #3713 can be reverted

myk002 avatar Aug 31 '23 21:08 myk002

getZoneValue(unit) (unit may be NULL)

myk002 avatar Sep 30 '23 00:09 myk002

getZoneValue(unit) (unit may be NULL)

more specifically, building_civzonest::valuation(unitst *un) is what we're looking for here

ab9rf avatar Sep 30 '23 01:09 ab9rf

buildingst::blastbuilding would be nice -- see Discord discussion: https://discord.com/channels/793331351645323264/807444515194798090/1268955236849160267

myk002 avatar Aug 02 '24 17:08 myk002

Interestingly, we already wanted that function as of Feb 2023, just under our name for it (rather than Toady's name):

[> buildingst::deconstruct

](https://github.com/DFHack/dfhack/issues/2746#issuecomment-1432646518)

quietust avatar Aug 02 '24 18:08 quietust

Fn that gives "a day's travel", etc. make_announcement or markup_text_boxst fns. Fn for playing FMOD sounds. Fn for removing tile (recalc tile light, building support, items fall, etc.) Fn(s) that give name/prof as displayed by unit list.

Bumber64 avatar Aug 02 '24 22:08 Bumber64