Registration Example

<< Click to Display Table of Contents >>

Navigation:  Connectors > Smallworld > Routine Calls >

Registration Example

 

_package user

 

##############################

## Count underground routes ##

##############################

 

# Here's our mockup procedure

 

_global !count_all_underground_routes! <<

 _proc @!count_all_underground_routes!()

         _local v << gis_program_manager.cached_dataset(:gis)

         _return v.collection(:underground_route).size

 _endproc

$

 

# This procedure can be registered directly, since it only uses a predefined type

 

dts_manager.register_api_call("count_all_underground_routes", "user:!count_all_underground_routes!",

                       {},

                       {

                               {dts:dts_type_mapping.uint32}

                       })

$

 

###################################

## Get routes in the given area  ##

###################################

 

# Another one - a bit more complex

 

_global !get_uroute_ids_in_area! <<

 _proc @!get_uroute_ids_in_area!(p_area, p_max_size)

         _local v << gis_program_manager.cached_dataset(:gis)

         _local l_area << _if p_area.is_class_of?(dts:dts_area)

                          _then >> pseudo_area.new_for_world(p_area.as_pseudo_area(), v.world)

                          _else >> pseudo_area.new_for_world(p_area, v.world)

                          _endif

         _local rts << v.collection(:underground_route).select(predicate.within(:route, l_area))

         _local rt_ids << rope.new()

         _local idx << 1

         _for rt _over rts.fast_elements()

         _loop

                 _if idx > p_max_size _then _leave _endif

                 rt_ids.add(rt.id)

                 idx +<< 1

         _endloop

         _return rt_ids.as_simple_vector()

 _endproc

$

 

# This procedure also used only predefined types, but has arguments and returns an array

 

dts_manager.register_api_call("get_uroute_ids_in_area", "user:!get_uroute_ids_in_area!",

     {

             {dts:dts_area.dts_type_key},

             {dts:dts_type_mapping.uint32}

     },

     {

             {dts:dts_type_mapping.uint32, :vector?, _true}

     })

$

 

#########################################

## Get details about underground route ##

#########################################

 

# For this one, we'll need some custom objects, which we define here:

 

def_slotted_exemplar(:cable_info,

 {

         {:id, _unset, :writable, :public},

         {:name, _unset, :writable, :public},

         {:kind, _unset, :writable, :public},

         {:length, _unset, :writable, :public}

 })

$

 

_method cable_info.new()

 _return _clone.init()

_endmethod

$

 

_private _method cable_info.init()

 _return _self

_endmethod

$

 

def_slotted_exemplar(:uroute_info,

 {

         {:uroute_record, _unset, :writable, :public},

         {:cable_infos, _unset, :writable, :public}

 })

$

 

_method uroute_info.new()

 _return _clone.init()

_endmethod

$

 

_private _method uroute_info.init()

 _return _self

_endmethod

$

 

# And here is the procedure

 

_global !get_uroute_details! <<

 _proc @!get_uroute_details!(p_id)

         _local v << gis_program_manager.cached_dataset(:gis)

         

         _local uroute << v.collection(:underground_route).at(p_id)

         

         _local response << uroute_info.new()

         response.uroute_record << uroute

         

         _local cbls << rope.new()

         _for c _over uroute.mit_structure_route.mit_cables.fast_elements()

         _loop

                 _local cbl << cable_info.new()

                 _if c.copper_cable _isnt _unset

                 _then

                         cbl.id << c.copper_cable.id

                         cbl.name << c.copper_cable.name.write_string

                         cbl.kind << "copper"

                         cbl.length << c.copper_cable.calculated_length.as_float

                 _elif c.sheath_with_loc _isnt _unset

                 _then

                         cbl.id << c.sheath_with_loc.id

                         cbl.name << c.sheath_with_loc.name.write_string

                         cbl.kind << "fiber"

                         cbl.length << c.sheath_with_loc.calculated_fiber_length.as_float

                 _else

                         cbl.id << c.id

                         cbl.name << "uninteresting cable"

                         cbl.kind << "irrelevant"

                         cbl.length << _unset

                 _endif

                 cbls.add_last(cbl)

         _endloop

         response.cable_infos << cbls.as_simple_vector()

         _return response

 _endproc

$

 

# First, we register a DS type for :underground_route with the fields we're interested in

 

dts_manager.register_ds_type("dts_uroute", gis_program_manager.cached_dataset(:gis).collection(:underground_route),

     {

             "id",

             "construction_status",

             "underground_route_type",

             "route"

     })

$

 

# Then, we register slotted exemplar types for our cable_info and uroute_info exemplars

# Note how uroute_info refers to cable_info. The referrer always must come after the referred!

 

dts_manager.register_type("cable_info", cable_info,

     {

             {"id", dts:dts_type_mapping.uint32},

             {"name", dts:dts_type_mapping.string},

             {"kind", dts:dts_type_mapping.string},

             {"length", dts:dts_type_mapping.float}

     })

$

 

dts_manager.register_type("uroute_info", uroute_info,

     {

             {"uroute_record", "dts_uroute"},

             {"cable_infos", "cable_info", :vector?, _true}

     })

$

 

# Finally, we can register the routine

 

dts_manager.register_api_call("get_uroute_details", "user:!get_uroute_details!",

                       {

                               {dts:dts_type_mapping.uint32}

                       },

                       {

                               {"uroute_info"}

                       }

     )

$

 

############

## Method ##

############

 

# To have a method to call, we need a singleton exemplar

 

def_slotted_exemplar(:test_singleton, {})

$

 

 

# And a test method

 

_method test_singleton.test_multi(p_string, p_int)

 _return (p_string, p_int, 0.003)

_endmethod

$

 

 

# Here's how we register it

# Notice that we populated to options in order to tell the connector that it's a method and what the target exemplar is

 

dts_manager.register_api_call("test_singleton.test_multi", "test_multi()",

                       {{dts:dts_type_mapping.string}, {dts:dts_type_mapping.uint32}},

                       {{dts:dts_type_mapping.string}, {dts:dts_type_mapping.uint32}, {dts:dts_type_mapping.double}},

                       property_list.new_with(:procedure?, _false, :target, "user:test_singleton"))

$

 

#######################

## Streaming Routine ##

#######################

 

# First, we need an exemplar for the stream elements

 

def_slotted_exemplar(:test_item,

 {

         {:part1, _unset, :writable, :public},

         {:part2, _unset, :writable, :public}

 }, {})

$

 

_method test_item.new(a_string, an_int)

 _return _clone.init(a_string, an_int)

_endmethod

$

 

_private _method test_item.init(a_string, an_int)

 .part1 << a_string

 .part2 << an_int

 _return _self

_endmethod

$

 

# We register the type with DTS

 

dts_manager.register_type("test_item", test_item,

                   {{"part1", dts:dts_type_mapping.string}, 

                         {"part2", dts:dts_type_mapping.int32}})

$

 

# Here is our procedure that returns a stream of test_items

 

_global !streamy_fun_test! <<

_proc @!streamy_fun_test!(p_size)

 _local v << rope.new()

 _for i _over 1.upto(p_size)

 _loop

         v.add(test_item.new(write_string(i), i))

 _endloop

 _return dts:dts_record_stream.new_for_vector(v)

_endproc

$

 

# And finally we register the procedure with DTS

 

dts_manager.register_api_call("streamy_fun_test", "user:!streamy_fun_test!",

                       {{dts:dts_type_mapping.int32}},

                       {{"test_item", :stream?, _true}})

$