void DiagnosticTreatNeg::onPatientDefault() { LOG_DEBUG_F( "Individual %d got the test but defaulted, receiving Defaulters intervention without waiting for days_to_diagnosis (actually means days_to_intervention) \n", parent->GetSuid().data ); // Important: Use the instance method to obtain the intervention factory obj instead of static method to cross the DLL boundary IGlobalContext *pGC = nullptr; const IInterventionFactory* ifobj = nullptr; if (s_OK == parent->QueryInterface(GET_IID(IGlobalContext), (void**)&pGC)) { ifobj = pGC->GetInterventionFactory(); } if (!ifobj) { throw NullPointerException( __FILE__, __LINE__, __FUNCTION__, "parent->GetInterventionFactoryObj()" ); } if( !defaulters_event.IsUninitialized() ) { if( defaulters_event != NO_TRIGGER_STR ) { INodeTriggeredInterventionConsumer* broadcaster = nullptr; if (s_OK != parent->GetEventContext()->GetNodeEventContext()->QueryInterface(GET_IID(INodeTriggeredInterventionConsumer), (void**)&broadcaster)) { throw QueryInterfaceException( __FILE__, __LINE__, __FUNCTION__, "parent->GetEventContext()->GetNodeEventContext()", "INodeTriggeredInterventionConsumer", "INodeEventContext" ); } broadcaster->TriggerNodeEventObserversByString( parent->GetEventContext(), defaulters_event ); } } else if( defaulters_config._json.Type() != ElementType::NULL_ELEMENT ) { auto tmp_config = Configuration::CopyFromElement(defaulters_config._json); // Distribute the defaulters intervention, right away (do not use the days_to_diagnosis IDistributableIntervention *di = const_cast<IInterventionFactory*>(ifobj)->CreateIntervention( tmp_config ); delete tmp_config; tmp_config = nullptr; ICampaignCostObserver* pICCO; // Now make sure cost of the test-positive intervention is reported back to node if (s_OK == parent->GetEventContext()->GetNodeEventContext()->QueryInterface(GET_IID(ICampaignCostObserver), (void**)&pICCO) ) { di->Distribute( parent->GetInterventionsContext(), pICCO ); pICCO->notifyCampaignEventOccurred( (IBaseIntervention*)di, (IBaseIntervention*)this, parent ); } else { throw QueryInterfaceException( __FILE__, __LINE__, __FUNCTION__, "parent->GetEventContext()->GetNodeEventContext()", "ICampaignCostObserver", "INodeEventContext" ); } } else { throw GeneralConfigurationException( __FILE__, __LINE__, __FUNCTION__, "neither event or config defined" ); } }
void NodeLevelHealthTriggeredIVScaleUpSwitch::onDisqualifiedByCoverage( IIndividualHumanEventContext *pIndiv ) { //if qualify by everything except demographic coverage, give the not_covered_individualintervention_config // this intervention is the one phased out as the actual_individualintervention_config is phased in // if the not_covered_individualintervention_config is NULL, then there is no intervention to phase out LOG_DEBUG("The person qualified by everything except demographic coverage, give the not_covered_individualintervention_config \n"); // Query for campaign cost observer interface from INodeEventContext *parent ICampaignCostObserver *iCCO; if (s_OK != parent->QueryInterface(GET_IID(ICampaignCostObserver), (void**)&iCCO)) { throw QueryInterfaceException( __FILE__, __LINE__, __FUNCTION__, "parent", "ICampaignCostObserver", "INodeEventContext" ); } // Important: Use the instance method to obtain the intervention factory obj instead of static method to cross the DLL boundary //const IInterventionFactory* ifobj = dynamic_cast<NodeEventContextHost *>(parent)->GetInterventionFactoryObj(); IGlobalContext *pGC = nullptr; const IInterventionFactory* ifobj = nullptr; if (s_OK == parent->QueryInterface(GET_IID(IGlobalContext), (void**)&pGC)) { ifobj = pGC->GetInterventionFactory(); } if (!ifobj) { throw GeneralConfigurationException( __FILE__, __LINE__, __FUNCTION__, "The pointer to IInterventionFactory object is not valid (could be DLL specific)" ); } const json::Array & interventions_array = json::QuickInterpreter(not_covered_intervention_configs._json).As<json::Array>(); LOG_DEBUG_F("not_covered_intervention_configs array size = %d\n", interventions_array.Size()); if (interventions_array.Size() == 0 ) { LOG_DEBUG("nothing to phase out \n"); } else { for( int idx=0; idx<interventions_array.Size(); idx++ ) { const json::Object& notcoveredIntervention = json_cast<const json::Object&>(interventions_array[idx]); Configuration * tmpConfig = Configuration::CopyFromElement( notcoveredIntervention, "campaign" ); assert( tmpConfig ); LOG_DEBUG_F("NodeHTIScaleUpSwitch will distribute notcoveredintervention #%d\n", idx); IDistributableIntervention *di = const_cast<IInterventionFactory*>(ifobj)->CreateIntervention(tmpConfig); delete tmpConfig; tmpConfig = nullptr; if( di ) { di->Distribute( pIndiv->GetInterventionsContext(), iCCO ); LOG_DEBUG("A Node level health-triggered intervention was successfully distributed, gave the not_covered_intervention_configs\n"); // It's not at all clear to me that we would incur cost at this point, but we could. //iCCO->notifyCampaignExpenseIncurred( interventionCost, pIndiv ); } } } }
void DiagnosticTreatNeg::negativeTestDistribute() { LOG_DEBUG_F( "Individual %d tested 'negative', receiving negative intervention.\n", parent->GetSuid().data ); // Important: Use the instance method to obtain the intervention factory obj instead of static method to cross the DLL boundary IGlobalContext *pGC = nullptr; const IInterventionFactory* ifobj = nullptr; if (s_OK == parent->QueryInterface(GET_IID(IGlobalContext), (void**)&pGC)) { ifobj = pGC->GetInterventionFactory(); } if (!ifobj) { throw NullPointerException( __FILE__, __LINE__, __FUNCTION__, "parent->GetInterventionFactoryObj()" ); } if( use_event_or_config == EventOrConfig::Event ) { INodeTriggeredInterventionConsumer* broadcaster = nullptr; if (s_OK != parent->GetEventContext()->GetNodeEventContext()->QueryInterface(GET_IID(INodeTriggeredInterventionConsumer), (void**)&broadcaster)) { throw QueryInterfaceException( __FILE__, __LINE__, __FUNCTION__, "parent->GetEventContext()->GetNodeEventContext()", "INodeTriggeredInterventionConsumer", "INodeEventContext" ); } broadcaster->TriggerNodeEventObservers( parent->GetEventContext(), negative_diagnosis_event ); } else if( negative_diagnosis_config._json.Type() != ElementType::NULL_ELEMENT ) { auto tmp_config = Configuration::CopyFromElement( negative_diagnosis_config._json, "campaign" ); // Distribute the test-negative intervention IDistributableIntervention *di = const_cast<IInterventionFactory*>(ifobj)->CreateIntervention( tmp_config ); delete tmp_config; tmp_config = nullptr; ICampaignCostObserver* pICCO; // Now make sure cost of the test-positive intervention is reported back to node if (s_OK == parent->GetEventContext()->GetNodeEventContext()->QueryInterface(GET_IID(ICampaignCostObserver), (void**)&pICCO) ) { di->Distribute( parent->GetInterventionsContext(), pICCO ); pICCO->notifyCampaignEventOccurred( (IBaseIntervention*)di, (IBaseIntervention*)this, parent ); } else { throw QueryInterfaceException( __FILE__, __LINE__, __FUNCTION__, "parent->GetEventContext()->GetNodeEventContext()", "ICampaignCostObserver", "INodeEventContext" ); } } else { throw GeneralConfigurationException( __FILE__, __LINE__, __FUNCTION__, "neither event or config defined" ); } expired = true; }
void NodeLevelHealthTriggeredIV::SetContextTo(INodeEventContext *context) { BaseNodeIntervention::SetContextTo( context ); // Important: Use the instance method to obtain the intervention factory obj instead of static method to cross the DLL boundary //const IInterventionFactory* ifobj = dynamic_cast<NodeEventContextHost *>(parent)->GetInterventionFactoryObj(); IGlobalContext *pGC = nullptr; const IInterventionFactory* ifobj = nullptr; if (s_OK == parent->QueryInterface(GET_IID(IGlobalContext), (void**)&pGC)) { ifobj = pGC->GetInterventionFactory(); } if (!ifobj) { throw GeneralConfigurationException( __FILE__, __LINE__, __FUNCTION__, "The pointer to IInterventionFactory object is not valid (could be DLL specific)" ); } if( (_di == nullptr) && (_ndi == nullptr) ) { Configuration* config = nullptr; if( using_individual_config ) { config = Configuration::CopyFromElement( (actual_individual_intervention_config._json), "campaign" ); } else { config = Configuration::CopyFromElement( (actual_node_intervention_config._json), "campaign" ); } _di = const_cast<IInterventionFactory*>(ifobj)->CreateIntervention( config ); if( _di == nullptr ) { _ndi = const_cast<IInterventionFactory*>(ifobj)->CreateNDIIntervention( config ); } release_assert( (_di !=nullptr) || (_ndi != nullptr) ); delete config; config = nullptr; } }
bool MultiInterventionDistributor::Distribute(IIndividualHumanInterventionsContext *context, ICampaignCostObserver * const pICCO ) { // ---------------------------------------------------------------------------------- // --- Putting this here because we don't want anything to happen if we are aborting // ---------------------------------------------------------------------------------- if( AbortDueToDisqualifyingInterventionStatus( context->GetParent() ) ) { return false; } // Important: Use the instance method to obtain the intervention factory obj instead of static method to cross the DLL boundary IGlobalContext *pGC = nullptr; const IInterventionFactory* ifobj = nullptr; release_assert(context->GetParent()); if (s_OK == context->GetParent()->QueryInterface(GET_IID(IGlobalContext), (void**)&pGC)) { ifobj = pGC->GetInterventionFactory(); } if (!ifobj) { throw GeneralConfigurationException( __FILE__, __LINE__, __FUNCTION__, "The pointer to IInterventionFactory object is not valid (could be DLL specific)" ); } try { // Parse intervention_list const json::Array & interventions_array = json::QuickInterpreter(intervention_list._json).As<json::Array>(); LOG_DEBUG_F("interventions array size = %d\n", interventions_array.Size()); for( int idx=0; idx<interventions_array.Size(); idx++ ) { const json::Object& actualIntervention = json_cast<const json::Object&>(interventions_array[idx]); Configuration * tmpConfig = Configuration::CopyFromElement( actualIntervention, "campaign" ); assert( tmpConfig ); // Instantiate and distribute interventions LOG_DEBUG_F( "Attempting to instantiate intervention of class %s\n", std::string((*tmpConfig)["class"].As<json::String>()).c_str() ); IDistributableIntervention *di = const_cast<IInterventionFactory*>(ifobj)->CreateIntervention(tmpConfig); if (di) { if (!di->Distribute( context, pICCO ) ) { di->Release(); } } else { INodeDistributableIntervention* ndi = const_cast<IInterventionFactory*>(ifobj)->CreateNDIIntervention( tmpConfig ); release_assert(ndi); if( !ndi->Distribute( context->GetParent()->GetEventContext()->GetNodeEventContext(), nullptr ) ) { ndi->Release(); } } delete tmpConfig; tmpConfig = nullptr; } } catch(json::Exception &e) { // ERROR: ::cerr << "exception casting intervention_config to array! " << e.what() << std::endl; throw GeneralConfigurationException( __FILE__, __LINE__, __FUNCTION__, e.what() ); // ( "Intervention_List json problem: intervention_list is valid json but needs to be an array." ); } // Nothing more for this class to do... Expire(); return true; }