88 #include "pgm_controller.h"
89 #include "cst_controller.h"
90 #include "mdl_controller.h"
94 using namespace std::chrono;
95 using namespace r_code;
99 inline bool Group::is_active_pgm(View *view) {
101 return view->get_act() > get_act_thr() &&
102 get_c_sln() > get_c_sln_thr() &&
103 get_c_act() > get_c_act_thr();
106 inline bool Group::is_eligible_input(View *view) {
108 return view->get_sln() > get_sln_thr() &&
109 get_c_sln() > get_c_sln_thr() &&
110 get_c_act() > get_c_act_thr();
113 View *Group::get_view(uint32 OID) {
115 unordered_map<uint32, P<View> >::const_iterator it = other_views_.find(OID);
116 if (it != other_views_.end())
118 it = group_views_.find(OID);
119 if (it != group_views_.end())
121 it = ipgm_views_.find(OID);
122 if (it != ipgm_views_.end())
124 it = anti_ipgm_views_.find(OID);
125 if (it != anti_ipgm_views_.end())
127 it = input_less_ipgm_views_.find(OID);
128 if (it != input_less_ipgm_views_.end())
130 it = notification_views_.find(OID);
131 if (it != notification_views_.end())
136 void Group::reset_ctrl_values() {
138 sln_thr_changes_ = 0;
140 act_thr_changes_ = 0;
142 vis_thr_changes_ = 0;
148 c_sln_thr_changes_ = 0;
150 c_act_thr_changes_ = 0;
154 void Group::reset_stats() {
166 if (sln_change_monitoring_periods_to_go_ <= 0) {
168 if (get_sln_chg_thr() < 1)
169 sln_change_monitoring_periods_to_go_ = get_sln_chg_prd();
170 }
else if (get_sln_chg_thr() == 1)
171 sln_change_monitoring_periods_to_go_ = -1;
173 --sln_change_monitoring_periods_to_go_;
175 if (act_change_monitoring_periods_to_go_ <= 0) {
177 if (get_act_chg_thr() < 1)
178 act_change_monitoring_periods_to_go_ = get_act_chg_prd();
179 }
else if (get_act_chg_thr() == 1)
180 act_change_monitoring_periods_to_go_ = -1;
182 --act_change_monitoring_periods_to_go_;
185 void Group::update_stats() {
187 if (decay_periods_to_go_ > 0)
188 --decay_periods_to_go_;
191 if (code(GRP_DCY_AUTO).asFloat()) {
193 float32 period = code(GRP_DCY_PRD).asFloat();
194 if (decay_periods_to_go_ <= 0 && period > 0)
195 decay_periods_to_go_ = period;
199 avg_sln_ = avg_sln_ / (float32)sln_updates_;
201 avg_act_ = avg_act_ / (float32)act_updates_;
203 code(GRP_AVG_SLN) = Atom::Float(avg_sln_);
204 code(GRP_AVG_ACT) = Atom::Float(avg_act_);
205 code(GRP_HIGH_SLN) = Atom::Float(high_sln_);
206 code(GRP_LOW_SLN) = Atom::Float(low_sln_);
207 code(GRP_HIGH_ACT) = Atom::Float(high_act_);
208 code(GRP_LOW_ACT) = Atom::Float(low_act_);
210 if (sln_change_monitoring_periods_to_go_ == 0) {
212 FOR_ALL_NON_NTF_VIEWS_BEGIN(
this, v)
214 float32 change = v->second->update_sln_delta();
215 if (fabs(change) > get_sln_chg_thr()) {
217 uint16 ntf_grp_count = get_ntf_grp_count();
218 for (uint16 i = 1; i <= ntf_grp_count; ++i)
219 _Mem::Get()->inject_notification(
new NotificationView(
this, get_ntf_grp(i),
new MkSlnChg(_Mem::Get(), v->second->object_, change)),
false);
222 FOR_ALL_NON_NTF_VIEWS_END
225 if (act_change_monitoring_periods_to_go_ == 0) {
227 FOR_ALL_NON_NTF_VIEWS_BEGIN(
this, v)
229 float32 change = v->second->update_act_delta();
230 if (fabs(change) > get_act_chg_thr()) {
232 uint16 ntf_grp_count = get_ntf_grp_count();
233 for (uint16 i = 1; i <= ntf_grp_count; ++i)
234 _Mem::Get()->inject_notification(
new NotificationView(
this, get_ntf_grp(i),
new MkActChg(_Mem::Get(), v->second->object_, change)),
false);
237 FOR_ALL_NON_NTF_VIEWS_END
241 void Group::reset_decay_values() {
245 decay_periods_to_go_ = -1;
246 decay_percentage_per_period_ = 0;
250 float32 Group::update_sln_thr() {
252 float32 percentage = code(GRP_DCY_PER).asFloat();
253 float32 period = code(GRP_DCY_PRD).asFloat();
254 if (percentage == 0 || period == 0)
255 reset_decay_values();
258 float32 percentage_per_period = percentage / period;
259 if (percentage_per_period != decay_percentage_per_period_ || code(GRP_DCY_TGT).asFloat() != decay_target_) {
261 decay_periods_to_go_ = period;
262 decay_percentage_per_period_ = percentage_per_period;
263 decay_target_ = code(GRP_DCY_TGT).asFloat();
265 if (code(GRP_DCY_TGT).asFloat() == 0) {
268 sln_decay_ = percentage_per_period;
272 sln_thr_decay_ = percentage_per_period;
277 if (decay_periods_to_go_ > 0) {
279 if (sln_thr_decay_ != 0)
280 mod_sln_thr(get_sln_thr()*sln_thr_decay_);
283 if (sln_thr_changes_) {
285 float32 new_sln_thr = get_sln_thr() + acc_sln_thr_ / sln_thr_changes_;
288 else if (new_sln_thr > 1)
290 code(GRP_SLN_THR) = r_code::Atom::Float(new_sln_thr);
293 sln_thr_changes_ = 0;
294 return get_sln_thr();
297 float32 Group::update_act_thr() {
299 if (act_thr_changes_) {
301 float32 new_act_thr = get_act_thr() + acc_act_thr_ / act_thr_changes_;
304 else if (new_act_thr > 1)
306 code(GRP_ACT_THR) = r_code::Atom::Float(new_act_thr);
309 act_thr_changes_ = 0;
310 return get_act_thr();
313 float32 Group::update_vis_thr() {
315 if (vis_thr_changes_) {
317 float32 new_vis_thr = get_vis_thr() + acc_vis_thr_ / vis_thr_changes_;
320 else if (new_vis_thr > 1)
322 code(GRP_VIS_THR) = r_code::Atom::Float(new_vis_thr);
325 vis_thr_changes_ = 0;
326 return get_vis_thr();
329 float32 Group::update_c_sln() {
331 if (c_sln_changes_) {
333 float32 new_c_sln = get_c_sln() + acc_c_sln_ / c_sln_changes_;
336 else if (new_c_sln > 1)
338 code(GRP_C_SLN) = r_code::Atom::Float(new_c_sln);
345 float32 Group::update_c_act() {
347 if (c_act_changes_) {
349 float32 new_c_act = get_c_act() + acc_c_act_ / c_act_changes_;
352 else if (new_c_act > 1)
354 code(GRP_C_ACT) = r_code::Atom::Float(new_c_act);
361 float32 Group::update_c_sln_thr() {
363 if (c_sln_thr_changes_) {
365 float32 new_c_sln_thr = get_c_sln_thr() + acc_c_sln_thr_ / c_sln_thr_changes_;
366 if (new_c_sln_thr < 0)
368 else if (new_c_sln_thr > 1)
370 code(GRP_C_SLN_THR) = r_code::Atom::Float(new_c_sln_thr);
373 c_sln_thr_changes_ = 0;
374 return get_c_sln_thr();
377 float32 Group::update_c_act_thr() {
379 if (c_act_thr_changes_) {
381 float32 new_c_act_thr = get_c_act_thr() + acc_c_act_thr_ / c_act_thr_changes_;
382 if (new_c_act_thr < 0)
384 else if (new_c_act_thr > 1)
386 code(GRP_C_ACT_THR) = r_code::Atom::Float(new_c_act_thr);
389 c_act_thr_changes_ = 0;
390 return get_c_act_thr();
393 float32 Group::update_res(View *v) {
395 if (v->object_->is_invalidated())
397 float res = v->update_res();
398 if (!v->is_notification() && res > 0 && res < get_low_res_thr()) {
400 uint16 ntf_grp_count = get_ntf_grp_count();
401 for (uint16 i = 1; i <= ntf_grp_count; ++i)
402 _Mem::Get()->inject_notification(
new NotificationView(
this, get_ntf_grp(i),
new MkLowRes(_Mem::Get(), v->object_)),
false);
407 float32 Group::update_sln(View *v) {
409 if (decay_periods_to_go_ > 0 && sln_decay_ != 0)
410 v->mod_sln(v->get_sln()*sln_decay_);
412 float32 sln = v->update_sln(get_low_sln_thr(), get_high_sln_thr());
416 else if (sln < low_sln_)
419 if (!v->is_notification()) {
421 if (v->periods_at_high_sln_ == get_sln_ntf_prd()) {
423 v->periods_at_high_sln_ = 0;
424 uint16 ntf_grp_count = get_ntf_grp_count();
425 for (uint16 i = 1; i <= ntf_grp_count; ++i)
426 _Mem::Get()->inject_notification(
new NotificationView(
this, get_ntf_grp(i),
new MkHighSln(_Mem::Get(), v->object_)),
false);
427 }
else if (v->periods_at_low_sln_ == get_sln_ntf_prd()) {
429 v->periods_at_low_sln_ = 0;
430 uint16 ntf_grp_count = get_ntf_grp_count();
431 for (uint16 i = 1; i <= ntf_grp_count; ++i)
432 _Mem::Get()->inject_notification(
new NotificationView(
this, get_ntf_grp(i),
new MkLowSln(_Mem::Get(), v->object_)),
false);
438 float32 Group::update_act(View *v) {
440 float32 act = v->update_act(get_low_act_thr(), get_high_act_thr());
444 else if (act < low_act_)
447 if (!v->is_notification()) {
449 if (v->periods_at_high_act_ == get_act_ntf_prd()) {
451 v->periods_at_high_act_ = 0;
452 uint16 ntf_grp_count = get_ntf_grp_count();
453 for (uint16 i = 1; i <= ntf_grp_count; ++i)
454 _Mem::Get()->inject_notification(
new NotificationView(
this, get_ntf_grp(i),
new MkHighAct(_Mem::Get(), v->object_)),
false);
455 }
else if (v->periods_at_low_act_ == get_act_ntf_prd()) {
457 v->periods_at_low_act_ = 0;
458 uint16 ntf_grp_count = get_ntf_grp_count();
459 for (uint16 i = 1; i <= ntf_grp_count; ++i)
460 _Mem::Get()->inject_notification(
new NotificationView(
this, get_ntf_grp(i),
new MkLowAct(_Mem::Get(), v->object_)),
false);
468 bool Group::load(View *view,
Code *
object) {
470 switch (object->code(0).getDescriptor()) {
472 group_views_[view->get_oid()] = view;
475 bool viewing_c_active = get_c_act() > get_c_act_thr();
476 bool viewing_c_salient = get_c_sln() > get_c_sln_thr();
477 bool viewed_visible = view->get_vis() > get_vis_thr();
478 if (viewing_c_active && viewing_c_salient && viewed_visible)
479 ((Group *)
object)->viewing_groups_[
this] = view->get_cov();
481 }
case Atom::INSTANTIATED_PROGRAM: {
482 ipgm_views_[view->get_oid()] = view;
483 PGMController *c =
new PGMController(view);
484 view->controller_ = c;
485 if (is_active_pgm(view))
486 c->gain_activation();
488 }
case Atom::INSTANTIATED_INPUT_LESS_PROGRAM: {
489 input_less_ipgm_views_[view->get_oid()] = view;
490 InputLessPGMController *c =
new InputLessPGMController(view);
491 view->controller_ = c;
492 if (is_active_pgm(view))
493 c->gain_activation();
495 }
case Atom::INSTANTIATED_ANTI_PROGRAM: {
496 anti_ipgm_views_[view->get_oid()] = view;
497 AntiPGMController *c =
new AntiPGMController(view);
498 view->controller_ = c;
499 if (is_active_pgm(view))
500 c->gain_activation();
502 }
case Atom::INSTANTIATED_CPP_PROGRAM: {
503 ipgm_views_[view->get_oid()] = view;
504 Controller *c = CPPPrograms::New(Utils::GetString<Code>(view->object_, ICPP_PGM_NAME), view);
507 view->controller_ = c;
508 if (is_active_pgm(view))
509 c->gain_activation();
511 }
case Atom::COMPOSITE_STATE: {
512 ipgm_views_[view->get_oid()] = view;
513 CSTController *c =
new CSTController(view);
514 view->controller_ = c;
515 c->set_secondary_host(get_secondary_group());
516 if (is_active_pgm(view))
517 c->gain_activation();
518 #ifdef WITH_DETAIL_OID
519 OUTPUT_LINE(MDL_OUT,
"load cst " << view->object_->get_oid() <<
520 ", CSTController(" + to_string(c->get_detail_oid()) +
")");
524 ipgm_views_[view->get_oid()] = view;
525 bool inject_in_secondary_group;
526 MDLController *c = MDLController::New(view, inject_in_secondary_group);
527 view->controller_ = c;
528 if (inject_in_secondary_group) {
529 Group* secondary_group = get_secondary_group();
532 secondary_group->load_secondary_mdl_controller(view);
534 if (is_active_pgm(view))
535 c->gain_activation();
536 #ifdef WITH_DETAIL_OID
537 OUTPUT_LINE(MDL_OUT,
"load mdl " << view->object_->get_oid() <<
538 ", MDLController(" + to_string(c->get_detail_oid()) +
") strength:" <<
539 view->object_->code(MDL_STRENGTH).asFloat() <<
" cnt:" << view->object_->code(MDL_CNT).asFloat() <<
540 " sr:" << view->object_->code(MDL_SR).asFloat());
544 for (uint32 i = 0; i <
object->references_size(); ++i)
545 object->get_reference(i)->markers_.push_back(
object);
546 other_views_[view->get_oid()] = view;
549 other_views_[view->get_oid()] = view;
556 void Group::update(Timestamp planned_time) {
560 if (
this != _Mem::Get()->get_root() && views_.size() == 0) {
568 newly_salient_views_.clear();
571 for (uint32 i = 0; i < pending_operations_.size(); ++i) {
573 pending_operations_[i]->execute(
this);
574 delete pending_operations_[i];
576 pending_operations_.clear();
583 GroupState state(get_sln_thr(), get_c_act() > get_c_act_thr(), update_c_act() > get_c_act_thr(), get_c_sln() > get_c_sln_thr(), update_c_sln() > get_c_sln_thr());
587 FOR_ALL_VIEWS_BEGIN_NO_INC(
this, v)
589 if (v->second->object_->is_invalidated())
593 auto ijt = v->second->get_ijt();
594 if (ijt >= planned_time) {
600 float32 res = update_res(v->second);
603 _update_saliency(&state, v->second);
605 switch (v->second->object_->code(0).getDescriptor()) {
607 _update_visibility(&state, v->second);
609 case Atom::NULL_PROGRAM:
610 case Atom::INSTANTIATED_PROGRAM:
611 case Atom::INSTANTIATED_ANTI_PROGRAM:
612 case Atom::INSTANTIATED_INPUT_LESS_PROGRAM:
613 case Atom::INSTANTIATED_CPP_PROGRAM:
614 case Atom::COMPOSITE_STATE:
616 _update_activation(&state, v->second);
622 v->second->delete_from_object();
628 if (state.is_c_salient)
632 std::multiset<P<View>,
_View::Less>::const_iterator v;
633 for (v = newly_salient_views_.begin(); v != newly_salient_views_.end(); ++v)
634 inject_reduction_jobs(*v);
636 if (state.is_c_active && state.is_c_salient) {
638 for (uint32 i = 0; i < new_controllers_.size(); ++i) {
640 switch (new_controllers_[i]->get_object()->code(0).getDescriptor()) {
641 case Atom::INSTANTIATED_ANTI_PROGRAM: {
642 P<TimeJob> j =
new AntiPGMSignalingJob((
r_exec::View *)new_controllers_[i]->get_view(), now + Utils::GetDuration<Code>(new_controllers_[i]->get_object(), IPGM_TSC));
643 _Mem::Get()->push_time_job(j);
645 }
case Atom::INSTANTIATED_INPUT_LESS_PROGRAM: {
647 P<TimeJob> j =
new InputLessPGMSignalingJob((
r_exec::View *)new_controllers_[i]->get_view(), now + Utils::GetDuration<Code>(new_controllers_[i]->get_object(), IPGM_TSC));
648 _Mem::Get()->push_time_job(j);
654 new_controllers_.clear();
661 P<TimeJob> j =
new UpdateJob(
this, planned_time + get_upr()*Utils::GetBasePeriod());
662 _Mem::Get()->push_time_job(j);
668 void Group::_update_saliency(GroupState *state, View *view) {
670 float32 view_old_sln = view->get_sln();
671 bool wiew_was_salient = view_old_sln > state->former_sln_thr;
672 float32 view_new_sln = update_sln(view);
673 bool wiew_is_salient = view_new_sln > get_sln_thr();
675 if (state->is_c_salient) {
677 if (wiew_is_salient) {
679 switch (view->get_sync()) {
680 case View::SYNC_ONCE:
681 case View::SYNC_ONCE_AXIOM:
682 case View::SYNC_PERIODIC:
683 if (!wiew_was_salient)
684 newly_salient_views_.insert(view);
686 case View::SYNC_HOLD:
687 case View::SYNC_AXIOM:
688 view->set_ijt(Now());
689 newly_salient_views_.insert(view);
699 if (state->is_c_active)
700 _initiate_sln_propagation(view->object_, view_new_sln - view_old_sln, get_sln_thr());
704 void Group::_update_visibility(GroupState *state, View *view) {
706 bool view_was_visible = view->get_vis() > get_vis_thr();
707 bool view_is_visible = view->update_vis() > get_vis_thr();
708 bool cov = view->get_cov();
711 if (state->was_c_active && state->was_c_salient) {
713 if (!state->is_c_active || !state->is_c_salient)
714 ((Group *)view->object_)->viewing_groups_.erase(
this);
717 if (!view_was_visible) {
720 ((Group *)view->object_)->viewing_groups_[
this] = cov;
723 if (!view_is_visible)
724 ((Group *)view->object_)->viewing_groups_.erase(
this);
726 ((Group *)view->object_)->viewing_groups_[
this] = cov;
729 }
else if (state->is_c_active && state->is_c_salient) {
732 ((Group *)view->object_)->viewing_groups_[
this] = cov;
736 void Group::_update_activation(GroupState *state, View *view) {
738 bool view_was_active = view->get_act() > get_act_thr();
739 bool view_is_active = update_act(view) > get_act_thr();
742 if (state->was_c_active && state->was_c_salient) {
744 if (!state->is_c_active || !state->is_c_salient)
745 view->controller_->lose_activation();
748 if (!view_was_active) {
750 if (view_is_active) {
752 view->controller_->gain_activation();
753 new_controllers_.push_back(view->controller_);
758 view->controller_->lose_activation();
761 }
else if (state->is_c_active && state->is_c_salient) {
763 if (view_is_active) {
765 view->controller_->gain_activation();
766 new_controllers_.push_back(view->controller_);
773 void Group::_initiate_sln_propagation(
Code *
object, float32 change, float32 source_sln_thr)
const {
775 if (fabs(change) > object->get_psln_thr()) {
778 path.push_back(
object);
780 if (object->code(0).getDescriptor() == Atom::MARKER) {
782 for (uint16 i = 0; i <
object->references_size(); ++i)
783 _propagate_sln(object->get_reference(i), change, source_sln_thr, path);
787 object->acq_markers();
789 for (m = object->markers_.begin(); m != object->markers_.end(); ++m)
790 _propagate_sln(*m, change, source_sln_thr, path);
791 object->rel_markers();
795 void Group::_initiate_sln_propagation(
Code *
object, float32 change, float32 source_sln_thr, vector<Code *> &path)
const {
797 if (fabs(change) > object->get_psln_thr()) {
800 for (uint32 i = 0; i < path.size(); ++i)
801 if (path[i] ==
object)
803 path.push_back(
object);
805 if (object->code(0).getDescriptor() == Atom::MARKER)
806 for (uint16 i = 0; i <
object->references_size(); ++i)
807 _propagate_sln(object->get_reference(i), change, source_sln_thr, path);
810 object->acq_markers();
812 for (m = object->markers_.begin(); m != object->markers_.end(); ++m)
813 _propagate_sln(*m, change, source_sln_thr, path);
814 object->rel_markers();
818 void Group::_propagate_sln(
Code *
object, float32 change, float32 source_sln_thr, vector<Code *> &path)
const {
820 if (
object == _Mem::Get()->get_root())
824 for (uint32 i = 0; i < path.size(); ++i)
825 if (path[i] ==
object)
827 path.push_back(
object);
829 P<TimeJob> j =
new SaliencyPropagationJob(
object, change, source_sln_thr, Timestamp(seconds(0)));
830 _Mem::Get()->push_time_job(j);
832 _initiate_sln_propagation(
object, change, source_sln_thr, path);
837 void Group::inject_hlps(vector<View *> &views) {
841 vector<View *>::const_iterator view;
842 for (view = views.begin(); view != views.end(); ++view) {
844 Atom a = (*view)->object_->code(0);
845 switch (a.getDescriptor()) {
846 case Atom::COMPOSITE_STATE: {
847 ipgm_views_[(*view)->get_oid()] = *view;
848 CSTController *c =
new CSTController(*view);
849 (*view)->controller_ = c;
850 c->set_secondary_host(get_secondary_group());
851 string controllerInfo;
852 #ifdef WITH_DETAIL_OID
853 controllerInfo =
", CSTController(" + to_string(c->get_detail_oid()) +
")";
855 OUTPUT_LINE(CST_OUT, Utils::RelativeTime(Now()) <<
" -> cst " << (*view)->object_->get_oid() << controllerInfo);
859 ipgm_views_[(*view)->get_oid()] = *view;
860 bool inject_in_secondary_group;
861 MDLController *c = MDLController::New(*view, inject_in_secondary_group);
862 (*view)->controller_ = c;
863 if (inject_in_secondary_group)
864 get_secondary_group()->inject_secondary_mdl_controller(*view);
865 string controllerInfo;
866 #ifdef WITH_DETAIL_OID
867 controllerInfo =
", MDLController(" + to_string(c->get_detail_oid()) +
")";
869 OUTPUT_LINE(MDL_OUT, Utils::RelativeTime(Now()) <<
" -> mdl " << (*view)->object_->get_oid() <<
870 " strength:" << (*view)->object_->code(MDL_STRENGTH).asFloat() <<
" cnt:" <<
871 (*view)->object_->code(MDL_CNT).asFloat() <<
" sr:" << (*view)->object_->code(MDL_SR).asFloat() << controllerInfo);
875 (*view)->set_ijt(Now());
878 for (view = views.begin(); view != views.end(); ++view) {
880 if (is_active_pgm(*view)) {
882 (*view)->controller_->gain_activation();
883 std::multiset<P<View>,
_View::Less>::const_iterator v;
884 for (v = newly_salient_views_.begin(); v != newly_salient_views_.end(); ++v)
885 (*view)->controller_->_take_input(*v);
892 void Group::inject(View *view) {
896 Atom a = view->object_->code(0);
899 switch (a.getDescriptor()) {
900 case Atom::NULL_PROGRAM:
901 ipgm_views_[view->get_oid()] = view;
902 if (is_active_pgm(view)) {
904 view->controller_->gain_activation();
905 if (a.takesPastInputs()) {
907 std::multiset<P<View>,
_View::Less>::const_iterator v;
908 for (v = newly_salient_views_.begin(); v != newly_salient_views_.end(); ++v)
909 view->controller_->_take_input(*v);
913 case Atom::INSTANTIATED_PROGRAM: {
914 ipgm_views_[view->get_oid()] = view;
915 PGMController *c =
new PGMController(view);
916 view->controller_ = c;
917 if (is_active_pgm(view)) {
919 c->gain_activation();
920 std::multiset<P<View>,
_View::Less>::const_iterator v;
921 for (v = newly_salient_views_.begin(); v != newly_salient_views_.end(); ++v)
925 }
case Atom::INSTANTIATED_CPP_PROGRAM: {
926 ipgm_views_[view->get_oid()] = view;
927 Controller *c = CPPPrograms::New(Utils::GetString<Code>(view->object_, ICPP_PGM_NAME), view);
930 view->controller_ = c;
931 if (is_active_pgm(view)) {
933 c->gain_activation();
934 std::multiset<P<View>,
_View::Less>::const_iterator v;
935 for (v = newly_salient_views_.begin(); v != newly_salient_views_.end(); ++v)
939 }
case Atom::INSTANTIATED_ANTI_PROGRAM: {
940 anti_ipgm_views_[view->get_oid()] = view;
941 AntiPGMController *c =
new AntiPGMController(view);
942 view->controller_ = c;
943 if (is_active_pgm(view)) {
945 c->gain_activation();
946 std::multiset<P<View>,
_View::Less>::const_iterator v;
947 for (v = newly_salient_views_.begin(); v != newly_salient_views_.end(); ++v)
949 _Mem::Get()->push_time_job(
new AntiPGMSignalingJob(view, now + Utils::GetDuration<Code>(c->get_object(), IPGM_TSC)));
952 }
case Atom::INSTANTIATED_INPUT_LESS_PROGRAM: {
953 input_less_ipgm_views_[view->get_oid()] = view;
954 InputLessPGMController *c =
new InputLessPGMController(view);
955 view->controller_ = c;
956 if (is_active_pgm(view)) {
958 c->gain_activation();
959 _Mem::Get()->push_time_job(
new InputLessPGMSignalingJob(view, now + Utils::GetDuration<Code>(view->object_, IPGM_TSC)));
963 other_views_[view->get_oid()] = view;
967 other_views_[view->get_oid()] = view;
970 case Atom::COMPOSITE_STATE: {
971 OUTPUT_LINE(HLP_INJ, Utils::RelativeTime(Now()) <<
" cst " << view->object_->get_oid() <<
" injected");
972 ipgm_views_[view->get_oid()] = view;
973 CSTController *c =
new CSTController(view);
974 view->controller_ = c;
975 c->set_secondary_host(get_secondary_group());
976 if (is_active_pgm(view)) {
978 c->gain_activation();
979 std::multiset<P<View>,
_View::Less>::const_iterator v;
980 for (v = newly_salient_views_.begin(); v != newly_salient_views_.end(); ++v)
985 OUTPUT_LINE(HLP_INJ, Utils::RelativeTime(Now()) <<
" mdl " << view->object_->get_oid() <<
" injected");
986 ipgm_views_[view->get_oid()] = view;
987 bool inject_in_secondary_group;
988 MDLController *c = MDLController::New(view, inject_in_secondary_group);
989 view->controller_ = c;
990 if (inject_in_secondary_group)
991 get_secondary_group()->inject_secondary_mdl_controller(view);
992 if (is_active_pgm(view)) {
994 c->gain_activation();
995 std::multiset<P<View>,
_View::Less>::const_iterator v;
996 for (v = newly_salient_views_.begin(); v != newly_salient_views_.end(); ++v)
997 c->Controller::_take_input(*v);
1003 if (is_eligible_input(view)) {
1005 newly_salient_views_.insert(view);
1006 inject_reduction_jobs(view);
1012 void Group::inject_new_object(View *view) {
1014 switch (view->object_->code(0).getDescriptor()) {
1016 for (uint32 i = 0; i < view->object_->references_size(); ++i) {
1018 Code *ref = view->object_->get_reference(i);
1020 ref->markers_.push_back(view->object_);
1032 void Group::inject_existing_object(View *view) {
1034 Code *
object = view->object_;
1035 object->acq_views();
1036 View *existing_view = (View *)object->get_view(
this,
false);
1037 if (!existing_view) {
1039 object->views_.insert(view);
1040 object->rel_views();
1045 object->rel_views();
1049 pending_operations_.push_back(
new Group::Set(existing_view->get_oid(), VIEW_RES, view->get_res()));
1050 pending_operations_.push_back(
new Group::Set(existing_view->get_oid(), VIEW_SLN, view->get_sln()));
1051 switch (object->code(0).getDescriptor()) {
1052 case Atom::INSTANTIATED_PROGRAM:
1053 case Atom::INSTANTIATED_ANTI_PROGRAM:
1054 case Atom::INSTANTIATED_INPUT_LESS_PROGRAM:
1055 case Atom::INSTANTIATED_CPP_PROGRAM:
1056 case Atom::COMPOSITE_STATE:
1058 pending_operations_.push_back(
new Group::Set(existing_view->get_oid(), VIEW_ACT, view->get_act()));
1062 existing_view->code(VIEW_SYNC) = view->code(VIEW_SYNC);
1063 existing_view->set_ijt(Now());
1065 bool wiew_is_salient = view->get_sln() > get_sln_thr();
1066 bool wiew_was_salient = existing_view->get_sln() > get_sln_thr();
1067 bool reduce_view = (!wiew_was_salient && wiew_is_salient);
1070 bool group_is_c_active = update_c_act() > get_c_act_thr();
1071 bool group_is_c_salient = update_c_sln() > get_c_sln_thr();
1072 if (group_is_c_active && group_is_c_salient && reduce_view) {
1074 newly_salient_views_.insert(view);
1075 inject_reduction_jobs(view);
1082 void Group::inject_group(View *view) {
1086 group_views_[view->get_oid()] = view;
1088 if (get_c_sln() > get_c_sln_thr() && view->get_sln() > get_sln_thr()) {
1090 if (view->get_vis() > get_vis_thr())
1091 ((Group *)view->object_)->viewing_groups_[
this] = view->get_cov();
1093 inject_reduction_jobs(view);
1098 if (((Group *)view->object_)->get_upr() > 0)
1099 _Mem::Get()->push_time_job(
new UpdateJob((Group *)view->object_, ((Group *)view->object_)->get_next_upr_time(Now())));
1104 void Group::inject_notification(View *view,
bool lock) {
1109 notification_views_[view->get_oid()] = view;
1111 for (uint32 i = 0; i < view->object_->references_size(); ++i) {
1113 Code *ref = view->object_->get_reference(i);
1115 ref->markers_.push_back(view->object_);
1119 view->set_ijt(Now());
1121 if (get_c_sln() > get_c_sln_thr() && view->get_sln() > get_sln_thr())
1122 inject_reduction_jobs(view);
1128 void Group::inject_reduction_jobs(View *view) {
1130 if (get_c_act() > get_c_act_thr()) {
1133 FOR_ALL_VIEWS_WITH_INPUTS_BEGIN(
this, v)
1135 if (v->second->get_act() > get_act_thr())
1136 v->second->controller_->_take_input(view);
1138 FOR_ALL_VIEWS_WITH_INPUTS_END
1144 unordered_map<Group *, bool>::const_iterator vg;
1145 for (vg = viewing_groups_.begin(); vg != viewing_groups_.end(); ++vg) {
1147 if (vg->second || view->is_notification())
1150 FOR_ALL_VIEWS_WITH_INPUTS_BEGIN(vg->first, v)
1152 if (v->second->get_act() > vg->first->get_act_thr())
1153 v->second->controller_->_take_input(view);
1155 FOR_ALL_VIEWS_WITH_INPUTS_END
1159 void Group::notifyNew(View *view) {
1161 if (get_ntf_new() == 1) {
1163 uint16 ntf_grp_count = get_ntf_grp_count();
1164 for (uint16 i = 1; i <= ntf_grp_count; ++i)
1165 _Mem::Get()->inject_notification(
new NotificationView(
this, get_ntf_grp(i),
new MkNew(_Mem::Get(), view->object_)), get_ntf_grp(i) !=
this);
1169 void Group::cov(View *view) {
1171 unordered_map<Group *, bool>::const_iterator vg;
1172 for (vg = viewing_groups_.begin(); vg != viewing_groups_.end(); ++vg) {
1175 _Mem::Get()->inject_copy(view, vg->first);
1183 unordered_map<Group *, bool>::const_iterator vg;
1184 for (vg = viewing_groups_.begin(); vg != viewing_groups_.end(); ++vg) {
1188 std::multiset<P<View>,
_View::Less>::const_iterator v;
1189 for (v = newly_salient_views_.begin(); v != newly_salient_views_.end(); ++v) {
1191 if ((*v)->is_notification())
1193 switch ((*v)->object_->code(0).getDescriptor()) {
1195 case Atom::NULL_PROGRAM:
1196 case Atom::INSTANTIATED_PROGRAM:
1197 case Atom::INSTANTIATED_CPP_PROGRAM:
1198 case Atom::INSTANTIATED_INPUT_LESS_PROGRAM:
1199 case Atom::INSTANTIATED_ANTI_PROGRAM:
1200 case Atom::COMPOSITE_STATE:
1204 _Mem::Get()->inject_copy(*v, vg->first);
1212 void Group::delete_view(View *v) {
1214 if (v->is_notification())
1215 notification_views_.erase(v->get_oid());
1216 else switch (v->object_->code(0).getDescriptor()) {
1217 case Atom::NULL_PROGRAM:
1218 case Atom::INSTANTIATED_PROGRAM:
1219 case Atom::INSTANTIATED_CPP_PROGRAM:
1220 case Atom::COMPOSITE_STATE:
1222 ipgm_views_.erase(v->get_oid());
1224 case Atom::INSTANTIATED_ANTI_PROGRAM:
1225 anti_ipgm_views_.erase(v->get_oid());
1227 case Atom::INSTANTIATED_INPUT_LESS_PROGRAM:
1228 input_less_ipgm_views_.erase(v->get_oid());
1232 other_views_.erase(v->get_oid());
1235 group_views_.erase(v->get_oid());
1240 void Group::delete_view(unordered_map<uint32,
P<View> >::const_iterator &v) {
1242 if (v->second->is_notification())
1243 v = notification_views_.erase(v);
1244 else switch (v->second->object_->code(0).getDescriptor()) {
1245 case Atom::NULL_PROGRAM:
1246 case Atom::INSTANTIATED_PROGRAM:
1247 case Atom::INSTANTIATED_CPP_PROGRAM:
1248 case Atom::COMPOSITE_STATE:
1250 v = ipgm_views_.erase(v);
1252 case Atom::INSTANTIATED_ANTI_PROGRAM:
1253 v = anti_ipgm_views_.erase(v);
1255 case Atom::INSTANTIATED_INPUT_LESS_PROGRAM:
1256 v = input_less_ipgm_views_.erase(v);
1260 v = other_views_.erase(v);
1263 v = group_views_.erase(v);
1268 Group *Group::get_secondary_group() {
1270 Group *secondary = NULL;
1273 for (m = markers_.begin(); m != markers_.end(); ++m) {
1275 if ((*m)->code(0).asOpcode() == Opcodes::MkGrpPair) {
1277 if ((Group *)(*m)->get_reference((*m)->code(GRP_PAIR_FIRST).asIndex()) ==
this) {
1279 secondary = (Group *)(*m)->get_reference((*m)->code(GRP_PAIR_SECOND).asIndex());
1288 void Group::load_secondary_mdl_controller(View *view) {
1290 PrimaryMDLController *p = (PrimaryMDLController *)view->controller_;
1291 View *_view =
new View(view,
true);
1292 _view->code(VIEW_ACT) = Atom::Float(0);
1293 _view->references_[0] =
this;
1294 ipgm_views_[_view->get_oid()] = _view;
1295 SecondaryMDLController *s =
new SecondaryMDLController(_view);
1296 _view->controller_ = s;
1297 view->object_->views_.insert(_view);
1298 p->set_secondary(s);
1302 void Group::inject_secondary_mdl_controller(View *view) {
1304 PrimaryMDLController *p = (PrimaryMDLController *)view->controller_;
1305 View *_view =
new View(view,
true);
1306 _view->code(VIEW_ACT) = Atom::Float(0);
1307 _view->references_[0] =
this;
1308 ipgm_views_[_view->get_oid()] = _view;
1309 SecondaryMDLController *s =
new SecondaryMDLController(_view);
1310 _view->controller_ = s;
1311 view->object_->views_.insert(_view);
1312 p->set_secondary(s);
1316 Timestamp Group::get_next_upr_time(Timestamp now)
const {
1318 uint32 __upr = get_upr();
1320 return Utils_MaxTime;
1321 auto _upr = __upr * Utils::GetBasePeriod();
1322 auto delta = (now - Utils::GetTimeReference()) % _upr;
1323 return now - delta + _upr;
1326 Timestamp Group::get_prev_upr_time(Timestamp now)
const {
1328 uint32 __upr = get_upr();
1330 return Utils_MaxTime;
1331 auto _upr = __upr * Utils::GetBasePeriod();
1332 auto delta = (now - Utils::GetTimeReference()) % _upr;