@@ -41,23 +41,27 @@ namespace buildcc {
4141class  CustomGeneratorContext  {
4242public: 
4343  CustomGeneratorContext (const  env::Command &c, const  fs_unordered_set &i,
44-                          const  fs_unordered_set &o)
45-       : command(c), inputs(i), outputs(o) {}
44+                          const  fs_unordered_set &o,
45+                          const  std::vector<uint8_t > &ub)
46+       : command(c), inputs(i), outputs(o), userblob(ub) {}
4647
47- public: 
4848  const  env::Command &command;
4949  const  fs_unordered_set &inputs;
5050  const  fs_unordered_set &outputs;
51+   const  std::vector<uint8_t > &userblob;
5152};
5253
5354//  clang-format off
54- typedef   std::function<bool (CustomGeneratorContext &)> GenerateCb ;
55+ using  GenerateCb =  std::function<bool   (CustomGeneratorContext &)>;
5556
56- typedef   std::function<void (std::unordered_map<std::string, tf::Task> &)> DependencyCb ;
57+ using  DependencyCb =  std::function<void   (std::unordered_map<std::string, tf::Task> &&)> ;
5758//  clang-format on
5859
5960class  CustomBlobHandler  {
6061public: 
62+   CustomBlobHandler () = default ;
63+   virtual  ~CustomBlobHandler () = default ;
64+ 
6165  bool  CheckChanged (const  std::vector<uint8_t > &previous,
6266                    const  std::vector<uint8_t > ¤t) const  {
6367    env::assert_fatal (
@@ -69,7 +73,7 @@ class CustomBlobHandler {
6973    return  !IsEqual (previous, current);
7074  };
7175
72-   std::vector<uint8_t > GetSerializedData () {
76+   std::vector<uint8_t > GetSerializedData () const   {
7377    auto  serialized_data = Serialize ();
7478    env::assert_fatal (
7579        Verify (serialized_data),
@@ -94,12 +98,11 @@ struct UserCustomGeneratorSchema : public internal::CustomGeneratorSchema {
9498  std::unordered_map<std::string, UserGenInfo> gen_info_map;
9599
96100  void  ConvertToInternal () {
97-     for  (auto  &r_miter : gen_info_map) {
98-       r_miter.second .internal_inputs  = path_schema_convert (
99-           r_miter.second .inputs , internal::Path::CreateExistingPath);
100-       auto  p = internal_gen_info_map.emplace (r_miter.first , r_miter.second );
101-       env::assert_fatal (p.second ,
102-                         fmt::format (" Could not save {}" first ));
101+     for  (auto  &[id, gen_info] : gen_info_map) {
102+       gen_info.internal_inputs  = path_schema_convert (
103+           gen_info.inputs , internal::Path::CreateExistingPath);
104+       auto  [_, success] = internal_gen_info_map.try_emplace (id, gen_info);
105+       env::assert_fatal (success, fmt::format (" Could not save {}" 
103106    }
104107  }
105108};
@@ -136,6 +139,10 @@ class CustomGenerator : public internal::BuilderInterface {
136139                  const  GenerateCb &generate_cb,
137140                  std::shared_ptr<CustomBlobHandler> blob_handler = nullptr );
138141
142+   void  AddGroup (const  std::string &group_id,
143+                 std::initializer_list<std::string> ids,
144+                 const  DependencyCb &dependency_cb = DependencyCb());
145+ 
139146  //  Callbacks
140147  /* *
141148   * @brief Setup dependencies between Tasks using their `id` 
@@ -168,20 +175,48 @@ class CustomGenerator : public internal::BuilderInterface {
168175private: 
169176  void  Initialize ();
170177
171-   template  <bool  run> void  TaskRunner (const  std::string &id);
178+   void  TaskRunner (bool  run, const  std::string &id);
179+   tf::Task CreateTaskRunner (tf::Subflow &subflow, bool  build,
180+                             const  std::string &id);
172181
173182  void  GenerateTask ();
174-   void  BuildGenerate (
175-       std::unordered_map<std::string, UserGenInfo> &gen_selected_map,
176-       std::unordered_map<std::string, UserGenInfo> &dummy_gen_selected_map);
183+   void  BuildGenerate (std::unordered_set<std::string> &gen_selected_ids,
184+                      std::unordered_set<std::string> &dummy_gen_selected_ids);
185+ 
186+   void  InvokeDependencyCb (std::unordered_map<std::string, tf::Task>
187+                               &®istered_tasks) const  noexcept ;
177188
178189  //  Recheck states
179190  void  IdRemoved ();
180191  void  IdAdded ();
181192  void  IdUpdated ();
182193
183194protected: 
184-   env::Command command_;
195+   const  env::Command &ConstCommand () const  { return  command_; }
196+   env::Command &RefCommand () { return  command_; }
197+ 
198+ private: 
199+   struct  GroupMetadata  {
200+     std::vector<std::string> ids;
201+     DependencyCb dependency_cb;
202+ 
203+     void  InvokeDependencyCb (const  std::string &group_id,
204+                             std::unordered_map<std::string, tf::Task>
205+                                 &®istered_tasks) const  noexcept  {
206+       if  (!dependency_cb) {
207+         return ;
208+       }
209+       try  {
210+         dependency_cb (std::move (registered_tasks));
211+       } catch  (...) {
212+         env::log_critical (
213+             __FUNCTION__,
214+             fmt::format (" Dependency callback failed for group id {}" 
215+                         group_id));
216+         env::set_task_state (env::TaskState::FAILURE);
217+       }
218+     }
219+   };
185220
186221private: 
187222  std::string name_;
@@ -190,11 +225,14 @@ class CustomGenerator : public internal::BuilderInterface {
190225
191226  //  Serialization
192227  UserCustomGeneratorSchema user_;
228+   std::unordered_map<std::string, GroupMetadata> grouped_ids_;
229+   std::unordered_set<std::string> ungrouped_ids_;
193230
194231  std::mutex success_schema_mutex_;
195232  std::unordered_map<std::string, UserGenInfo> success_schema_;
196233
197234  //  Internal
235+   env::Command command_;
198236  tf::Taskflow tf_;
199237
200238  //  Callbacks
0 commit comments