33#include " physicslab.h"
44
55#include < cstring>
6+ #include < new>
67#include < string>
78
89// Minimal C API for embedding / wasm bindings.
@@ -13,10 +14,12 @@ namespace phy_engine::phy_lab_wrapper::c_api::detail
1314inline thread_local std::string last_error;
1415
1516inline void set_error (std::string msg) { last_error = std::move (msg); }
17+ inline void clear_error () noexcept { last_error.clear (); }
1618
1719inline char * dup_cstr (std::string const & s)
1820{
19- auto * out = new char [s.size () + 1 ];
21+ auto * out = new (std::nothrow) char [s.size () + 1 ];
22+ if (out == nullptr ) { return nullptr ; }
2023 std::memcpy (out, s.data (), s.size ());
2124 out[s.size ()] = ' \0 ' ;
2225 return out;
@@ -37,44 +40,39 @@ inline void plw_string_free(char* s) { delete[] s; }
3740inline plw_experiment_t plw_experiment_create (int type_value)
3841{
3942 using namespace phy_engine ::phy_lab_wrapper;
40- try
43+ c_api::detail::clear_error ();
44+ auto type = static_cast <experiment_type>(type_value);
45+ auto * ex = new (std::nothrow) experiment (experiment::create (type));
46+ if (ex == nullptr )
4147 {
42- auto type = static_cast <experiment_type>(type_value);
43- return new experiment (experiment::create (type));
44- }
45- catch (std::exception const & e)
46- {
47- c_api::detail::set_error (e.what ());
48- return nullptr ;
49- }
50- catch (...)
51- {
52- c_api::detail::set_error (" unknown error" );
48+ c_api::detail::set_error (" out of memory" );
5349 return nullptr ;
5450 }
51+ return ex;
5552}
5653
5754inline plw_experiment_t plw_experiment_load_from_string (char const * sav_json)
5855{
5956 using namespace phy_engine ::phy_lab_wrapper;
60- try
57+ c_api::detail::clear_error ();
58+ if (sav_json == nullptr )
6159 {
62- if (sav_json == nullptr )
63- {
64- throw std::invalid_argument (" sav_json is null" );
65- }
66- return new experiment (experiment::load_from_string (sav_json));
60+ c_api::detail::set_error (" sav_json is null" );
61+ return nullptr ;
6762 }
68- catch (std::exception const & e)
63+ auto r = experiment::load_from_string_ec (sav_json);
64+ if (!r)
6965 {
70- c_api::detail::set_error (e. what () );
66+ c_api::detail::set_error (r. st . message );
7167 return nullptr ;
7268 }
73- catch (...)
69+ auto * ex = new (std::nothrow) experiment (std::move (*r.value ));
70+ if (ex == nullptr )
7471 {
75- c_api::detail::set_error (" unknown error " );
72+ c_api::detail::set_error (" out of memory " );
7673 return nullptr ;
7774 }
75+ return ex;
7876}
7977
8078inline void plw_experiment_destroy (plw_experiment_t handle)
@@ -86,25 +84,26 @@ inline void plw_experiment_destroy(plw_experiment_t handle)
8684inline char * plw_experiment_dump (plw_experiment_t handle, int indent)
8785{
8886 using namespace phy_engine ::phy_lab_wrapper;
89- try
87+ c_api::detail::clear_error ();
88+ auto * ex = static_cast <experiment*>(handle);
89+ if (ex == nullptr )
9090 {
91- auto * ex = static_cast <experiment*>(handle);
92- if (ex == nullptr )
93- {
94- throw std::invalid_argument (" experiment handle is null" );
95- }
96- return c_api::detail::dup_cstr (ex->dump (indent));
91+ c_api::detail::set_error (" experiment handle is null" );
92+ return nullptr ;
9793 }
98- catch (std::exception const & e)
94+ auto r = ex->dump_ec (indent);
95+ if (!r)
9996 {
100- c_api::detail::set_error (e. what () );
97+ c_api::detail::set_error (r. st . message );
10198 return nullptr ;
10299 }
103- catch (...)
100+ auto * out = c_api::detail::dup_cstr (*r.value );
101+ if (out == nullptr )
104102 {
105- c_api::detail::set_error (" unknown error " );
103+ c_api::detail::set_error (" out of memory " );
106104 return nullptr ;
107105 }
106+ return out;
108107}
109108
110109inline char * plw_experiment_add_circuit_element (plw_experiment_t handle,
@@ -115,30 +114,31 @@ inline char* plw_experiment_add_circuit_element(plw_experiment_t handle,
115114 int element_xyz_coords)
116115{
117116 using namespace phy_engine ::phy_lab_wrapper;
118- try
117+ c_api::detail::clear_error ();
118+ auto * ex = static_cast <experiment*>(handle);
119+ if (ex == nullptr )
119120 {
120- auto * ex = static_cast <experiment*>(handle);
121- if (ex == nullptr )
122- {
123- throw std::invalid_argument (" experiment handle is null" );
124- }
125- if (model_id == nullptr )
126- {
127- throw std::invalid_argument (" model_id is null" );
128- }
129- auto id = ex->add_circuit_element (model_id, position{x, y, z}, element_xyz_coords != 0 );
130- return c_api::detail::dup_cstr (id);
121+ c_api::detail::set_error (" experiment handle is null" );
122+ return nullptr ;
123+ }
124+ if (model_id == nullptr )
125+ {
126+ c_api::detail::set_error (" model_id is null" );
127+ return nullptr ;
131128 }
132- catch (std::exception const & e)
129+ auto id_r = ex->add_circuit_element_ec (model_id, position{x, y, z}, element_xyz_coords != 0 );
130+ if (!id_r)
133131 {
134- c_api::detail::set_error (e. what () );
132+ c_api::detail::set_error (id_r. st . message );
135133 return nullptr ;
136134 }
137- catch (...)
135+ auto * out = c_api::detail::dup_cstr (*id_r.value );
136+ if (out == nullptr )
138137 {
139- c_api::detail::set_error (" unknown error " );
138+ c_api::detail::set_error (" out of memory " );
140139 return nullptr ;
141140 }
141+ return out;
142142}
143143
144144inline int plw_experiment_connect (plw_experiment_t handle,
@@ -149,31 +149,25 @@ inline int plw_experiment_connect(plw_experiment_t handle,
149149 int color_value)
150150{
151151 using namespace phy_engine ::phy_lab_wrapper;
152- try
152+ c_api::detail::clear_error ();
153+ auto * ex = static_cast <experiment*>(handle);
154+ if (ex == nullptr )
153155 {
154- auto * ex = static_cast <experiment*>(handle);
155- if (ex == nullptr )
156- {
157- throw std::invalid_argument (" experiment handle is null" );
158- }
159- if (src_id == nullptr || dst_id == nullptr )
160- {
161- throw std::invalid_argument (" src_id/dst_id is null" );
162- }
163- ex->connect (src_id, src_pin, dst_id, dst_pin, static_cast <wire_color>(color_value));
164- return 0 ;
156+ c_api::detail::set_error (" experiment handle is null" );
157+ return 1 ;
165158 }
166- catch (std::exception const & e )
159+ if (src_id == nullptr || dst_id == nullptr )
167160 {
168- c_api::detail::set_error (e. what () );
161+ c_api::detail::set_error (" src_id/dst_id is null " );
169162 return 1 ;
170163 }
171- catch (...)
164+ auto st = ex->connect_ec (src_id, src_pin, dst_id, dst_pin, static_cast <wire_color>(color_value));
165+ if (!st)
172166 {
173- c_api::detail::set_error (" unknown error " );
167+ c_api::detail::set_error (st. message );
174168 return 1 ;
175169 }
170+ return 0 ;
176171}
177172
178173} // extern "C"
179-
0 commit comments