サブプロジェクトAI004
修订版 | 0136ab382b86209ad5eb116cb8692032c2eee247 (tree) |
---|---|
时间 | 2014-04-27 22:32:47 |
作者 | hikarupsp <hikarupsp@user...> |
Commiter | hikarupsp |
mgcanvas, memdb
@@ -0,0 +1,196 @@ | ||
1 | +// 知識表現のデータベース | |
2 | +// php経由でMySQLデータベースに同期する機能と | |
3 | +// データへのアクセスを提供する | |
4 | + | |
5 | +function MemoryDB(syncPHPURL){ | |
6 | + // 全データ | |
7 | + this.root = new Array(); | |
8 | + // | |
9 | + this.nodeList = new Array(); | |
10 | + // | |
11 | + this.syncPHPURL = syncPHPURL; | |
12 | + this.isEnabledNetDB = true; | |
13 | + // | |
14 | + this.callback_addNode = null; // function(nodeinstance){}; | |
15 | +} | |
16 | +MemoryDB.prototype = { | |
17 | + UUID_Null: "00000000-0000-0000-0000-000000000000", | |
18 | + UUID_NodeType_DecimalNumber: "e3346fd4-ac17-41c3-b3c7-e04972e5c014", | |
19 | + UUID_Node_MemoryDBNetworkTimestamp: "a2560a9c-dcf7-4746-ac14-347188518cf2", | |
20 | + createRequestObject: function(){ | |
21 | + var rq = null; | |
22 | + // XMLHttpRequest | |
23 | + try{ | |
24 | + // XMLHttpRequest オブジェクトを作成 | |
25 | + rq = new XMLHttpRequest(); | |
26 | + }catch(e){} | |
27 | + // Internet Explorer | |
28 | + try{ | |
29 | + rq = new ActiveXObject('MSXML2.XMLHTTP.6.0'); | |
30 | + }catch(e){} | |
31 | + try{ | |
32 | + rq = new ActiveXObject('MSXML2.XMLHTTP.3.0'); | |
33 | + }catch(e){} | |
34 | + try{ | |
35 | + rq = new ActiveXObject('MSXML2.XMLHTTP'); | |
36 | + }catch(e){} | |
37 | + if(rq == null){ | |
38 | + return null; | |
39 | + } | |
40 | + return rq; | |
41 | + }, | |
42 | + requestObjectDisableCache: function(rq){ | |
43 | + //call after open request. | |
44 | + //disable cache | |
45 | + //http://vird2002.s8.xrea.com/javascript/XMLHttpRequest.html | |
46 | + rq.setRequestHeader('Pragma', 'no-cache'); // HTTP/1.0 における汎用のヘッダフィールド | |
47 | + rq.setRequestHeader('Cache-Control', 'no-cache'); // HTTP/1.1 におけるキャッシュ制御のヘッダフィールド | |
48 | + rq.setRequestHeader('If-Modified-Since', 'Thu, 01 Jun 1970 00:00:00 GMT'); | |
49 | + | |
50 | + }, | |
51 | + sendRequestSync: function(mode, url, data){ | |
52 | + //同期モード | |
53 | + var q = this.createRequestObject(); | |
54 | + q.open(mode, url, false); | |
55 | + q.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); | |
56 | + this.requestObjectDisableCache(q); | |
57 | + try { | |
58 | + q.send(data); | |
59 | + } catch(e){ | |
60 | + console.log("sendRequestSync:Network Error.\n"); | |
61 | + this.isEnabledNetDB = false; | |
62 | + return null; | |
63 | + } | |
64 | + if(q.status == 0){ | |
65 | + console.log("ネットワークにアクセスできません。" + q.status + ":" + q.statusText); | |
66 | + }else if((200 <= q.status && q.status < 300) || (q.status == 304)){ | |
67 | + var res = q.responseText; | |
68 | + return res; | |
69 | + } else{ | |
70 | + console.log("サーバーがエラーを返しました。" + request.status + ":" + request.statusText); | |
71 | + } | |
72 | + this.isEnabledNetDB = false; | |
73 | + return null; | |
74 | + }, | |
75 | + syncDB: function(){ | |
76 | + // MySQLと同期 | |
77 | + var r, a, d, t; | |
78 | + if(this.root.length == 0){ | |
79 | + // 初回同期時は全て取得 | |
80 | + r = this.sendRequestSync("GET", this.syncPHPURL + "?action=getallnode", null); | |
81 | + } else{ | |
82 | + // 差分のみを取得 | |
83 | + | |
84 | + } | |
85 | + a = r.split("\n"); | |
86 | + for(var i = 0, iLen = a.length; i < iLen; i++){ | |
87 | + try{ | |
88 | + d = eval(a[i]); | |
89 | + } catch(e){ | |
90 | + console.log(i + ": " + e + "\n"); | |
91 | + continue; | |
92 | + } | |
93 | + if(d === undefined){ | |
94 | + continue; | |
95 | + } | |
96 | + t = new MemoryDBNodeTag(d[0], d[1], d[2]); | |
97 | + if(t){ | |
98 | + this.root.push(t); | |
99 | + this.nodeList.push(t); | |
100 | + } | |
101 | + } | |
102 | + console.log(this.root); | |
103 | + }, | |
104 | + editNode: function(ident, tid, nid, disableSync){ | |
105 | + // Nodeを追加し、データベースにも反映し、可能ならばネットワークにも反映させる | |
106 | + // nid(nodeid)は省略可能で、省略時は新たなUUIDが自動的に付与される | |
107 | + // tid(typeid)も省略可能で、省略時はNullUUIDが付与される。 | |
108 | + // 戻り値はMemoryDBNodeTagインスタンス | |
109 | + // すでに同じnodeidのNodeが存在している場合はundefinedを返しデータベースへの変更は行われない。 | |
110 | + var t, s, r; | |
111 | + if(!ident){ | |
112 | + return undefined; | |
113 | + } | |
114 | + if(!tid){ | |
115 | + tid = this.UUID_Null; | |
116 | + } | |
117 | + if(!nid){ | |
118 | + nid = this.createUUID(); | |
119 | + } | |
120 | + // 存在確認 | |
121 | + t = this.getNodeFromUUID(nid); | |
122 | + if(t){ | |
123 | + return undefined; | |
124 | + } | |
125 | + t = new MemoryDBNodeTag(nid, tid, ident); | |
126 | + | |
127 | + if(this.isEnabledNetDB){ | |
128 | + s = this.syncPHPURL + "?action=addnode"; | |
129 | + s += "&nid=" + encodeURIComponent(nid); | |
130 | + s += "&tid=" + encodeURIComponent(tid); | |
131 | + s += "&ident=" + encodeURIComponent(ident); | |
132 | + r = this.sendRequestSync("GET", s, null); | |
133 | + console.log(r); | |
134 | + } | |
135 | + }, | |
136 | + addNode: function(ident, tid, nid){ | |
137 | + // Nodeを追加し、データベースにも反映し、可能ならばネットワークにも反映させる | |
138 | + // nid(nodeid)は省略可能で、省略時は新たなUUIDが自動的に付与される | |
139 | + // tid(typeid)も省略可能で、省略時はNullUUIDが付与される。 | |
140 | + // 戻り値はMemoryDBNodeTagインスタンス | |
141 | + // すでに同じnodeidのNodeが存在している場合はundefinedを返しデータベースへの変更は行われない。 | |
142 | + var t, s, r; | |
143 | + if(!ident){ | |
144 | + return undefined; | |
145 | + } | |
146 | + if(!tid){ | |
147 | + tid = this.UUID_Null; | |
148 | + } | |
149 | + if(!nid){ | |
150 | + nid = this.createUUID(); | |
151 | + } | |
152 | + // 存在確認 | |
153 | + t = this.getNodeFromUUID(nid); | |
154 | + if(t){ | |
155 | + return undefined; | |
156 | + } | |
157 | + t = new MemoryDBNodeTag(nid, tid, ident); | |
158 | + | |
159 | + if(this.isEnabledNetDB){ | |
160 | + s = this.syncPHPURL + "?action=addnode"; | |
161 | + s += "&nid=" + encodeURIComponent(nid); | |
162 | + s += "&tid=" + encodeURIComponent(tid); | |
163 | + s += "&ident=" + encodeURIComponent(ident); | |
164 | + r = this.sendRequestSync("GET", s, null); | |
165 | + console.log(r); | |
166 | + } | |
167 | + }, | |
168 | + createUUID: function(){ | |
169 | + var f = this.createUUIDSub; | |
170 | + return (f() + f() + "-" + f() + "-" + f() + "-" + f() + "-" + f() + f() + f()); | |
171 | + }, | |
172 | + createUUIDSub: function(){ | |
173 | + return (((1 + Math.random()) * 0x10000) | 0).toString(16).toLowerCase().substring(1); | |
174 | + }, | |
175 | + getNodeFromUUID: function(nodeid){ | |
176 | + return this.nodeList.isIncluded(nodeid, function(a, b){ return a.nodeid == b; }); | |
177 | + }, | |
178 | +} | |
179 | + | |
180 | +function MemoryDBNodeTag(nodeid, typeid, identifier){ | |
181 | + this.nodeid = nodeid; | |
182 | + this.typeid = typeid; | |
183 | + this.identifier = identifier; | |
184 | + // | |
185 | + | |
186 | +} | |
187 | +MemoryDBNodeTag.prototype = { | |
188 | + | |
189 | +} | |
190 | + | |
191 | +function MemoryDBEdgeTag(typeUUIDStr){ | |
192 | + this.uuid = null; | |
193 | +} | |
194 | +MemoryDBEdgeTag.prototype = { | |
195 | + | |
196 | +} |
@@ -21,7 +21,8 @@ define("QUERY_CREATE_TABLE_Node", " | ||
21 | 21 | create table Node ( |
22 | 22 | nodeid binary(16) primary key, |
23 | 23 | typeid binary(16) not null, |
24 | - identifier text character set utf8 not null | |
24 | + identifier text character set utf8 not null, | |
25 | + modtimestamp bigint | |
25 | 26 | ) |
26 | 27 | "); |
27 | 28 |
@@ -30,31 +31,40 @@ create table Edge ( | ||
30 | 31 | edgeid binary(16) primary key, |
31 | 32 | typeid binary(16) not null, |
32 | 33 | nodeid0 binary(16) not null, |
33 | - nodeid1 binary(16) not null | |
34 | + nodeid1 binary(16) not null, | |
35 | + modtimestamp bigint | |
34 | 36 | ) |
35 | 37 | "); |
36 | 38 | |
39 | +// | |
40 | + | |
37 | 41 | define("QUERY_ADD_Node", " |
38 | 42 | insert into Node ( |
39 | - nodeid, typeid, identifier | |
43 | + nodeid, typeid, identifier, modtimestamp | |
40 | 44 | ) values ( |
41 | - unhex(replace(?, '-', '')), unhex(replace(?, '-', '')), ? | |
45 | + unhex(replace(?, '-', '')), unhex(replace(?, '-', '')), ?, ? | |
42 | 46 | ) |
43 | 47 | "); |
44 | -define("QUERY_ADD_Node_TYPES", "sss"); | |
48 | +define("QUERY_ADD_Node_TYPES", "sssi"); | |
45 | 49 | |
46 | 50 | define("QUERY_ADD_Edge", " |
47 | 51 | insert into Node ( |
48 | - edgeid, typeid, nodeid0, nodeid1 | |
52 | + edgeid, typeid, nodeid0, nodeid1, modtimestamp | |
49 | 53 | ) values ( |
50 | - unhex(replace(?, '-', '')), unhex(replace(?, '-', '')), unhex(replace(?, '-', '')), unhex(replace(?, '-', '')) | |
54 | + unhex(replace(?, '-', '')), unhex(replace(?, '-', '')), unhex(replace(?, '-', '')), unhex(replace(?, '-', '')), ? | |
51 | 55 | ) |
52 | 56 | "); |
53 | -define("QUERY_ADD_Edge_TYPES", "ssss"); | |
57 | +define("QUERY_ADD_Edge_TYPES", "ssssi"); | |
58 | + | |
59 | +// | |
54 | 60 | |
55 | 61 | define("QUERY_SELECT_ALL_Node", "select hex(nodeid), hex(typeid), identifier from Node"); |
62 | +define("QUERY_SELECT_ALL_Node_With_modtimestamp", "select hex(nodeid), hex(typeid), identifier, modtimestamp from Node"); | |
56 | 63 | define("QUERY_SELECT_ALL_Edge", "select hex(edgeid), hex(typeid), hex(nodeid0), hex(nodeid1) from Edge"); |
57 | 64 | |
65 | +define("QUERY_SELECT_modified_Node", "select hex(nodeid), hex(typeid), identifier from Node WHERE modtimestamp>?"); | |
66 | +define("QUERY_SELECT_modified_Node_TYPES", "i"); | |
67 | + | |
58 | 68 | //FOR DEBUG |
59 | 69 | mysqli_report(MYSQLI_REPORT_ERROR); |
60 | 70 |
@@ -88,9 +98,17 @@ if(isset($_GET['action'])){ | ||
88 | 98 | echo(PHP_EOL); |
89 | 99 | } |
90 | 100 | $stmt->close(); |
101 | + // put timestamp tag | |
102 | + echoMemoryDBNetworkTimestamp(); | |
91 | 103 | exit(); |
92 | - } else if(strcmp($action, 'viewallnode') == 0){ | |
93 | - $stmt = $db->prepare(QUERY_SELECT_ALL_Node); | |
104 | + } else if(strcmp($action, 'getnodemod') == 0){ | |
105 | + if(isset($_GET['t'])){ | |
106 | + $ts = $_GET['t']; | |
107 | + } else{ | |
108 | + $ts = 0; | |
109 | + } | |
110 | + $stmt = $db->prepare(QUERY_SELECT_modified_Node); | |
111 | + $stmt->bind_param(QUERY_SELECT_modified_Node_TYPES, $ts); | |
94 | 112 | $stmt->execute(); |
95 | 113 | // |
96 | 114 | $stmt->store_result(); |
@@ -108,19 +126,45 @@ if(isset($_GET['action'])){ | ||
108 | 126 | echo('","'); |
109 | 127 | echo($ident); |
110 | 128 | echo('"]'); |
129 | + echo(PHP_EOL); | |
130 | + } | |
131 | + $stmt->close(); | |
132 | + // put timestamp tag | |
133 | + echoMemoryDBNetworkTimestamp(); | |
134 | + exit(); | |
135 | + } else if(strcmp($action, 'viewallnode') == 0){ | |
136 | + $stmt = $db->prepare(QUERY_SELECT_ALL_Node_With_modtimestamp); | |
137 | + $stmt->execute(); | |
138 | + // | |
139 | + $stmt->store_result(); | |
140 | + if($stmt->errno != 0){ | |
141 | + exitWithResponseCode("A0518702-C90C-4785-B5EA-1A213DD0205B"); | |
142 | + } | |
143 | + | |
144 | + $stmt->bind_result($uuid, $typeid, $ident, $mts); | |
145 | + while($stmt->fetch()){ | |
146 | + $uuid = strtolower($uuid); | |
147 | + echo('["'); | |
148 | + echo(getFormedUUIDString($uuid)); | |
149 | + echo('","'); | |
150 | + echo(getFormedUUIDString($typeid)); | |
151 | + echo('","'); | |
152 | + echo($ident); | |
153 | + echo('"]'); | |
154 | + echo(' @' . $mts); | |
111 | 155 | echo("<br />"); |
112 | 156 | } |
113 | 157 | echo($stmt->num_rows); |
114 | 158 | $stmt->close(); |
115 | - exit(" OK"); | |
159 | + exit(" OK " . getTimeStampMs()); | |
116 | 160 | } else if(strcmp($action, 'addnode') == 0){ |
117 | - if(isset($_GET['nodeid'])){ | |
118 | - $uuid = $_GET['nodeid']; | |
161 | + if(isset($_GET['nid'])){ | |
162 | + $nodeid = $_GET['nid']; | |
119 | 163 | } else{ |
120 | 164 | exitWithResponseCode("A0518702-C90C-4785-B5EA-1A213DD0205B", "nodeid needed."); |
121 | 165 | } |
122 | - if(isset($_GET['typeid'])){ | |
123 | - $typeid = $_GET['typeid']; | |
166 | + if(isset($_GET['tid'])){ | |
167 | + $typeid = $_GET['tid']; | |
124 | 168 | } else{ |
125 | 169 | exitWithResponseCode("A0518702-C90C-4785-B5EA-1A213DD0205B", "typeid needed."); |
126 | 170 | } |
@@ -132,7 +176,7 @@ if(isset($_GET['action'])){ | ||
132 | 176 | |
133 | 177 | $stmt = $db->prepare(QUERY_ADD_Node); |
134 | 178 | $mts = getTimeStampMs(); |
135 | - $stmt->bind_param(QUERY_ADD_Node_TYPES, $nodeid, $typeid, $ident); | |
179 | + $stmt->bind_param(QUERY_ADD_Node_TYPES, $nodeid, $typeid, $ident, $mts); | |
136 | 180 | $stmt->execute(); |
137 | 181 | // |
138 | 182 | $stmt->store_result(); |
@@ -157,6 +201,14 @@ function exitWithResponseCode($errid, $description = "") | ||
157 | 201 | die('["' . $errid .'","' . $description . '"]'); |
158 | 202 | } |
159 | 203 | |
204 | +function echoMemoryDBNetworkTimestamp() | |
205 | +{ | |
206 | + echo('["a2560a9c-dcf7-4746-ac14-347188518cf2","e3346fd4-ac17-41c3-b3c7-e04972e5c014","'); | |
207 | + echo(getTimeStampMs()); | |
208 | + echo('"]'); | |
209 | + echo(PHP_EOL); | |
210 | +} | |
211 | + | |
160 | 212 | function connectDB() |
161 | 213 | { |
162 | 214 | $db = new mysqli('localhost', DATABASE_USER, DATABASE_PWD, DATABASE_NAME); |
@@ -198,33 +250,25 @@ function connectDB() | ||
198 | 250 | |
199 | 251 | function rebuildDB($db) |
200 | 252 | { |
201 | - // すでにあるテーブルの削除 | |
253 | + // | |
254 | + // 削除 | |
255 | + // | |
202 | 256 | |
203 | 257 | // Node |
204 | - $stmt = $db->prepare("drop table if exists Node"); | |
205 | - $stmt->execute(); | |
206 | - // エラーチェック省略 | |
207 | - $stmt->close(); | |
258 | + $stmt = $db->query("drop table if exists Node"); | |
208 | 259 | |
209 | 260 | // Edge |
210 | - $stmt = $db->prepare("drop table if exists Edge"); | |
211 | - $stmt->execute(); | |
212 | - // エラーチェック省略 | |
213 | - $stmt->close(); | |
261 | + $stmt = $db->query("drop table if exists Edge"); | |
214 | 262 | |
263 | + // | |
215 | 264 | // 再構築 |
265 | + // | |
216 | 266 | |
217 | 267 | // Node |
218 | - $stmt = $db->prepare(QUERY_CREATE_TABLE_Node); | |
219 | - $stmt->execute(); | |
220 | - // エラーチェック省略 | |
221 | - $stmt->close(); | |
268 | + $stmt = $db->query(QUERY_CREATE_TABLE_Node); | |
222 | 269 | |
223 | 270 | // Edge |
224 | - $stmt = $db->prepare(QUERY_CREATE_TABLE_Edge); | |
225 | - $stmt->execute(); | |
226 | - // エラーチェック省略 | |
227 | - $stmt->close(); | |
271 | + $stmt = $db->query(QUERY_CREATE_TABLE_Edge); | |
228 | 272 | } |
229 | 273 | |
230 | 274 | function getFormedUUIDString($str) |
@@ -1,306 +0,0 @@ | ||
1 | -// 知識表現を保存するデータベース | |
2 | - | |
3 | -function MemoryDB(){ | |
4 | - //ルート | |
5 | - this.root = new Array(); | |
6 | - // タグタイプリスト(各タグのfunctionオブジェクトの配列) | |
7 | - this.tagTypeList = new Array(); | |
8 | - /* | |
9 | - //サブリスト | |
10 | - this.candidateWordList = new Array(); | |
11 | - this.candidateWordListLastModifiedDate = new Date(); | |
12 | - this.candidateWordListLastCleanedDate = new Date(); | |
13 | - // | |
14 | - this.wordList = new Array(); | |
15 | - this.wordListLastModifiedDate = new Date(); | |
16 | - // | |
17 | - this.notWordList = new Array(); | |
18 | - this.notWordListLastModifiedDate = new Date(); | |
19 | - // | |
20 | - this.patternList = new Array(); | |
21 | - // | |
22 | - this.dbInfo = new AI_DatabaseInfoTag(); | |
23 | - */ | |
24 | -} | |
25 | -MemoryDB.prototype = { | |
26 | - headerUUID: "42e11880-62b8-46ea-a1c4-481264d4440d", // UUID_Mode_ReadMemory | |
27 | - memoryDataString: function(){ | |
28 | - var s = "#" + this.headerUUID + "\n"; | |
29 | - var cl = this.root; | |
30 | - var k; | |
31 | - for(var i = 0, iLen = cl.length; i < iLen; i++){ | |
32 | - if(cl[i] instanceof AI_MemoryTag){ | |
33 | - k = cl[i].parseToStringData(); | |
34 | - if(k !== undefined){ | |
35 | - s += k + "\n"; | |
36 | - } | |
37 | - } | |
38 | - } | |
39 | - //dbInfoタグの保存 | |
40 | - k = this.dbInfo.parseToStringData(); | |
41 | - if(k !== undefined){ | |
42 | - s += k + "\n"; | |
43 | - } | |
44 | - // | |
45 | - /* | |
46 | - var d = new Blob([s]); | |
47 | - if(d){ | |
48 | - m.showDownloadLink(d); | |
49 | - } | |
50 | - */ | |
51 | - return s; | |
52 | - }, | |
53 | - loadMemory: function(str){ | |
54 | - var a, t, d, m, q; | |
55 | - | |
56 | - // this.env.debug("Memory loading...\n"); | |
57 | - a = str.splitByArray(["\n"]); | |
58 | - | |
59 | - for(var i = 1, iLen = a.length; i < iLen; i++){ | |
60 | - try{ | |
61 | - d = eval(a[i]); | |
62 | - } catch(e){ | |
63 | - // this.env.debug(i + ": " + e + "\n"); | |
64 | - continue; | |
65 | - } | |
66 | - if(d === undefined){ | |
67 | - continue; | |
68 | - } | |
69 | - q = d.type; | |
70 | - if(q == AI_MemoryTag.prototype.Type_CandidateWord){ | |
71 | - t = new AI_CandidateWordTag(); | |
72 | - } else if(q == AI_MemoryTag.prototype.Type_Word){ | |
73 | - t = new AI_WordTag(); | |
74 | - } else if(q == AI_MemoryTag.prototype.Type_NotWord){ | |
75 | - t = new AI_NotWordTag(); | |
76 | - } else if(q == AI_MemoryTag.prototype.Type_DatabaseInfo){ | |
77 | - t = new AI_DatabaseInfoTag(); | |
78 | - } else{ | |
79 | - t = new AI_MemoryTag(); | |
80 | - } | |
81 | - AI_MemoryTag.prototype.loadFromMemoryData.call(t, d); | |
82 | - this.appendMemoryTag(t); | |
83 | - } | |
84 | - this.verifyMemoryStructure(); | |
85 | - this.env.debug("Memory loading done.\n" + this.root.length + " tags exist.\n"); | |
86 | - }, | |
87 | - appendMemoryTag: function(tag){ | |
88 | - //同じUUIDのタグがあった場合はデバッグ表示をして、追加しようとしているものに置き換える。 | |
89 | - //ただし、初期データに入っているものは警告を発さず上書きする。 | |
90 | - var s = this.root.isIncluded(tag, function(a, b){ return (a.uuid == b.uuid); }); | |
91 | - | |
92 | - //タグに合わせて追加条件を満たしているか確認し、それぞれのサブリストに分配 | |
93 | - if(tag instanceof AI_CandidateWordTag){ | |
94 | - this.candidateWordList.push(tag); | |
95 | - this.candidateWordListLastModifiedDate = new Date(); | |
96 | - } else if(tag instanceof AI_WordTag){ | |
97 | - if(this.wordList.isIncluded(tag, function(a, b){ return ((a.str == b.str) && (a !== s)); })){ | |
98 | - this.env.debug("appendMemoryTag: Duplicated word [" + tag.str + "].\n"); | |
99 | - return; | |
100 | - } | |
101 | - if(tag.str == undefined || tag.str.length == 0){ | |
102 | - this.env.debug("appendMemoryTag: Invalid word [" + tag.str + "].\n"); | |
103 | - return; | |
104 | - } | |
105 | - this.wordList.push(tag); | |
106 | - this.wordListLastModifiedDate = new Date(); | |
107 | - } else if(tag instanceof AI_NotWordTag){ | |
108 | - if(this.notWordList.isIncluded(tag, function(a, b){ return ((a.str == b.str) && (a !== s)); })){ | |
109 | - this.env.debug("appendMemoryTag: Duplicated notWord [" + tag.str + "].\n"); | |
110 | - return; | |
111 | - } | |
112 | - if(tag.str == undefined || tag.str.length == 0){ | |
113 | - this.env.debug("appendMemoryTag: Invalid notWord [" + tag.str + "].\n"); | |
114 | - return; | |
115 | - } | |
116 | - this.notWordList.push(tag); | |
117 | - this.notWordListLastModifiedDate = new Date(); | |
118 | - } else if(tag instanceof AI_PatternTag){ | |
119 | - this.patternList.push(tag); | |
120 | - } else if(tag instanceof AI_DatabaseInfoTag){ | |
121 | - //データベースデータに反映させて、タグ自体は破棄する | |
122 | - tag.bindDatabaseInfo(this); | |
123 | - return; | |
124 | - } | |
125 | - | |
126 | - //すでにあった重複UUIDの削除 | |
127 | - if(s){ | |
128 | - if(s.isBootstrap === undefined){ | |
129 | - this.env.debug("appendMemoryTag: duplicated UUID " + tag.uuid + ", overwritten.\n"); | |
130 | - } | |
131 | - this.removeMemoryTagByObject(s); | |
132 | - } | |
133 | - //ルートに追加 | |
134 | - this.root.push(tag); | |
135 | - }, | |
136 | - /* | |
137 | - appendMemoryTagFromString: function(str){ | |
138 | - //retv:isAppended | |
139 | - var d; | |
140 | - var q; | |
141 | - var t; | |
142 | - try{ | |
143 | - d = eval(str); | |
144 | - } catch(e){ | |
145 | - this.env.debug(""i + ": " + e + "\n"); | |
146 | - return false; | |
147 | - } | |
148 | - if(d === undefined){ | |
149 | - return false; | |
150 | - } | |
151 | - q = d.type; | |
152 | - if(q == AI_MemoryTag.prototype.Type_CandidateWord){ | |
153 | - t = new AI_CandidateWordTag(); | |
154 | - } else{ | |
155 | - t = new AI_MemoryTag(); | |
156 | - } | |
157 | - AI_MemoryTag.prototype.loadFromMemoryData.call(t, d); | |
158 | - this.appendMemoryTag(t); | |
159 | - }, | |
160 | - */ | |
161 | - removeMemoryTagByObject: function(obj){ | |
162 | - this.root.removeAnObject(obj); | |
163 | - if(this.candidateWordList.removeAnObject(obj)){ | |
164 | - this.candidateWordListLastModifiedDate = new Date(); | |
165 | - } | |
166 | - if(this.wordList.removeAnObject(obj)){ | |
167 | - this.wordListLastModifiedDate = new Date(); | |
168 | - } | |
169 | - }, | |
170 | - verifyMemoryStructure: function(){ | |
171 | - //メモリ構造検査・修復 | |
172 | - //単語が単語候補に残っていた場合は単語候補から削除 | |
173 | - for(var i = 0, iLen = this.wordList.length; i < iLen; i++){ | |
174 | - var w = this.wordList[i].str; | |
175 | - for(var j = 0, jLen = this.candidateWordList.length; j < jLen; j++){ | |
176 | - if(this.candidateWordList[j].str == w){ | |
177 | - this.env.debug("Word duplicated in CWL. Removed.\n"); | |
178 | - this.removeMemoryTagByObject(this.candidateWordList[j]); | |
179 | - j--; | |
180 | - jLen--; | |
181 | - } | |
182 | - } | |
183 | - } | |
184 | - | |
185 | - this.env.wordRecognition.cleanCandidateWordList(); | |
186 | - //候補リスト並べ替え | |
187 | - this.env.wordRecognition.sortCandidateWordListByWordCount(); | |
188 | - this.env.wordRecognition.computeEachWordLevel(); | |
189 | - this.env.wordRecognition.sortCandidateWordListByWordLevel(); | |
190 | - // | |
191 | - this.env.debug("Memory verifying done.\n"); | |
192 | - }, | |
193 | - getTagFromWordInNotWord: function(str){ | |
194 | - return this.notWordList.isIncluded(str, function(a, b){ return a.str == b; }); | |
195 | - }, | |
196 | - getUUIDFromWord: function(str){ | |
197 | - var t = this.wordList.isIncluded(str, function(a, b){ return a.str == b; }); | |
198 | - if(!t){ | |
199 | - return this.env.UUID_Meaning_UndefinedString; | |
200 | - } | |
201 | - return t.uuid; | |
202 | - }, | |
203 | - /* | |
204 | - getUUIDFromWordInNotWord: function(str){ | |
205 | - var t = this.getTagFromWordInNotWord(str); | |
206 | - if(!t){ | |
207 | - return this.env.UUID_Meaning_UndefinedString; | |
208 | - } | |
209 | - return t.uuid; | |
210 | - }, | |
211 | - */ | |
212 | -} | |
213 | - | |
214 | -function MemoryDBTag(typeUUIDStr){ | |
215 | - //保存対象 | |
216 | - this.uuid = null; | |
217 | - this.createdDate = new Date(); | |
218 | - | |
219 | - //初期化 | |
220 | - this.initUUID(); | |
221 | -} | |
222 | -AI_MemoryTag.prototype = { | |
223 | - Type_CandidateWord: "2fba8fc1-2b9a-46e0-8ade-455c0bd30637", | |
224 | - Type_Word: "d5eef85c-a796-4d04-bb72-8d45c94c5e4f", | |
225 | - Type_Pattern: "8085e53e-0e99-4221-821c-057f38e35ed9", | |
226 | - Type_Meaning: "dec1789a-9200-4f9b-9248-177495f47f7d", | |
227 | - Type_DatabaseInfo: "4e7b3a3e-bb8c-4315-b3d0-6b25f9aead61", | |
228 | - Type_NotWord: "505dbc8d-fa0a-4d0f-b625-d6065738f63d", | |
229 | - Type_Null: "00000000-0000-0000-0000-000000000000", | |
230 | - AppendType_Manual: "a2aaf202-7a6c-4dc5-b394-da9592410195", | |
231 | - type: "00000000-0000-0000-0000-000000000000", | |
232 | - //http://codedehitokoto.blogspot.jp/2012/01/javascriptuuid.html | |
233 | - initUUID: function(){ | |
234 | - if(!this.uuid){ | |
235 | - var f = this.initUUIDSub; | |
236 | - this.uuid = f() + f() + "-" + | |
237 | - f() + "-" + | |
238 | - f() + "-" + | |
239 | - f() + "-" + | |
240 | - f() + f() + f(); | |
241 | - } | |
242 | - }, | |
243 | - initUUIDSub: function(){ | |
244 | - return (((1 + Math.random()) * 0x10000) | 0).toString(16).toLowerCase().substring(1); | |
245 | - }, | |
246 | - parseToStringData: function(data){ | |
247 | - //uuid:type: | |
248 | - var d = new Object(); | |
249 | - // | |
250 | - d.id = this.uuid; | |
251 | - d.type = this.type; | |
252 | - d.cDate = this.createdDate.toUTCString(); | |
253 | - // | |
254 | - d.data = data; | |
255 | - // | |
256 | - return this.parseArrayToStringSource(d); | |
257 | - }, | |
258 | - loadFromMemoryData: function(data){ | |
259 | - this.uuid = data.id; | |
260 | - this.type = data.type; | |
261 | - this.createdDate = new Date(data.cDate); | |
262 | - if(data.data){ | |
263 | - if(this.loadFromMemoryData != AI_MemoryTag.prototype.loadFromMemoryData){ | |
264 | - this.loadFromMemoryData(data.data); | |
265 | - } | |
266 | - } | |
267 | - }, | |
268 | - parseArrayToStringSource: function(anArray){ | |
269 | - if(!anArray){ | |
270 | - return "null"; | |
271 | - } | |
272 | - var srcstr = "var t="; | |
273 | - srcstr += this.parseArrayToStringSourceSub(anArray); | |
274 | - srcstr += ";t;"; | |
275 | - return srcstr; | |
276 | - }, | |
277 | - parseArrayToStringSourceSub: function(anArray){ | |
278 | - if(!anArray){ | |
279 | - return "null"; | |
280 | - } | |
281 | - var srcstr = "{"; | |
282 | - for(var k in anArray){ | |
283 | - var v = anArray[k]; | |
284 | - var t = Object.prototype.toString.call(v); | |
285 | - if(v instanceof Array){ | |
286 | - srcstr += k + ":" + this.parseArrayToStringSourceSub(v) + ","; | |
287 | - } else if(!isNaN(v) && v.toString().replace(/\s+/g, "").length > 0){ | |
288 | - //isNaNだけでは数値判定できないので、文字列化後の空白文字を削除した長さも検査している。 | |
289 | - srcstr += k + ":" + v + ","; | |
290 | - } else if(t == "[object String]"){ | |
291 | - //文字列として変換 | |
292 | - srcstr += k + ":'" + v + "',"; | |
293 | - } else if(t == "[object Object]"){ | |
294 | - srcstr += k + ":" + this.parseArrayToStringSourceSub(v) + ","; | |
295 | - } else{ | |
296 | - srcstr += k + ":undefined,"; | |
297 | - } | |
298 | - } | |
299 | - if(srcstr.charAt(srcstr.length - 1) == ","){ | |
300 | - //最後の余計なカンマを削除 | |
301 | - srcstr = srcstr.slice(0, srcstr.length - 1); | |
302 | - } | |
303 | - srcstr += "}"; | |
304 | - return srcstr; | |
305 | - }, | |
306 | -} |
@@ -1,7 +1,9 @@ | ||
1 | 1 | include = function(relpath){ |
2 | 2 | document.write("<script type='text/javascript' src=" + relpath + " charset='UTF-8'></script>"); |
3 | 3 | } |
4 | -//AICore | |
4 | +// AICore | |
5 | 5 | include("./../aiext.js"); |
6 | -//MGCanvas | |
6 | +// MGCanvas | |
7 | 7 | include("./mgcanvas.js"); |
8 | +// memdb | |
9 | +include("./../memdb/memdb.js") |
@@ -18,117 +18,15 @@ | ||
18 | 18 | <script type="text/javascript"> |
19 | 19 | |
20 | 20 | var mgmain; |
21 | +var memdb; | |
21 | 22 | |
22 | 23 | onload = function() { |
24 | + memdb = new MemoryDB("./../memdb/memdb.php"); | |
25 | + memdb.syncDB(); | |
26 | + | |
23 | 27 | var c = document.getElementById("mainCanvas"); |
24 | 28 | mgmain = new MGCanvas(c); |
25 | - | |
26 | - /* | |
27 | - mgmain.setGraph([[ | |
28 | - "A","B","C","D","E","F", | |
29 | - ],[ | |
30 | - ["D", "F"], | |
31 | - ["D", "E"], | |
32 | - ["C", "E"], | |
33 | - ["B", "E"], | |
34 | - ["B", "C"], | |
35 | - ["A", "E"], | |
36 | - ["A", "B"], | |
37 | - ]]); | |
38 | - */ | |
39 | - /* | |
40 | - mgmain.setGraph([[ | |
41 | - "A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P", | |
42 | - ],[ | |
43 | - ["A", "B"], | |
44 | - ["A", "C"], | |
45 | - ["A", "D"], | |
46 | - ["A", "E"], | |
47 | - ["A", "F"], | |
48 | - ["A", "G"], | |
49 | - ["A", "H"], | |
50 | - ["A", "I"], | |
51 | - ["A", "J"], | |
52 | - ["A", "K"], | |
53 | - ["A", "L"], | |
54 | - ["A", "M"], | |
55 | - ["A", "N"], | |
56 | - ["A", "O"], | |
57 | - ["A", "P"], | |
58 | - ]]); | |
59 | - */ | |
60 | - /* | |
61 | - mgmain.setGraph([[ | |
62 | - "A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P", | |
63 | - ],[ | |
64 | - ["A", "B"], | |
65 | - ["B", "C"], | |
66 | - ["C", "D"], | |
67 | - ["D", "E"], | |
68 | - ["E", "F"], | |
69 | - ["F", "G"], | |
70 | - ["G", "H"], | |
71 | - ["A", "I"], | |
72 | - ["A", "J"], | |
73 | - ["A", "K"], | |
74 | - ["A", "L"], | |
75 | - ["A", "M"], | |
76 | - ["A", "N"], | |
77 | - ["A", "O"], | |
78 | - ["A", "P"], | |
79 | - ]]); | |
80 | - */ | |
81 | - /* | |
82 | - //Petersen Graph | |
83 | - mgmain.setGraph([[ | |
84 | - "A","B","C","D","E","F","G","H","I","J", | |
85 | - ],[ | |
86 | - ["A", "B", "AB"], | |
87 | - ["B", "C", "BC"], | |
88 | - ["C", "D", "CD"], | |
89 | - ["D", "E"], | |
90 | - ["E", "A"], | |
91 | - // | |
92 | - ["A", "F"], | |
93 | - ["B", "G"], | |
94 | - ["C", "H"], | |
95 | - ["D", "I"], | |
96 | - ["E", "J"], | |
97 | - // | |
98 | - ["H", "F"], | |
99 | - ["I", "G"], | |
100 | - ["J", "H"], | |
101 | - ["F", "I"], | |
102 | - ["G", "J"], | |
103 | - ]]); | |
104 | - */ | |
105 | - /* | |
106 | - mgmain.setGraph([[ | |
107 | - "A","B","C","D","E","F","G","H","I","J","K","L","M","N","O", | |
108 | - ],[ | |
109 | - ["A", "B"], | |
110 | - ["A", "C"], | |
111 | - ["A", "D"], | |
112 | - ["A", "E"], | |
113 | - // | |
114 | - ["B", "F"], | |
115 | - ["B", "G"], | |
116 | - // | |
117 | - ["C", "H"], | |
118 | - ["C", "I"], | |
119 | - // | |
120 | - ["D", "J"], | |
121 | - ["D", "K"], | |
122 | - // | |
123 | - ["E", "L"], | |
124 | - ["E", "M"], | |
125 | - // | |
126 | - ["A", "N"], | |
127 | - // | |
128 | - ["M", "O"], | |
129 | - ]]); | |
130 | - */ | |
131 | - | |
29 | + mgmain.loadGraphFromMemoryDB(memdb); | |
132 | 30 | } |
133 | 31 | </script> |
134 | 32 | </head> |
@@ -144,7 +42,11 @@ onload = function() { | ||
144 | 42 | <button onclick="mgmain.moveViewRelative(0, 10);">↓</button> |
145 | 43 | <button onclick="mgmain.moveViewRelative(-10, 0);">←</button> |
146 | 44 | <button onclick="mgmain.moveViewRelative(10, 0);">→</button> |
147 | -<input id="identBox" type="text"> | |
148 | -<button onclick="mgmain.setIdentifierForSelectedNode(getElementById('identBox').value);">set</button> | |
45 | +<br /> | |
46 | +identifier:<input id="identBox" type="text"></input> | |
47 | +<br /> | |
48 | +<button onclick="mgmain.setIdentifierForSelectedNode(getElementById('identBox').value);">setNodeIdent</button> | |
49 | +<button onclick="memdb.addNode(getElementById('identBox').value);">addNode</button> | |
50 | + | |
149 | 51 | </body> |
150 | 52 | </html> |
\ No newline at end of file |
@@ -79,11 +79,23 @@ MGCanvas.prototype = { | ||
79 | 79 | this.edgeList.push(new MGEdge(this, p[i][2], n(p[i][0]), n(p[i][1]))); |
80 | 80 | } |
81 | 81 | }, |
82 | - addNode: function(identifier, uuid){ | |
83 | - | |
84 | - }, | |
85 | - addEdge: function(identifier, uuid, nodeid){ | |
86 | - | |
82 | + loadGraphFromMemoryDB: function(mdb){ | |
83 | + var a, l, t, u, m, e, f; | |
84 | + a = mdb.nodeList; | |
85 | + l = a.length; | |
86 | + //m = 12 * l; | |
87 | + t = new MGNode(this, "Node"); | |
88 | + this.nodeList.push(t); | |
89 | + f = function(){}; | |
90 | + for(var i = 0; i < l; i++){ | |
91 | + u = new MGNode(this, a[i].identifier); | |
92 | + this.nodeList.push(u); | |
93 | + //e = new MGEdge(this, null, t, u); | |
94 | + //this.edgeList.push(e); | |
95 | + //t = u; | |
96 | + //e.freeLength = m; | |
97 | + //e.draw = f; | |
98 | + } | |
87 | 99 | }, |
88 | 100 | bringToCenter: function(){ |
89 | 101 | // 重心を求めて、それを表示オフセットに設定する |
@@ -170,7 +182,7 @@ MGCanvas.prototype = { | ||
170 | 182 | // |
171 | 183 | // Check |
172 | 184 | // |
173 | - | |
185 | + /* | |
174 | 186 | p = this.nodeList; |
175 | 187 | for(var i = 0, iLen = p.length; i < iLen; i++){ |
176 | 188 | nTemp = this.getVectorLength(p[i].vector); |
@@ -182,7 +194,7 @@ MGCanvas.prototype = { | ||
182 | 194 | if(n){ |
183 | 195 | n.ignoreEdgeRepulsion = 10; |
184 | 196 | } |
185 | - | |
197 | + */ | |
186 | 198 | |
187 | 199 | // |
188 | 200 | // Move |
@@ -360,6 +372,7 @@ MGCanvas.prototype = { | ||
360 | 372 | this.context.translate(w, h); |
361 | 373 | this.displayRect = new Rectangle(-w, -h, this.canvas.width, this.canvas.height); |
362 | 374 | this.currentScale = 1; |
375 | + this.zoomOut(); | |
363 | 376 | this.positionOffset = new Point2D(0, 0); |
364 | 377 | }, |
365 | 378 | convertPointToGraphLayerFromCanvasLayerP: function(pCanvas){ |
@@ -427,11 +440,11 @@ MGCanvas.prototype = { | ||
427 | 440 | function MGNode(env, identifier){ |
428 | 441 | this.env = env; |
429 | 442 | this.identifier = identifier; |
430 | - this.position = new Point2D(0, 0); | |
443 | + this.position = new Point2D(Math.random() * 32 - 16, Math.random() * 32 - 16); | |
431 | 444 | this.size = 10; |
432 | 445 | //ランダムな初期ベクトルをもつ。 |
433 | 446 | this.vector = new Point2D(Math.random() * 2 - 1, Math.random() * 2 - 1); |
434 | - this.friction = (100 - 8) / 100; | |
447 | + this.friction = 50 / 100; | |
435 | 448 | this.repulsionLengthNode = 90; |
436 | 449 | this.repulsionLengthEdge = 90; |
437 | 450 | this.ignoreEdgeRepulsion = 0; |
@@ -478,8 +491,10 @@ MGNode.prototype = { | ||
478 | 491 | } |
479 | 492 | } |
480 | 493 | } |
494 | + | |
481 | 495 | //edge |
482 | 496 | //自分を端点に含まないエッジとの距離が近い場合、そのエッジから遠ざかろうとする。 |
497 | + /* | |
483 | 498 | p = this.env.edgeList; |
484 | 499 | for(var i = 0, iLen = p.length; i < iLen; i++){ |
485 | 500 | var q = this.env.edgeList[i]; |
@@ -501,9 +516,11 @@ MGNode.prototype = { | ||
501 | 516 | } |
502 | 517 | } |
503 | 518 | } |
519 | + */ | |
504 | 520 | } else{ |
505 | 521 | this.ignoreEdgeRepulsion--; |
506 | 522 | } |
523 | + | |
507 | 524 | }, |
508 | 525 | } |
509 | 526 |
@@ -514,7 +531,7 @@ function MGEdge(env, identifier, node0, node1){ | ||
514 | 531 | this.node1 = node1; |
515 | 532 | this.freeLength = 250; |
516 | 533 | // |
517 | - this.strokeStyle = "rgba(0, 0, 0, 1)"; | |
534 | + this.strokeStyle = "rgba(0, 0, 0, 0.5)"; | |
518 | 535 | this.isSelected = false; |
519 | 536 | // |
520 | 537 | this.centerPoint = new Point2D(0, 0); |