2012-03-07 18:23:41 +00:00
|
|
|
(* Copyright 2012 Tony Garnock-Jones <tonygarnockjones@gmail.com>. *)
|
|
|
|
|
2012-05-01 21:36:38 +00:00
|
|
|
(* This file is part of Hop. *)
|
2012-03-07 18:23:41 +00:00
|
|
|
|
2012-05-01 21:36:38 +00:00
|
|
|
(* Hop is free software: you can redistribute it and/or modify it *)
|
2012-03-07 18:23:41 +00:00
|
|
|
(* under the terms of the GNU General Public License as published by the *)
|
|
|
|
(* Free Software Foundation, either version 3 of the License, or (at your *)
|
|
|
|
(* option) any later version. *)
|
|
|
|
|
2012-05-01 21:36:38 +00:00
|
|
|
(* Hop is distributed in the hope that it will be useful, but *)
|
2012-03-07 18:23:41 +00:00
|
|
|
(* WITHOUT ANY WARRANTY; without even the implied warranty of *)
|
|
|
|
(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *)
|
|
|
|
(* General Public License for more details. *)
|
|
|
|
|
|
|
|
(* You should have received a copy of the GNU General Public License *)
|
2012-05-01 21:36:38 +00:00
|
|
|
(* along with Hop. If not, see <http://www.gnu.org/licenses/>. *)
|
2012-03-07 18:23:41 +00:00
|
|
|
|
2012-01-08 17:41:04 +00:00
|
|
|
open Printf
|
|
|
|
open Sexp
|
|
|
|
open Datastructures
|
|
|
|
|
2012-03-04 17:12:20 +00:00
|
|
|
type factory_t = Sexp.t -> (Sexp.t, Sexp.t) Status.t
|
2012-01-08 17:41:04 +00:00
|
|
|
|
2012-03-06 22:30:39 +00:00
|
|
|
let mutex = Mutex.create ()
|
2012-01-08 17:41:04 +00:00
|
|
|
let classes = ref StringMap.empty
|
|
|
|
|
|
|
|
let register_class name factory =
|
2012-03-06 22:30:39 +00:00
|
|
|
Util.with_mutex0 mutex
|
|
|
|
(fun () ->
|
|
|
|
if StringMap.mem name !classes
|
|
|
|
then (Log.error "Duplicate node class name" [Str name];
|
|
|
|
exit 1)
|
|
|
|
else (Log.info "Registered node class" [Str name];
|
|
|
|
classes := StringMap.add name factory !classes))
|
2012-01-08 17:41:04 +00:00
|
|
|
|
2012-04-29 23:41:28 +00:00
|
|
|
let all_class_names () =
|
|
|
|
Datastructures.string_map_keys !classes
|
|
|
|
|
2012-01-08 17:41:04 +00:00
|
|
|
let lookup_class name =
|
|
|
|
try Some (StringMap.find name !classes)
|
|
|
|
with Not_found -> None
|
|
|
|
|
|
|
|
let factory_handler n sexp =
|
|
|
|
match Message.message_of_sexp sexp with
|
|
|
|
| Message.Create (Str classname, arg, Str reply_sink, Str reply_name) ->
|
2012-03-05 21:55:14 +00:00
|
|
|
let reply =
|
|
|
|
match lookup_class classname with
|
|
|
|
| Some factory ->
|
|
|
|
(match factory arg with
|
2012-03-04 17:12:20 +00:00
|
|
|
| Status.Ok info ->
|
2012-03-05 21:55:14 +00:00
|
|
|
Log.info "Node create ok"
|
|
|
|
[Str classname; arg; Str reply_sink; Str reply_name; info];
|
2012-03-04 17:12:20 +00:00
|
|
|
Message.create_ok info
|
|
|
|
| Status.Problem explanation ->
|
2012-03-05 21:55:14 +00:00
|
|
|
Log.info "Node create failed"
|
|
|
|
[Str classname; arg; Str reply_sink; Str reply_name; explanation];
|
|
|
|
Message.create_failed (Arr [Str "constructor"; explanation]))
|
|
|
|
| None ->
|
|
|
|
Log.warn "Node class not found" [Str classname];
|
|
|
|
Message.create_failed (Arr [Str "factory"; Str "class-not-found"])
|
|
|
|
in
|
|
|
|
Node.post_ignore reply_sink (Str reply_name) reply (Str "")
|
2012-01-08 17:41:04 +00:00
|
|
|
| m ->
|
|
|
|
Util.message_not_understood "factory" m
|
|
|
|
|
|
|
|
let init () =
|
|
|
|
Node.bind_ignore ("factory", Node.make "factory" factory_handler)
|