<< 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}})
$