{"payload":{"feedbackUrl":"https://github.com/orgs/community/discussions/53140","repo":{"id":228632510,"defaultBranch":"master","name":"individual","ownerLogin":"mrc-ide","currentUserCanPush":false,"isFork":false,"isEmpty":false,"createdAt":"2019-12-17T14:19:24.000Z","ownerAvatar":"https://avatars.githubusercontent.com/u/25453642?v=4","public":true,"private":false,"isOrgOwned":true},"refInfo":{"name":"","listCacheKey":"v0:1725637232.0","currentOid":""},"activityList":{"items":[{"before":null,"after":"d7f4b6b47585ebcab5fa480b6047fce7dd140cad","ref":"refs/heads/expose-version-next","pushedAt":"2024-09-06T15:40:32.000Z","pushType":"branch_creation","commitsCount":0,"pusher":{"login":"plietar","name":"Paul Liétar","path":"/plietar","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/1489775?s=80&v=4"},"commit":{"message":"next","shortMessageHtmlLink":"next"}},{"before":"5f037ee468c5e609de136167528d2bd4b9d643e5","after":"68a86da4b9102c1bd1a5b34d9d6ffbbc24013b25","ref":"refs/heads/expose-version","pushedAt":"2024-09-06T14:57:05.000Z","pushType":"force_push","commitsCount":0,"pusher":{"login":"plietar","name":"Paul Liétar","path":"/plietar","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/1489775?s=80&v=4"},"commit":{"message":"Expose the package version in the C++ headers.\n\nOn multiple occasions, I have made changes to individual that\ninadvertently broke the ABI of the native code. Unfortunately, after the\nnew version of individual was released and users installed it, the R\ntooling wasn't able to detect this situation and did not automatically\nforce malariasimulation to be re-installed or re-compiled. As a result,\nusers were using a malariasimulation shared library that was built\nagainst individual 0.X together with an individual shared library at\nversion 0.(X+1). This causes very subtle and hard to diagnose bugs,\nwhere one piece of code might read from the wrong place.\n\nFor example, mrc-ide/individual#187 changed a return type of\n`NumericVariable::get_values` from a prvalue to a const-reference,\navoiding unnecessary copies. For most intents and purposes, this is a\nAPI-compatible change, but the ABI of the method is different. After the\nupdate, if a user was still using a installation of malariasimulation\nthat expected the old signature, the code would be compiled expecting to\nreceive an `std::vector` by value (ie. three words representing the\npointer to the data, the length and the capacity) instead received a\npointer to such a vector.\n\nAnother example is mrc-ide/individual#201, which removed the `num_bits`\nfield and made it a compile-time constant. Code which used `num_bits`\nwas now reading from an unintialized piece of memory instead. While the\n`num_bits` field was private, header-file code from the individual\npackage that reads the field can make its way into the malariasimulation\nshared library and embed the assumptions about the layout of the class.\nGiven the heavy use of templates in the package, almost all of it is\nre-instantiated and included in the downstream shared library.\n\nIn all these cases, recompiling malariasimulation is sufficient to\nensure it uses the new ABI of the individual package. If the user uses\n`devtools`, then this simply requires them to call\n`devtools::clean_dll`. The issue is that identifying the problem is near\nimpossible for a user. Nothing in the behaviour of malariasimulation\npoints to an incompatibility, instead the package only misbehaves in\nvery suprising ways.\n\nThe goal of this change is to export the version of the individual\npackage in its C++ headers. The constant may then be included and\ncompiled into the malariasimulation shared object. At load-time,\nmalariasimulation can compare this version with the result of\n`packageVersion(\"individual\")` and show a warning or an error if they\ndon't match. The user will be directed to re-install malariasimulation.\n\nI could not figure out a way of exporting the version from `DESCRIPTION`\ninto header files. It's possibly something `Rcpp::compileAttributes()`\ncould do, but it doesn't. Instead the version number is duplicated and a\nCI check ensures that they are kept in sync.\n\nSome alternatives I considered instead:\n1. Don't make ABI breaking changes to individual: I think this is a\n non-starter. We do not want to restrict our abilities to improve and\n optimise the package. Moreover identifying what is or isn't a breaking\n change is quite challenging.\n2. Stop exposing a C++ API, and require users to call the R functions\n instead: allowing users to write high-performant processes or utility\n functions for the hot path of their models is quite an important\n aspect of individual.\n3. Break the ABI but announce it in release notes so users know to be on\n the look out and to re-compile their copy of malariasimulation: no one\n reads release notes, especially for a package they only use\n indirectly. Moreover it still requires identifying ABI breaking changes.\n4. Implement the suggested scheme, but use an ABI version instead of the\n package version. This will avoid false positives, where the package's\n version number is increased even though the ABI hasn't changed. I\n think the rate of releases and the cost of recompiling malariasimulation\n are low enough that it is better to err on the safe side and treat\n every release as if it could be ABI breaking.","shortMessageHtmlLink":"Expose the package version in the C++ headers."}},{"before":"f3cba48a713f636f4634264f18c3be19afbf3dca","after":"5f037ee468c5e609de136167528d2bd4b9d643e5","ref":"refs/heads/expose-version","pushedAt":"2024-09-06T14:54:27.000Z","pushType":"force_push","commitsCount":0,"pusher":{"login":"plietar","name":"Paul Liétar","path":"/plietar","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/1489775?s=80&v=4"},"commit":{"message":"Expose the package version in the C++ headers.\n\nOn multiple occasions, I have made changes to individual that\ninadvertently broke the ABI of the native code. Unfortunately, after the\nnew version of individual was released and users installed it, the R\ntooling wasn't able to detect this situation and did not automatically\nforce malariasimulation to be re-installed or re-compiled. As a result,\nusers were using a malariasimulation shared library that was built\nagainst individual 0.X together with an individual shared library at\nversion 0.(X+1). This causes very subtle and hard to diagnose bugs,\nwhere one piece of code might read from the wrong place.\n\nFor example, mrc-ide/individual#187 changed a return type of\n`NumericVariable::get_values` from a prvalue to a const-reference,\navoiding unnecessary copies. For most intents and purposes, this is a\nAPI-compatible change, but the ABI of the method is different. After the\nupdate, if a user was still using a installation of malariasimulation\nthat expected the old signature, the code would be compiled expecting to\nreceive an `std::vector` by value (ie. three words representing the\npointer to the data, the length and the capacity) instead received a\npointer to such a vector.\n\nAnother example is mrc-ide/individual#201, which removed the `num_bits`\nfield and made it a compile-time constant. Code which used `num_bits`\nwas now reading from an unintialized piece of memory instead. While the\n`num_bits` field was private, header-file code from the individual\npackage that reads the field can make its way into the malariasimulation\nshared library and embed the assumptions about the layout of the class.\nGiven the heavy use of templates in the package, almost all of it is\nre-instantiated and included in the downstream shared library.\n\nIn all these cases, recompiling malariasimulation is sufficient to\nensure it uses the new ABI of the individual package. If the user uses\n`devtools`, then this simply requires them to call\n`devtools::clean_dll`. The issue is that identifying the problem is near\nimpossible for a user. Nothing in the behaviour of malariasimulation\npoints to an incompatibility, instead the package only misbehaves in\nvery suprising ways.\n\nThe goal of this change is to export the version of the individual\npackage in its C++ headers. The constant may then be included and\ncompiled into the malariasimulation shared object. At load-time,\nmalariasimulation can compare this version with the result of\n`packageVersion(\"individual\")` and show a warning or an error if they\ndon't match. The user will be directed to re-install malariasimulation.\n\nSome alternatives I considered instead:\n1. Don't make ABI breaking changes to individual: I think this is a\n non-starter. We do not want to restrict our abilities to improve and\n optimise the package. Moreover identifying what is or isn't a breaking\n change is quite challenging.\n2. Stop exposing a C++ API, and require users to call the R functions\n instead: allowing users to write high-performant processes or utility\n functions for the hot path of their models is quite an important\n aspect of individual.\n3. Break the ABI but announce it in release notes so users know to be on\n the look out and to re-compile their copy of malariasimulation: no one\n reads release notes, especially for a package they only use\n indirectly. Moreover it still requires identifying ABI breaking changes.\n4. Implement the suggested scheme, but use an ABI version instead of the\n package version. This will avoid false positives, where the package's\n version number is increased even though the ABI hasn't changed. I\n think the rate of releases and the cost of recompiling malariasimulation\n are low enough that it is better to err on the safe side and treat\n every release as if it could be ABI breaking.","shortMessageHtmlLink":"Expose the package version in the C++ headers."}},{"before":null,"after":"f3cba48a713f636f4634264f18c3be19afbf3dca","ref":"refs/heads/expose-version","pushedAt":"2024-09-06T12:45:45.000Z","pushType":"branch_creation","commitsCount":0,"pusher":{"login":"plietar","name":"Paul Liétar","path":"/plietar","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/1489775?s=80&v=4"},"commit":{"message":"Expose package version in the C++ headers.","shortMessageHtmlLink":"Expose package version in the C++ headers."}},{"before":"f26c87a8ec66f01797ccede56ea525677ed41708","after":"092af4ee476060229da4434c935a0ecaff7831dc","ref":"refs/heads/gh-pages","pushedAt":"2024-08-13T12:33:41.000Z","pushType":"push","commitsCount":1,"pusher":{"login":"github-actions[bot]","name":null,"path":"/apps/github-actions","primaryAvatarUrl":"https://avatars.githubusercontent.com/in/15368?s=80&v=4"},"commit":{"message":"Built site for individual@0.1.17: 079e45e","shortMessageHtmlLink":"Built site for individual@0.1.17: 079e45e"}},{"before":"fe41a9e82d6efde8db203f1d481326fe23067f68","after":null,"ref":"refs/heads/fix-partial-names","pushedAt":"2024-08-13T12:30:37.000Z","pushType":"branch_deletion","commitsCount":0,"pusher":{"login":"plietar","name":"Paul Liétar","path":"/plietar","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/1489775?s=80&v=4"}},{"before":"76496ecf1f437525249224221ca40ebbc3bd0cdf","after":"079e45e96fff0e5682ebfe5a7f9eb4dd9807c438","ref":"refs/heads/master","pushedAt":"2024-08-13T12:30:33.000Z","pushType":"pr_merge","commitsCount":2,"pusher":{"login":"plietar","name":"Paul Liétar","path":"/plietar","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/1489775?s=80&v=4"},"commit":{"message":"Merge pull request #203 from mrc-ide/fix-partial-names\n\nAllow only some processes to be named and not others.","shortMessageHtmlLink":"Merge pull request #203 from mrc-ide/fix-partial-names"}},{"before":null,"after":"bcd6d13b6b682f719cd8ddf6bc27e38b45d109e1","ref":"refs/heads/feat/logi_size","pushedAt":"2024-08-07T10:55:58.000Z","pushType":"branch_creation","commitsCount":0,"pusher":{"login":"giovannic","name":"Giovanni","path":"/giovannic","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/2605711?s=80&v=4"},"commit":{"message":"Add bitset_count_and","shortMessageHtmlLink":"Add bitset_count_and"}},{"before":null,"after":"fe41a9e82d6efde8db203f1d481326fe23067f68","ref":"refs/heads/fix-partial-names","pushedAt":"2024-07-25T15:16:46.000Z","pushType":"branch_creation","commitsCount":0,"pusher":{"login":"plietar","name":"Paul Liétar","path":"/plietar","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/1489775?s=80&v=4"},"commit":{"message":"Allow only some processes to be named and not others.\n\nIt was using `is.null` to detect unnamed processes, however in the case\nof a list of processes where some are named and some are not, the name\nis actually an empty string.","shortMessageHtmlLink":"Allow only some processes to be named and not others."}},{"before":"1e4b6022dadd1ce622d122ea04c5d6d1509bc08a","after":"76496ecf1f437525249224221ca40ebbc3bd0cdf","ref":"refs/heads/dev","pushedAt":"2024-07-22T12:34:00.000Z","pushType":"push","commitsCount":2,"pusher":{"login":"plietar","name":"Paul Liétar","path":"/plietar","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/1489775?s=80&v=4"},"commit":{"message":"Merge pull request #202 from mrc-ide/release/0.1.17\n\nRelease 0.1.17","shortMessageHtmlLink":"Merge pull request #202 from mrc-ide/release/0.1.17"}},{"before":"5c1ba2552a1cb8fcc2e4aa09d54802b59ed8afe9","after":"f26c87a8ec66f01797ccede56ea525677ed41708","ref":"refs/heads/gh-pages","pushedAt":"2024-07-18T16:23:29.000Z","pushType":"push","commitsCount":1,"pusher":{"login":"github-actions[bot]","name":null,"path":"/apps/github-actions","primaryAvatarUrl":"https://avatars.githubusercontent.com/in/15368?s=80&v=4"},"commit":{"message":"Built site for individual@0.1.17: 76496ec","shortMessageHtmlLink":"Built site for individual@0.1.17: 76496ec"}},{"before":"ecf2a685c315614617b62d4730cc720effc729ec","after":"76496ecf1f437525249224221ca40ebbc3bd0cdf","ref":"refs/heads/master","pushedAt":"2024-07-18T16:20:18.000Z","pushType":"pr_merge","commitsCount":7,"pusher":{"login":"plietar","name":"Paul Liétar","path":"/plietar","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/1489775?s=80&v=4"},"commit":{"message":"Merge pull request #202 from mrc-ide/release/0.1.17\n\nRelease 0.1.17","shortMessageHtmlLink":"Merge pull request #202 from mrc-ide/release/0.1.17"}},{"before":null,"after":"e1279c835ec3cbc6b91ae1d44471e40b1e16107a","ref":"refs/heads/release/0.1.17","pushedAt":"2024-07-18T12:23:36.000Z","pushType":"branch_creation","commitsCount":0,"pusher":{"login":"plietar","name":"Paul Liétar","path":"/plietar","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/1489775?s=80&v=4"},"commit":{"message":"Release 0.1.17","shortMessageHtmlLink":"Release 0.1.17"}},{"before":"9927e3e3e5c93176fdf53be5896146a2b0751586","after":"1e4b6022dadd1ce622d122ea04c5d6d1509bc08a","ref":"refs/heads/dev","pushedAt":"2024-07-17T10:24:48.000Z","pushType":"pr_merge","commitsCount":1,"pusher":{"login":"plietar","name":"Paul Liétar","path":"/plietar","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/1489775?s=80&v=4"},"commit":{"message":"Add a method to overwrite a bitset. (#200)\n\nThis copies the value from one bitset to another one.","shortMessageHtmlLink":"Add a method to overwrite a bitset. (#200)"}},{"before":"5376bc27ce9568036b40da90561d4e0da9bf7ef1","after":"9927e3e3e5c93176fdf53be5896146a2b0751586","ref":"refs/heads/dev","pushedAt":"2024-07-16T17:53:53.000Z","pushType":"pr_merge","commitsCount":2,"pusher":{"login":"plietar","name":"Paul Liétar","path":"/plietar","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/1489775?s=80&v=4"},"commit":{"message":"Merge pull request #201 from plietar/constexpr-numbits\n\nMake num_bits a constant expression.","shortMessageHtmlLink":"Merge pull request #201 from plietar/constexpr-numbits"}},{"before":"3d199bc37f1f54d5cc25035dd43d3202719f0c23","after":"5376bc27ce9568036b40da90561d4e0da9bf7ef1","ref":"refs/heads/dev","pushedAt":"2024-07-16T11:27:01.000Z","pushType":"pr_merge","commitsCount":1,"pusher":{"login":"plietar","name":"Paul Liétar","path":"/plietar","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/1489775?s=80&v=4"},"commit":{"message":"Support vectors of logicals as an argument to filter_bitset. (#199)\n\nIn addition to a vector of numerical indices and another bitset, the\r\nfilter_bitset now accepts a vector of logicals (ie. booleans). Each set\r\nbit of the bitset is included in the return value only if the\r\ncorresponding value in the logical vector is TRUE.\r\n\r\nGiven `v` a logical vector, `filter_bitset(b, v)` is equivalent to the\r\nalready supported `filter_bitset(v, which(v))` but is more performant.\r\nThe new semantics also align with subsetting of R vectors, which\r\nsimilarly supports either a vector of indices or vector of logicals.","shortMessageHtmlLink":"Support vectors of logicals as an argument to filter_bitset. (#199)"}},{"before":"4bc7eaa3a6c049291b1a71953aa82caf466140b7","after":null,"ref":"refs/heads/named-processes","pushedAt":"2024-07-12T10:08:48.000Z","pushType":"branch_deletion","commitsCount":0,"pusher":{"login":"plietar","name":"Paul Liétar","path":"/plietar","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/1489775?s=80&v=4"}},{"before":"ecf2a685c315614617b62d4730cc720effc729ec","after":"3d199bc37f1f54d5cc25035dd43d3202719f0c23","ref":"refs/heads/dev","pushedAt":"2024-07-12T10:08:42.000Z","pushType":"pr_merge","commitsCount":1,"pusher":{"login":"plietar","name":"Paul Liétar","path":"/plietar","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/1489775?s=80&v=4"},"commit":{"message":"Allow processes to be named. (#198)\n\nBecause of how R assigns names to stack frames, all processes in a\r\ntypical individual simulation would end up being called `p`. This makes\r\nit difficult to interpret profiling results.\r\n\r\nR uses the name of the variable the called function is bound to. By\r\ndynamically creating a variable with a chosen name and using `eval` to\r\nexecute that variable, we can get the stack frame to show up with any\r\ndesired name.\r\n\r\nThis uses this trick to allow the list of processes to be given names,\r\nand these names are used in the calls.","shortMessageHtmlLink":"Allow processes to be named. (#198)"}},{"before":"258b75f8d83462e1694ec9afab8574b6036b2b9a","after":"ecf2a685c315614617b62d4730cc720effc729ec","ref":"refs/heads/dev","pushedAt":"2024-07-11T17:09:42.000Z","pushType":"push","commitsCount":3,"pusher":{"login":"plietar","name":"Paul Liétar","path":"/plietar","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/1489775?s=80&v=4"},"commit":{"message":"Merge pull request #197 from mrc-ide/release/0.1.16\n\nRelease 0.1.16","shortMessageHtmlLink":"Merge pull request #197 from mrc-ide/release/0.1.16"}},{"before":"07bc494c719bcf4d34bceecfb274b2ba2eb98a2d","after":"4bc7eaa3a6c049291b1a71953aa82caf466140b7","ref":"refs/heads/named-processes","pushedAt":"2024-07-11T17:09:13.000Z","pushType":"force_push","commitsCount":0,"pusher":{"login":"plietar","name":"Paul Liétar","path":"/plietar","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/1489775?s=80&v=4"},"commit":{"message":"Allow processes to be named.\n\nBecause of how R assigns names to stack frames, all processes in a\ntypical individual simulation would end up being called `p`. This makes\nit difficult to interpret profiling results.\n\nR uses the name of the variable the called function is bound to. By\ndynamically creating a variable with a chosen name and using `eval` to\nexecute that variable, we can get the stack frame to show up with any\ndesired name.\n\nThis uses this trick to allow the list of processes to be given names,\nand these names are used in the calls.","shortMessageHtmlLink":"Allow processes to be named."}},{"before":null,"after":"07bc494c719bcf4d34bceecfb274b2ba2eb98a2d","ref":"refs/heads/named-processes","pushedAt":"2024-07-11T16:17:41.000Z","pushType":"branch_creation","commitsCount":0,"pusher":{"login":"plietar","name":"Paul Liétar","path":"/plietar","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/1489775?s=80&v=4"},"commit":{"message":"Allow processes to be named.\n\nBecause of how R assigns names to stack frames, all processes in a\ntypical individual simulation would end up being called `p`. This makes\nit difficult to interpret profiling results.\n\nR uses the name of the variable the called function is bound to. By\ndynamically creating a variable with a chosen name and using `eval` to\nexecute that variable, we can get the stack frame to show up with any\ndesired name.\n\nThis uses this trick to allow the list of processes to be given names,\nand these names are used in the calls.","shortMessageHtmlLink":"Allow processes to be named."}},{"before":"82bdc43deab896ae05573f82ce7a25f0f8ab8f10","after":"5c1ba2552a1cb8fcc2e4aa09d54802b59ed8afe9","ref":"refs/heads/gh-pages","pushedAt":"2024-04-16T12:51:51.000Z","pushType":"push","commitsCount":1,"pusher":{"login":"github-actions[bot]","name":null,"path":"/apps/github-actions","primaryAvatarUrl":"https://avatars.githubusercontent.com/in/15368?s=80&v=4"},"commit":{"message":"cli-27269-596","shortMessageHtmlLink":"cli-27269-596"}},{"before":"4bef32e1f2bb12796046467c88343902b5efc08c","after":"ecf2a685c315614617b62d4730cc720effc729ec","ref":"refs/heads/master","pushedAt":"2024-04-16T12:44:31.000Z","pushType":"pr_merge","commitsCount":3,"pusher":{"login":"plietar","name":"Paul Liétar","path":"/plietar","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/1489775?s=80&v=4"},"commit":{"message":"Merge pull request #197 from mrc-ide/release/0.1.16\n\nRelease 0.1.16","shortMessageHtmlLink":"Merge pull request #197 from mrc-ide/release/0.1.16"}},{"before":"a545da81e91768a4b3c153f85503ff73c6529ca0","after":"ca51ae36bca480cc2b93dc40e308cb3022db4a38","ref":"refs/heads/release/0.1.16","pushedAt":"2024-04-16T10:05:13.000Z","pushType":"force_push","commitsCount":0,"pusher":{"login":"plietar","name":"Paul Liétar","path":"/plietar","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/1489775?s=80&v=4"},"commit":{"message":"Release 0.1.16","shortMessageHtmlLink":"Release 0.1.16"}},{"before":null,"after":"a545da81e91768a4b3c153f85503ff73c6529ca0","ref":"refs/heads/release/0.1.16","pushedAt":"2024-04-16T10:04:25.000Z","pushType":"branch_creation","commitsCount":0,"pusher":{"login":"plietar","name":"Paul Liétar","path":"/plietar","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/1489775?s=80&v=4"},"commit":{"message":"Release 0.1.16","shortMessageHtmlLink":"Release 0.1.16"}},{"before":"9c7fcde25858674e578caff7539c5dfa75f90499","after":null,"ref":"refs/heads/add-events","pushedAt":"2024-04-12T16:56:48.000Z","pushType":"branch_deletion","commitsCount":0,"pusher":{"login":"plietar","name":"Paul Liétar","path":"/plietar","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/1489775?s=80&v=4"}},{"before":"7e486089db5cf41c3bf0ab1f20bb2d914b1d2d99","after":"258b75f8d83462e1694ec9afab8574b6036b2b9a","ref":"refs/heads/dev","pushedAt":"2024-04-12T16:22:04.000Z","pushType":"pr_merge","commitsCount":1,"pusher":{"login":"plietar","name":"Paul Liétar","path":"/plietar","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/1489775?s=80&v=4"},"commit":{"message":"Allow events and variables to be added and removed when restoring the simulation. (#194)\n\nThe simulation restoring feature required the number of events to be\r\nidentical to the original simulation's. This has turned out to be too\r\nrestrictive for our use cases in malariasimulation, where we want to\r\nresume the simulation with new interventions enabled, which come with\r\nnew events.\r\n\r\nI had originally hoped that this would be enough, and that we could run\r\nthe first phase of the simulation with all the events present, even\r\nthough they are unused. However there are interventions whose number of\r\nevents depends on the parametrization of it, hence we cannot create a\r\nsaved simulation state that fits all possible use cases when resuming.\r\n\r\nThe solution implemented here is to allow more events and variables to\r\nbe introduced when resuming the simulation, on the condition that the\r\nobjects are named when passed to `simulation_loop`. Without this\r\nrequirement, given more objects than were saved, it would be ambigous\r\nwhich ones need to be restored and which ones are new.\r\n\r\nWhen a new object is included in the simulation, its `restore_state`\r\nmethod is called with a NULL argument. This is needed because events,\r\neven new ones, still need to set their internal timestep variable.\r\n\r\nAdditionally, the list of events and variables can now be structured\r\nusing nested lists of objects. This has no impact on the way the\r\nsimulation is executed, but it allows for more complicated simulations\r\nto be restored.\r\n\r\nFor example, this is a simplified example of what the list of events in\r\nmalariasimulation might look like:\r\n```\r\nlist(\r\n mda_administer = Event$new(),\r\n mass_pev_doses = list(\r\n TargetedEvent$new(n),\r\n TargetedEvent$new(n),\r\n TargetedEvent$new(n)\r\n )\r\n)\r\n```\r\n\r\nIn this example, the top-level list is names, allowing the\r\n`mass_pev_doses` events to be absent during the warmup simulation and\r\nadded only later when restoring. However, because the nested list of\r\ntargeted events is not named, more events cannot be added to it.\r\n\r\nThe names of the methods to save and restore state, together with the\r\nhelper functions `save_object_state` and `restore_object_state` are\r\ntweaked and made public to allow this pattern to be reused in\r\napplications that have their own state to save, as demonstrated by the\r\n[stateful.R] file in malariasimulation.\r\n\r\n[stateful.R]: https://github.com/mrc-ide/malariasimulation/blob/b3376d33cda29cc5e4d7217fefad4b367f9f9167/R/stateful.R","shortMessageHtmlLink":"Allow events and variables to be added and removed when restoring the…"}},{"before":"ec584db51dab30ee2d6c33e948055e25dacbf06b","after":"9c7fcde25858674e578caff7539c5dfa75f90499","ref":"refs/heads/add-events","pushedAt":"2024-04-12T11:36:59.000Z","pushType":"push","commitsCount":1,"pusher":{"login":"plietar","name":"Paul Liétar","path":"/plietar","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/1489775?s=80&v=4"},"commit":{"message":"Allow objects to be removed when resuming","shortMessageHtmlLink":"Allow objects to be removed when resuming"}},{"before":"a5fc67974db52095e4b8874b532dd91241c5ec59","after":"ec584db51dab30ee2d6c33e948055e25dacbf06b","ref":"refs/heads/add-events","pushedAt":"2024-03-26T16:40:11.000Z","pushType":"push","commitsCount":1,"pusher":{"login":"plietar","name":"Paul Liétar","path":"/plietar","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/1489775?s=80&v=4"},"commit":{"message":"Code review and more tests","shortMessageHtmlLink":"Code review and more tests"}},{"before":"1e376b984e6e8485dd24412d4eef70802716ea78","after":"a5fc67974db52095e4b8874b532dd91241c5ec59","ref":"refs/heads/add-events","pushedAt":"2024-03-25T14:10:05.000Z","pushType":"push","commitsCount":1,"pusher":{"login":"plietar","name":"Paul Liétar","path":"/plietar","primaryAvatarUrl":"https://avatars.githubusercontent.com/u/1489775?s=80&v=4"},"commit":{"message":"Fix docs","shortMessageHtmlLink":"Fix docs"}}],"hasNextPage":true,"hasPreviousPage":false,"activityType":"all","actor":null,"timePeriod":"all","sort":"DESC","perPage":30,"cursor":"Y3Vyc29yOnYyOpK7MjAyNC0wOS0wNlQxNTo0MDozMi4wMDAwMDBazwAAAASvFVTV","startCursor":"Y3Vyc29yOnYyOpK7MjAyNC0wOS0wNlQxNTo0MDozMi4wMDAwMDBazwAAAASvFVTV","endCursor":"Y3Vyc29yOnYyOpK7MjAyNC0wMy0yNVQxNDoxMDowNS4wMDAwMDBazwAAAAQeo7ZU"}},"title":"Activity · mrc-ide/individual"}