diff --git a/inst/include/ergm_dyadgen.h b/inst/include/ergm_dyadgen.h index 3e50a4c6b..bd44082fa 100644 --- a/inst/include/ergm_dyadgen.h +++ b/inst/include/ergm_dyadgen.h @@ -47,8 +47,8 @@ DyadGen *DyadGenInitialize(DyadGenType type, void *dyads, void *track_nwp); DyadGen *DyadGenInitializeR(SEXP pR, void *any_nwp, Rboolean el); void DyadGenDestroy(DyadGen *gen); -void DyadGenUpdate(Vertex tail, Vertex head, DyadGen *gen, Network *nwp, Rboolean edgestate); -void WtDyadGenUpdate(Vertex tail, Vertex head, double weight, DyadGen *gen, WtNetwork *nwp, double edgestate); +void DyadGenUpdate(Vertex tail, Vertex head, void *gen, Network *nwp, Rboolean edgestate); +void WtDyadGenUpdate(Vertex tail, Vertex head, double weight, void *gen, WtNetwork *nwp, double edgestate); static inline void DyadGenRandDyad(Vertex *tail, Vertex *head, DyadGen *gen){ switch(gen->type){ diff --git a/inst/include/ergm_stubs.c b/inst/include/ergm_stubs.c index ed63fd9e4..dfd02c666 100644 --- a/inst/include/ergm_stubs.c +++ b/inst/include/ergm_stubs.c @@ -67,14 +67,14 @@ static void (*fun)(DyadGen *) = NULL; if(fun==NULL) fun = (void (*)(DyadGen *)) R_FindSymbol("DyadGenDestroy", "ergm", NULL); fun(gen); } -void DyadGenUpdate(Vertex tail, Vertex head, DyadGen *gen, Network *nwp, Rboolean edgestate){ -static void (*fun)(Vertex,Vertex,DyadGen *,Network *,Rboolean) = NULL; -if(fun==NULL) fun = (void (*)(Vertex,Vertex,DyadGen *,Network *,Rboolean)) R_FindSymbol("DyadGenUpdate", "ergm", NULL); +void DyadGenUpdate(Vertex tail, Vertex head, void *gen, Network *nwp, Rboolean edgestate){ +static void (*fun)(Vertex,Vertex,void *,Network *,Rboolean) = NULL; +if(fun==NULL) fun = (void (*)(Vertex,Vertex,void *,Network *,Rboolean)) R_FindSymbol("DyadGenUpdate", "ergm", NULL); fun(tail,head,gen,nwp,edgestate); } -void WtDyadGenUpdate(Vertex tail, Vertex head, double weight, DyadGen *gen, WtNetwork *nwp, double edgestate){ -static void (*fun)(Vertex,Vertex,double,DyadGen *,WtNetwork *,double) = NULL; -if(fun==NULL) fun = (void (*)(Vertex,Vertex,double,DyadGen *,WtNetwork *,double)) R_FindSymbol("WtDyadGenUpdate", "ergm", NULL); +void WtDyadGenUpdate(Vertex tail, Vertex head, double weight, void *gen, WtNetwork *nwp, double edgestate){ +static void (*fun)(Vertex,Vertex,double,void *,WtNetwork *,double) = NULL; +if(fun==NULL) fun = (void (*)(Vertex,Vertex,double,void *,WtNetwork *,double)) R_FindSymbol("WtDyadGenUpdate", "ergm", NULL); fun(tail,head,weight,gen,nwp,edgestate); } diff --git a/src/MHproposal.c b/src/MHproposal.c index 92ade9cb8..a81506d64 100644 --- a/src/MHproposal.c +++ b/src/MHproposal.c @@ -11,6 +11,10 @@ #include "ergm_changestat.h" #include "ergm_Rutil.h" +void OnNetworkEdgeChangeMUWrap(Vertex tail, Vertex head, void *MHp, Network *nwp, Rboolean edgestate){ + ((MHProposal *) MHp)->u_func(tail, head, MHp, nwp, edgestate); +} + /********************* void MHProposalInitialize @@ -91,7 +95,7 @@ MHProposal *MHProposalInitialize(SEXP pR, Network *nwp, void **aux_storage){ MHp->togglehead = (Vertex *)R_Calloc(MHp->ntoggles, Vertex); if(MHp->u_func){ - AddOnNetworkEdgeChange(nwp, (OnNetworkEdgeChange) MHp->u_func, MHp, 0); // Need to insert at the start. + AddOnNetworkEdgeChange(nwp, OnNetworkEdgeChangeMUWrap, MHp, 0); // Need to insert at the start. } return MHp; @@ -104,7 +108,7 @@ MHProposal *MHProposalInitialize(SEXP pR, Network *nwp, void **aux_storage){ *********************/ void MHProposalDestroy(MHProposal *MHp, Network *nwp){ if(!MHp) return; - if(MHp->u_func) DeleteOnNetworkEdgeChange(nwp, (OnNetworkEdgeChange) MHp->u_func, MHp); + if(MHp->u_func) DeleteOnNetworkEdgeChange(nwp, OnNetworkEdgeChangeMUWrap, MHp); if(MHp->f_func) (*(MHp->f_func))(MHp, nwp); if(MHp->storage){ R_Free(MHp->storage); diff --git a/src/ergm_dyadgen.c b/src/ergm_dyadgen.c index 1b873079f..9cde2cf39 100644 --- a/src/ergm_dyadgen.c +++ b/src/ergm_dyadgen.c @@ -173,7 +173,8 @@ void DyadGenDestroy(DyadGen *gen){ } -void DyadGenUpdate(Vertex tail, Vertex head, DyadGen *gen, Network *nwp, Rboolean edgestate){ +void DyadGenUpdate(Vertex tail, Vertex head, void *payload, Network *nwp, Rboolean edgestate){ + DyadGen *gen = payload; if(gen->sleeping) return; switch(gen->intertype){ @@ -193,7 +194,8 @@ void DyadGenUpdate(Vertex tail, Vertex head, DyadGen *gen, Network *nwp, Rboolea } -void WtDyadGenUpdate(Vertex tail, Vertex head, double weight, DyadGen *gen, WtNetwork *nwp, double edgestate){ +void WtDyadGenUpdate(Vertex tail, Vertex head, double weight, void *payload, WtNetwork *nwp, double edgestate){ + DyadGen *gen = payload; if(gen->sleeping) return; switch(gen->intertype){ diff --git a/src/model.c b/src/model.c index 084dc6fab..05f26cc3a 100644 --- a/src/model.c +++ b/src/model.c @@ -12,6 +12,10 @@ #include "ergm_omp.h" #include "ergm_util.h" +void OnNetworkEdgeChangeUWrap(Vertex tail, Vertex head, void *mtp, Network *nwp, Rboolean edgestate){ + ((ModelTerm *) mtp)->u_func(tail, head, mtp, nwp, edgestate); +} + /* InitStats A helper's helper function to initialize storage for functions that use it. @@ -56,7 +60,7 @@ static inline void InitStats(Network *nwp, Model *m){ } // Now, bind the term to the network through the callback API. if(mtp->u_func && (!m->noinit_s || !mtp->s_func)) // Skip if noinit_s is set and s_func is present. - AddOnNetworkEdgeChange(nwp, (OnNetworkEdgeChange) mtp->u_func, mtp, on_edge_change_pos); + AddOnNetworkEdgeChange(nwp, OnNetworkEdgeChangeUWrap, mtp, on_edge_change_pos); }); } @@ -69,7 +73,7 @@ static inline void DestroyStats(Network *nwp, Model *m){ EXEC_THROUGH_TERMS(m, { if(!m->noinit_s || !mtp->s_func){ // Skip if noinit_s is set and s_func is present. if(mtp->u_func) - DeleteOnNetworkEdgeChange(nwp, (OnNetworkEdgeChange) mtp->u_func, mtp); + DeleteOnNetworkEdgeChange(nwp, OnNetworkEdgeChangeUWrap, mtp); if(mtp->f_func) (*(mtp->f_func))(mtp, nwp); /* Call f_??? function */ } diff --git a/src/wtMHproposal.c b/src/wtMHproposal.c index 1222c6d05..b2d95f8d3 100644 --- a/src/wtMHproposal.c +++ b/src/wtMHproposal.c @@ -10,6 +10,10 @@ #include "ergm_wtMHproposal.h" #include "ergm_Rutil.h" +void OnWtNetworkEdgeChangeMUWrap(Vertex tail, Vertex head, double weight, void *MHp, WtNetwork *nwp, double edgestate){ + ((WtMHProposal *) MHp)->u_func(tail, head, weight, MHp, nwp, edgestate); +} + /********************* void WtMHProposalInitialize @@ -92,7 +96,7 @@ WtMHProposal *WtMHProposalInitialize(SEXP pR, WtNetwork *nwp, void **aux_storage MHp->toggleweight = (double *)R_Calloc(MHp->ntoggles, double); if(MHp->u_func){ - AddOnWtNetworkEdgeChange(nwp, (OnWtNetworkEdgeChange) MHp->u_func, MHp, 0); // Need to insert at the start. + AddOnWtNetworkEdgeChange(nwp, OnWtNetworkEdgeChangeMUWrap, MHp, 0); // Need to insert at the start. } return MHp; @@ -105,7 +109,7 @@ WtMHProposal *WtMHProposalInitialize(SEXP pR, WtNetwork *nwp, void **aux_storage *********************/ void WtMHProposalDestroy(WtMHProposal *MHp, WtNetwork *nwp){ if(!MHp) return; - if(MHp->u_func) DeleteOnWtNetworkEdgeChange(nwp, (OnWtNetworkEdgeChange) MHp->u_func, MHp); + if(MHp->u_func) DeleteOnWtNetworkEdgeChange(nwp, OnWtNetworkEdgeChangeMUWrap, MHp); if(MHp->f_func) (*(MHp->f_func))(MHp, nwp); if(MHp->storage){ R_Free(MHp->storage); diff --git a/src/wtmodel.c b/src/wtmodel.c index 47c6ddb74..6cbef370d 100644 --- a/src/wtmodel.c +++ b/src/wtmodel.c @@ -12,6 +12,10 @@ #include "ergm_omp.h" #include "ergm_util.h" +void OnWtNetworkEdgeChangeUWrap(Vertex tail, Vertex head, double weight, void *mtp, WtNetwork *nwp, double edgestate){ + ((WtModelTerm *) mtp)->u_func(tail, head, weight, mtp, nwp, edgestate); +} + /* WtInitStats A helper's helper function to initialize storage for functions that use it. @@ -56,7 +60,7 @@ static inline void WtInitStats(WtNetwork *nwp, WtModel *m){ } // Now, bind the term to the network through the callback API. if(mtp->u_func && (!m->noinit_s || !mtp->s_func)) // Skip if noinit_s is set and s_func is present. - AddOnWtNetworkEdgeChange(nwp, (OnWtNetworkEdgeChange) mtp->u_func, mtp, on_edge_change_pos); + AddOnWtNetworkEdgeChange(nwp, OnWtNetworkEdgeChangeUWrap, mtp, on_edge_change_pos); }); } @@ -69,7 +73,7 @@ static inline void WtDestroyStats(WtNetwork *nwp, WtModel *m){ WtEXEC_THROUGH_TERMS(m, { if(!m->noinit_s || !mtp->s_func){ // Skip if noinit_s is set and s_func is present. if(mtp->u_func) - DeleteOnWtNetworkEdgeChange(nwp, (OnWtNetworkEdgeChange) mtp->u_func, mtp); + DeleteOnWtNetworkEdgeChange(nwp, OnWtNetworkEdgeChangeUWrap, mtp); if(mtp->f_func) (*(mtp->f_func))(mtp, nwp); /* Call f_??? function */ }