Last active
December 20, 2015 02:43
-
-
Save ryandoyle/21ce3cc661a36f22f10f to your computer and use it in GitHub Desktop.
Nested Data_Wrap_Struct
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
static VALUE rb_pmLookupDesc(VALUE self, VALUE pmid) { | |
pmDesc *pm_desc; | |
pm_desc = ALLOC(pmDesc); | |
pmLookupDesc(NUM2UINT(pmid), pm_desc)) | |
return rb_pmapi_pmdesc_new(pm_desc); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
typedef struct pmUnits { | |
unsigned int pad : 8; | |
signed int scaleCount : 4; /* one of PM_COUNT_* below */ | |
unsigned int scaleTime : 4; /* one of PM_TIME_* below */ | |
unsigned int scaleSpace : 4; /* one of PM_SPACE_* below */ | |
signed int dimCount : 4; /* event dimension */ | |
signed int dimTime : 4; /* time dimension */ | |
signed int dimSpace : 4; /* space dimension */ | |
} pmUnits; | |
typedef struct pmDesc { | |
pmID pmid; /* unique identifier */ | |
int type; /* base data type (see below) */ | |
pmInDom indom; /* instance domain */ | |
int sem; /* semantics of value (see below) */ | |
pmUnits units; /* dimension and units */ | |
} pmDesc; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
static VALUE rb_pmapi_pmdesc_pmunits(VALUE self) { | |
pmUnits *pm_units = &rb_pmapi_pmdesc_ptr(self)->units; | |
return rb_pmapi_pmunits_new(pm_units); | |
} | |
/* This is only ever called when pmDesc is created via native Ruby. | |
Because we are only memcpy()ing the data, back, it is possible for the | |
pmUnits class to get out of sync with the underlying pmDesc struct */ | |
static VALUE rb_pmapi_pmdesc_pmunits_set(VALUE self, VALUE pm_units) { | |
pmUnits *pm_units_from_pmUnits_class = rb_pmapi_pmunits_get(pm_units); | |
memcpy(&rb_pmapi_pmdesc_ptr(self)->units, pm_units_from_pmUnits_class, sizeof(pmUnits)); | |
return Qnil; | |
} | |
VALUE rb_pmapi_pmdesc_new(pmDesc *pm_desc) { | |
return Data_Wrap_Struct(pcp_pmapi_pmdesc_class, 0, rb_pmapi_pmdesc_free, pm_desc); | |
} | |
void init_rb_pmapi_pmdesc(VALUE pmapi_class) { | |
... | |
rb_define_method(pcp_pmapi_pmdesc_class, "units", rb_pmapi_pmdesc_pmunits, 0); | |
rb_define_private_method(pcp_pmapi_pmdesc_class, "units=", rb_pmapi_pmdesc_pmunits_set, 1); | |
... | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Allocation via this function requires that the callee is the one that frees pmUnits. | |
* When this object is created in Ruby code, it allocates and cleans up appropriately. | |
* When constructed here, its done so by the pmDesc class and its manages the freeing */ | |
VALUE rb_pmapi_pmunits_new(pmUnits *pm_units) { | |
return Data_Wrap_Struct(pcp_pmapi_pmunits_class, 0, 0, pm_units); | |
} | |
static pmUnits* rb_pmapi_pmunits_ptr(VALUE self) { | |
pmUnits *pm_units; | |
Data_Get_Struct(self, pmUnits, pm_units); | |
return pm_units; | |
} | |
pmUnits *rb_pmapi_pmunits_get(VALUE self) { | |
return rb_pmapi_pmunits_ptr(self); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'pcp/pmapi' | |
module PCP | |
class PMAPI | |
class PmDesc | |
def initialize(pmid, type, indom, sem, units) | |
self.pmid = pmid | |
self.type = type | |
self.indom = indom | |
self.sem = sem | |
raise ::TypeError, "#{units.class} are invalid units. Must be of type PCP::PMAPI::PmUnits" unless units.is_a?(PCP::PMAPI::PmUnits) | |
self.units = units | |
end | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment