adam.hpp
Go to the documentation of this file.
00001 /* 00002 Copyright 2005-2008 Adobe Systems Incorporated 00003 Distributed under the MIT License (see accompanying file LICENSE_1_0_0.txt 00004 or a copy at http://stlab.adobe.com/licenses.html) 00005 */ 00006 00007 /*************************************************************************************************/ 00008 00009 #ifndef ADOBE_ADAM_HPP 00010 #define ADOBE_ADAM_HPP 00011 00012 #include <adobe/config.hpp> 00013 00014 #include <functional> 00015 00016 #include <boost/utility.hpp> 00017 #include <boost/function.hpp> 00018 00019 #ifdef __MWERKS__ 00020 #pragma warn_unusedarg off 00021 #pragma warn_unusedvar off 00022 #endif 00023 00024 #include <boost/signals.hpp> 00025 00026 #ifdef __MWERKS__ 00027 #pragma warn_unusedarg reset 00028 #pragma warn_unusedvar reset 00029 #endif 00030 00031 #include <adobe/any_regular_fwd.hpp> 00032 #include <adobe/array.hpp> 00033 #include <adobe/dictionary_fwd.hpp> 00034 #include <adobe/istream.hpp> 00035 #include <adobe/move.hpp> 00036 #include <adobe/name_fwd.hpp> 00037 #include <adobe/vector.hpp> 00038 #include <adobe/virtual_machine.hpp> 00039 00040 /* 00041 00042 REVISIT (sparent) : It would be best to detangle the sheet from 00043 the virtual machine. The way to do this is to allow for funciton 00044 objects to be passed instead of line positions and expression 00045 arrays. The function object could bind to the line_position_t and 00046 the array.... This would allow for easier programatic driving - 00047 however, one would have to construct condition objects which 00048 tracked dependencies and the sheet would require a get() method to 00049 retrieve the value of a cell. 00050 00051 */ 00052 00053 /*************************************************************************************************/ 00054 00055 namespace adobe { 00056 00065 /*************************************************************************************************/ 00066 00073 class sheet_t : boost::noncopyable 00074 { 00075 public: 00076 struct relation_t; 00077 00078 typedef boost::function<void (bool)> monitor_invariant_t; 00079 typedef boost::function<void (const any_regular_t&)> monitor_value_t; 00080 typedef boost::function<void (const dictionary_t&)> monitor_contributing_t; 00081 typedef boost::function<void (bool)> monitor_enabled_t; 00082 00096 typedef boost::signals::connection connection_t; 00097 00098 #if !defined(ADOBE_NO_DOCUMENTATION) 00099 sheet_t(); 00100 ~sheet_t(); 00101 #endif 00102 00110 any_regular_t inspect(const array_t& expression); 00111 00118 void set(name_t cell, const any_regular_t& value); // input cell. 00119 00141 void touch(const name_t* first, const name_t* last); // range of input cells. 00142 00151 any_regular_t get(name_t cell); 00152 00164 void add_input (name_t name, const line_position_t& position, const array_t& initializer); 00165 00178 void add_output (name_t name, const line_position_t& position, const array_t& expression); 00179 00180 00194 void add_constant (name_t name, const line_position_t& position, const array_t& initializer); 00195 00196 00206 void add_constant(name_t name, any_regular_t value); 00207 00219 void add_logic (name_t name, const line_position_t& position, const array_t& expression); 00220 00232 void add_invariant (name_t name, const line_position_t& position, const array_t& expression); 00233 00254 void add_interface (name_t name, bool linked, const line_position_t& position1, 00255 const array_t& initializer, const line_position_t& position2, 00256 const array_t& expression); 00257 00269 void add_interface(name_t name, any_regular_t initial); 00270 00292 void add_relation(const line_position_t& position, const array_t& conditional, 00293 const relation_t* first, const relation_t* last); 00294 00295 00310 connection_t monitor_value(name_t name, const monitor_value_t& proc); 00311 00333 connection_t monitor_contributing(name_t cell, const dictionary_t& mark, 00334 const monitor_contributing_t& proc); 00335 // output only 00336 00389 connection_t monitor_enabled(name_t cell, const name_t* first, const name_t* last, 00390 const monitor_enabled_t& proc); // input only 00391 00392 #if 0 00393 connection_t monitor_invariant_contributing(name_t input, const monitor_invariant_t&); 00394 #endif 00395 00412 connection_t monitor_invariant_dependent(name_t output, const monitor_invariant_t& proc); 00413 00414 00425 bool has_input(name_t name) const; 00426 00437 bool has_output(name_t name) const; 00438 00449 std::size_t count_interface(name_t name) const 00450 { return has_input(name) && has_output(name); } 00451 00452 00460 void update(); 00461 00470 void reinitialize(); 00471 00472 00481 void set(const dictionary_t& dictionary); 00482 00483 #if 0 00484 dictionary_t current_mark() const; 00485 #endif 00486 00487 00495 dictionary_t contributing(const dictionary_t& mark) const; 00496 00503 dictionary_t contributing() const; 00504 00508 dictionary_t contributing_to_cell(name_t) const; 00509 00510 /* 00511 REVISIT (fbrereto) : From a note from sparent 2007/04/13: 00512 00513 "Make the adam VM public - eventually I'm going to pull it out all 00514 together (The property model library won't directly depend on it - 00515 only function object - which can be implemented with the VM)." 00516 00517 This solution is a bit hackish, but is a viable intermediary solution; 00518 because sheet_t and its underlying implementation are noncopyable, the 00519 machine can be stored here and held by reference by the implementation, 00520 and everything is fine. Nevertheless, this is an interim solution given 00521 Sean's plans for the VM's relationship to sheet_t in the future. 00522 */ 00523 virtual_machine_t machine_m; 00524 00525 private: 00526 class implementation_t; 00527 implementation_t* object_m; 00528 }; 00529 00530 /*************************************************************************************************/ 00531 00538 struct set_monitor_t : std::unary_function<any_regular_t, void> 00539 { 00540 set_monitor_t(sheet_t& sheet, name_t cell_name) : 00541 cell_name_m(cell_name), 00542 sheet_m(sheet) 00543 { } 00544 00545 void operator()(const any_regular_t& x) 00546 { sheet_m.get().set(cell_name_m, x); } 00547 00548 private: 00549 name_t cell_name_m; 00550 boost::reference_wrapper<sheet_t> sheet_m; 00551 }; 00552 00553 /*************************************************************************************************/ 00554 00555 /* 00556 REVISIT (sparent) : line_position_t and array_t need to go in favor of a function object. 00557 */ 00558 00564 struct sheet_t::relation_t 00565 { 00566 relation_t() { } 00567 relation_t(vector<name_t> n, line_position_t p, array_t e) : 00568 name_set_m(n), 00569 position_m(p), 00570 expression_m(adobe::move(e)) 00571 { } 00572 00573 friend void swap(relation_t& x, relation_t& y) 00574 { 00575 swap(x.name_set_m, y.name_set_m); 00576 swap(x.position_m, y.position_m); 00577 swap(x.expression_m, y.expression_m); 00578 } 00579 00580 relation_t(move_from<relation_t> x) : 00581 name_set_m(x.source.name_set_m), 00582 position_m(x.source.position_m), 00583 expression_m(adobe::move(x.source.expression_m)) 00584 { } 00585 00586 relation_t& operator=(relation_t x) 00587 { swap(*this, x); return *this; } 00588 00589 00590 vector<name_t> name_set_m; 00591 line_position_t position_m; 00592 array_t expression_m; 00593 }; 00594 00595 /*************************************************************************************************/ 00596 00597 } // namespace adobe 00598 00599 /*************************************************************************************************/ 00600 00601 #endif 00602 00603 /*************************************************************************************************/ |