Mercurial > hg > Papers > 2022 > riono-master
changeset 58:c269b11bb810
update slide and add poster
author | riono <e165729@ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 18 Feb 2022 01:09:32 +0900 |
parents | 309de2ffb2bd |
children | ac5582e1aa2d |
files | Paper/images/Remote_DataGearManager.graffle Paper/images/Remote_DataGearManager.pdf Poster/riono-poster.graffle/data.plist Poster/riono-poster.graffle/image22.pdf Poster/riono-poster.graffle/image33.pdf Poster/riono-poster.pdf Slide/master-slide.html Slide/master-slide.md riono-master.mm |
diffstat | 9 files changed, 3808 insertions(+), 936 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Poster/riono-poster.graffle/data.plist Fri Feb 18 01:09:32 2022 +0900 @@ -0,0 +1,3152 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>ActiveLayerIndex</key> + <integer>0</integer> + <key>ApplicationVersion</key> + <array> + <string>com.omnigroup.OmniGraffle6</string> + <string>169.23.0.276662</string> + </array> + <key>AutoAdjust</key> + <true/> + <key>BackgroundGraphic</key> + <dict> + <key>Bounds</key> + <string>{{0, 0}, {2860.68505859375, 2027.6220703125}}</string> + <key>Class</key> + <string>SolidGraphic</string> + <key>FontInfo</key> + <dict> + <key>Font</key> + <string>Helvetica</string> + <key>Size</key> + <real>28</real> + </dict> + <key>ID</key> + <integer>2</integer> + <key>Style</key> + <dict> + <key>stroke</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + </dict> + </dict> + <key>BaseZoom</key> + <integer>0</integer> + <key>CanvasOrigin</key> + <string>{0, 0}</string> + <key>ColorProfiles</key> + <array> + <dict> + <key>data</key> + <data> + AAACJGFwcGwEAAAAbW50clJHQiBYWVogB+EABwAHAA0AFgAgYWNz + cEFQUEwAAAAAQVBQTAAAAAAAAAAAAAAAAAAAAAAAAPbWAAEAAAAA + 0y1hcHBsyhqVgiV/EE04mRPV0eoVggAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAKZGVzYwAAAPwAAABlY3BydAAAAWQAAAAj + d3RwdAAAAYgAAAAUclhZWgAAAZwAAAAUZ1hZWgAAAbAAAAAUYlhZ + WgAAAcQAAAAUclRSQwAAAdgAAAAgY2hhZAAAAfgAAAAsYlRSQwAA + AdgAAAAgZ1RSQwAAAdgAAAAgZGVzYwAAAAAAAAALRGlzcGxheSBQ + MwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAB0ZXh0AAAAAENvcHlyaWdodCBBcHBsZSBJbmMuLCAyMDE3 + AABYWVogAAAAAAAA81EAAQAAAAEWzFhZWiAAAAAAAACD3wAAPb// + //+7WFlaIAAAAAAAAEq/AACxNwAACrlYWVogAAAAAAAAKDgAABEL + AADIuXBhcmEAAAAAAAMAAAACZmYAAPKnAAANWQAAE9AAAApbc2Yz + MgAAAAAAAQxCAAAF3v//8yYAAAeTAAD9kP//+6L///2jAAAD3AAA + wG4= + </data> + <key>space</key> + <string>031375ea2e6fd7f8c2ca30fdc720c8d7c8a37a18</string> + </dict> + </array> + <key>ColumnAlign</key> + <integer>1</integer> + <key>ColumnSpacing</key> + <real>36</real> + <key>CreationDate</key> + <string>2012-01-04 16:02:58 +0000</string> + <key>Creator</key> + <string>Daichi TOMA</string> + <key>DisplayScale</key> + <string>1.0000 cm = 1.0000 cm</string> + <key>GraphDocumentVersion</key> + <integer>12</integer> + <key>GraphicsList</key> + <array> + <dict> + <key>Bounds</key> + <string>{{1920.9282427555847, 1012.5742065735318}, {908.50394525086881, 273.54330956851396}}</string> + <key>Class</key> + <string>ShapedGraphic</string> + <key>FontInfo</key> + <dict> + <key>Size</key> + <real>22</real> + </dict> + <key>ID</key> + <integer>5039</integer> + <key>Style</key> + <dict> + <key>fill</key> + <dict> + <key>Color</key> + <dict> + <key>b</key> + <real>0.8509600759</real> + <key>g</key> + <real>0.99431246520000005</real> + <key>r</key> + <real>0.99912756680000003</real> + <key>space</key> + <string>031375ea2e6fd7f8c2ca30fdc720c8d7c8a37a18</string> + </dict> + </dict> + <key>shadow</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + </dict> + <key>Text</key> + <dict> + <key>Align</key> + <integer>0</integer> + <key>RTFD</key> + <data> + BAtzdHJlYW10eXBlZIHoA4QBQISEhBJOU0F0dHJpYnV0 + ZWRTdHJpbmcAhIQITlNPYmplY3QAhZKEhIQITlNTdHJp + bmcBlIQBK4FAAXB1YmxpYyBjbGFzcyBQb3NpdGlvbkFz + c2lnbkNvZGVHZWFyIDogQ29kZUdlYXIgewogICAgW1Rh + a2VdIHByaXZhdGUgVmVjdG9yMyBwb3M7CiAgICBbUGVl + a10gcHJpdmF0ZSBUcmFuc2Zvcm0gdHJhbnNmb3JtOwog + ICAgcHVibGljIG92ZXJyaWRlIHZvaWQgUnVuKENvZGVH + ZWFyTWFuYWdlciBjZ20pIHsKICAgICAgICBNYWluVGhy + ZWFkRGlzcGF0Y2hlci5Qb3N0KF8gPT4ge+OAgOOAgOOA + gOOAgC8vIE1haW5UaHJlYWTjgbjlh6bnkIbjgpLnp7vo + rbIKICAgICAgICAgICAgdHJhbnNmb3JtLnBvc2l0aW9u + ID0gcG9zOwogICAgICAgIH0sIG51bGwpOwogICAgfQp9 + hoQCaUkBBpKEhIQMTlNEaWN0aW9uYXJ5AJSEAWkDkoSW + lgdOU0NvbG9yhpKEhIQHTlNDb2xvcgCUhAFjAYQEZmZm + ZoMb0Ok8g3B4gD6DsoAAPwGGkoSWlhBOU1BhcmFncmFw + aFN0eWxlhpKEhIQXTlNNdXRhYmxlUGFyYWdyYXBoU3R5 + bGUAhIQQTlNQYXJhZ3JhcGhTdHlsZQCUhARDQ0BTAACE + hIQHTlNBcnJheQCUmQCGgQEChARbMmZdARyGkoSWlgZO + U0ZvbnSGkoSEhAZOU0ZvbnQelJkkhAVbMzZjXQYAAAAc + AAAA//5IAGUAbAB2AGUAdABpAGMAYQBOAGUAdQBlAIQB + ZhabAJsBmwCbAIaGlwIBkoSYmQKSnJKdkqKSo4aXAQWX + AhqXAQiXAgiXAwSShJiZA5KZkoSbmwGcg0YGhz2D43UA + P4Op4N87AYaSnJKdkqKSo4aXAgKXAQeXAgGXAQeXAguX + BASShJiZA5KZkoSbmwGcgz6AgD6DSn8AP4OszRI8AYaS + nJKdkqKSo4aXAgKXAQeXAgGXAQmXAhCXAQaXAgGXAQiX + AgGXAQSXAkSXBQSShJiZApKckoSenwAAoIEBAqEBHIaS + opKEpJkohAVbNDBjXQYAAAAgAAAA//5IAGkAcgBhAGcA + aQBuAG8AUwBhAG4AcwAtAFcAMwCkFpsAmwGbAJsAhoaX + BA2XBgaShJiZA5KZkqmSnJKrkqKSrIaXAkCG + </data> + <key>Text</key> + <string>{\rtf1\ansi\ansicpg932\cocoartf2513 +\cocoatextscaling0\cocoaplatform0{\fonttbl\f0\fnil\fcharset0 HelveticaNeue;\f1\fnil\fcharset128 HiraginoSans-W3;} +{\colortbl;\red255\green255\blue255;\red7\green64\blue128;\red17\green128\blue2;\red64\green128\blue2; +} +{\*\expandedcolortbl;;\cssrgb\c0\c32852\c57488;\cssrgb\c0\c56032\c0;\cssrgb\c30840\c56182\c0; +} +\deftab560 +\pard\pardeftab560\slleading20\partightenfactor0 + +\f0\fs44 \cf2 public\cf0 \cf2 class\cf0 PositionAssignCodeGear : \cf2 CodeGear\cf0 \{\ + [\cf3 Take\cf0 ] \cf2 private\cf0 \cf2 Vector3\cf0 pos;\ + [\cf4 Peek\cf0 ] \cf2 private\cf0 \cf2 Transform\cf0 transform;\ + \cf2 public\cf0 \cf2 override\cf0 \cf2 void\cf0 Run(CodeGearManager cgm) \{\ + MainThreadDispatcher.Post(_ => \{ +\f1 \'81\'40\'81\'40\'81\'40\'81\'40 +\f0 \cf4 // MainThread +\f1 \'82\'d6\'8f\'88\'97\'9d\'82\'f0\'88\'da\'8f\'f7 +\f0 \cf0 \ + transform.position = pos;\ + \}, null);\ + \}\ +\}}</string> + </dict> + <key>TextPlacement</key> + <integer>0</integer> + </dict> + <dict> + <key>Bounds</key> + <string>{{1921.8897812171235, 412.94670269960034}, {908.50394525086881, 582.52582606280043}}</string> + <key>Class</key> + <string>ShapedGraphic</string> + <key>FontInfo</key> + <dict> + <key>Color</key> + <dict> + <key>b</key> + <string>0.574885</string> + <key>g</key> + <string>0.328521</string> + <key>r</key> + <string>0</string> + <key>space</key> + <string>srgb</string> + </dict> + <key>Size</key> + <real>22</real> + </dict> + <key>ID</key> + <integer>5038</integer> + <key>Style</key> + <dict> + <key>fill</key> + <dict> + <key>Color</key> + <dict> + <key>b</key> + <real>0.8509600759</real> + <key>g</key> + <real>0.99431246520000005</real> + <key>r</key> + <real>0.99912756680000003</real> + <key>space</key> + <string>031375ea2e6fd7f8c2ca30fdc720c8d7c8a37a18</string> + </dict> + </dict> + <key>shadow</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + </dict> + <key>Text</key> + <dict> + <key>Align</key> + <integer>0</integer> + <key>RTFD</key> + <data> + BAtzdHJlYW10eXBlZIHoA4QBQISEhBJOU0F0dHJpYnV0 + ZWRTdHJpbmcAhIQITlNPYmplY3QAhZKEhIQITlNTdHJp + bmcBlIQBK4FXA3B1YmxpYyBjbGFzcyBUcmFuc2Zvcm1N + b3ZlVGVzdCA6IE1vbm9CZWhhdmlvdXIgewogICAgcHJp + dmF0ZSBDb2RlR2Vhck1hbmFnZXIgY2dtOwogICAgcHVi + bGljIFRyYW5zZm9ybSBvdGhlclRyYW5zZm9ybTsKICAg + IHByaXZhdGUgVmVjdG9yMyBwb3M7CiAgICBwcml2YXRl + IHZvaWQgU3RhcnQoKSB744CA44CA44CA44CALy8g44Ky + 44O844Og5a6f6KGM5pmC44Gu5pyA5Yid44GuMeWbnuWR + vOOBs+WHuuOBlwogICAgICAgIGNnbSA9IFN0YXJ0Q29k + ZUdlYXIuQ3JlYXRlQ2dtKDEwMDAwKTsKICAgICAgICBj + Z20uU2V0dXAobmV3IFBvc2l0aW9uQXNzaWduQ29kZUdl + YXIoKSk744CA44CALy8g5paw44GX44GEQ29kZUdlYXLj + ga7nlJ/miJAKICAgICAgICBjZ20uR2V0TG9jYWxER00o + KS5QdXQoInRyYW5zZm9ybSIsIHRyYW5zZm9ybSk7CiAg + ICB9CiAgICBwcml2YXRlIHZvaWQgVXBkYXRlKCkge+OA + gOOAgOOAgC8vIOavjuODleODrOODvOODoOWRvOOBs+WH + uuOBlwogICAgICAgIHBvcyA9IG90aGVyVHJhbnNmb3Jt + LnBvc2l0aW9uOwogICAgICAgIFZlY3RvcjMgbmV3UG9z + ID0gbmV3IFZlY3RvcjMocG9zLnggKyAzLCBwb3MueSwg + cG9zLnogKyAzKTsKICAgICAgICBWZWN0b3IzQ21kIHZD + bWQgPSBuZXcgVmVjdG9yM0NtZChuZXdQb3MueCwgbmV3 + UG9zLnksIG5ld1Bvcy56KTsKCiAgICAgICAgY2dtLkdl + dExvY2FsREdNKCkuUHV0KCJwb3MiLCB2Q21kKTsKICAg + IH0KICAgIHByaXZhdGUgdm9pZCBMYXRlVXBkYXRlKCkg + e+OAgOOAgC8vIOasoeOBruODleODrOODvOODoOebtOWJ + jeOBq+WRvOOBs+WHuuOBlwogICAgICAgIGNnbS5TZXR1 + cChuZXcgUG9zaXRpb25Bc3NpZ25Db2RlR2VhcigpKTsK + ICAgIH0KfYaEAmlJAQ2ShISEDE5TRGljdGlvbmFyeQCU + hAFpA5KElpYHTlNDb2xvcoaShISEB05TQ29sb3IAlIQB + YwGEBGZmZmaDG9DpPINweIA+g7KAAD8BhpKElpYQTlNQ + YXJhZ3JhcGhTdHlsZYaShISEF05TTXV0YWJsZVBhcmFn + cmFwaFN0eWxlAISEEE5TUGFyYWdyYXBoU3R5bGUAlIQE + Q0NAUwAAhISEB05TQXJyYXkAlJkAhoEBAoQEWzJmXQEc + hpKElpYGTlNGb250hpKEhIQGTlNGb250HpSZJIQFWzM2 + Y10GAAAAHAAAAP/+SABlAGwAdgBlAHQAaQBjAGEATgBl + AHUAZQCEAWYWmwCbAZsAmwCGhpcCFJKEmJkCkpySnZKi + kqOGlwENlwIHlwEHlwIBlwEPlwIKlwEGlwIBlwEJlwIV + lwEHlwIBlwEHlwIKlwMHkoSYmQOSmZKakpySnZKikoSk + mSSjBgAAABwAAAD//kgAZQBsAHYAZQB0AGkAYwBhAE4A + ZQB1AGUApBabAJsBmwCbAIaGlwQBkoSYmQKSnJKdkqKS + p4aXAQSXAgqXBQSShJiZApKckp2SopKEpJkohAVbNDBj + XQYAAAAgAAAA//5IAGkAcgBhAGcAaQBuAG8AUwBhAG4A + cwAtAFcAMwCkFpsAmwGbAJsAhoaXBgOShJiZA5KZkoSb + mwGcg0YGhz2D43UAP4Op4N87AYaSnJKdkqKSo4aXBwqS + hJiZA5KZkqySnJKdkqKSqoaXBgGXBwWXAkGXAQOXAhuX + BQKXBgOXBwOXBgiXBwOXAkKXAQeXAgGXAQSXAguXBQOX + BgOXBwmXAjCXAQeXAgqXAQOXAgGXAQeXAh6XBAmXAwqX + BAiXAwOXCAGShJiZA5KZkoSbmwGcAACD//5+PwGGkpyS + nZKikqeGlwMKlwQglwImlwkEkoSYmQOSmZKEm5sBnAAA + AAGGkpySnZKikqOGlwINlwEHlwIBlwEElwIPlwUClwYD + lwcNlwITlwEDlwIjhg== + </data> + <key>Text</key> + <string>{\rtf1\ansi\ansicpg932\cocoartf2513 +\cocoatextscaling0\cocoaplatform0{\fonttbl\f0\fnil\fcharset0 HelveticaNeue;\f1\fnil\fcharset128 HiraginoSans-W3;} +{\colortbl;\red255\green255\blue255;\red7\green64\blue128;\red17\green128\blue2;\red0\green0\blue254; +\red0\green0\blue0;} +{\*\expandedcolortbl;;\cssrgb\c0\c32852\c57488;\cssrgb\c0\c56032\c0;\csgenericrgb\c0\c0\c99608; +\cssrgb\c0\c0\c0;} +\deftab560 +\pard\pardeftab560\slleading20\partightenfactor0 + +\f0\fs44 \cf2 public class \cf0 TransformMoveTest : \cf2 MonoBehaviour\cf0 \{\ + \cf2 private\cf0 \cf2 CodeGearManager\cf0 cgm;\ + \cf2 public\cf0 \cf2 Transform\cf0 otherTransform;\ + \cf2 private\cf0 \cf2 Vector3\cf0 pos;\ + \cf2 private\cf0 \cf2 void\cf0 Start() \{ +\f1 \'81\'40\'81\'40\'81\'40\'81\'40 +\f0 \cf3 // +\f1 \'83\'51\'81\'5b\'83\'80\'8e\'c0\'8d\'73\'8e\'9e\'82\'cc\'8d\'c5\'8f\'89\'82\'cc +\f0 1 +\f1 \'89\'f1\'8c\'c4\'82\'d1\'8f\'6f\'82\'b5 +\f0 \cf0 \ + cgm = StartCodeGear.CreateCgm(10000);\ + cgm.Setup(\cf2 new\cf0 PositionAssignCodeGear()); +\f1 \'81\'40\'81\'40 +\f0 \cf3 // +\f1 \'90\'56\'82\'b5\'82\'a2 +\f0 CodeGear +\f1 \'82\'cc\'90\'b6\'90\'ac +\f0 \cf0 \ + cgm.GetLocalDGM().Put("transform", transform);\ + \}\ + \cf2 private\cf0 \cf2 void\cf0 Update() \{ +\f1 \'81\'40\'81\'40\'81\'40 +\f0 \cf3 // +\f1 \'96\'88\'83\'74\'83\'8c\'81\'5b\'83\'80\'8c\'c4\'82\'d1\'8f\'6f\'82\'b5 +\f0 \cf0 \ + pos = otherTransform.position;\ + \cf2 Vector3\cf0 newPos = \cf2 new\cf0 \cf2 Vector3\cf0 (pos.x + 3, pos.y, pos.z + 3);\ + \cf2 Vector3Cmd\cf0 vCmd = \cf2 new\cf4 \cf2 Vector3Cmd\cf0 (newPos.x, newPos.y, newPos.z);\ +\ + cgm.GetLocalDGM().Put("pos", \cf5 vCmd\cf0 );\ + \}\ + \cf2 private\cf0 \cf2 void\cf0 LateUpdate() \{ +\f1 \'81\'40\'81\'40 +\f0 \cf3 // +\f1 \'8e\'9f\'82\'cc\'83\'74\'83\'8c\'81\'5b\'83\'80\'92\'bc\'91\'4f\'82\'c9\'8c\'c4\'82\'d1\'8f\'6f\'82\'b5 +\f0 \cf0 \ + cgm.Setup(\cf2 new\cf0 PositionAssignCodeGear());\ + \}\ +\}}</string> + </dict> + <key>TextPlacement</key> + <integer>0</integer> + </dict> + <dict> + <key>Class</key> + <string>Group</string> + <key>Graphics</key> + <array> + <dict> + <key>Bounds</key> + <string>{{1908.2488463061477, 1600.732673778054}, {936.31810863689566, 406.19647828938582}}</string> + <key>Class</key> + <string>ShapedGraphic</string> + <key>FontInfo</key> + <dict> + <key>Color</key> + <dict> + <key>b</key> + <string>0</string> + <key>g</key> + <string>0</string> + <key>r</key> + <string>0</string> + </dict> + <key>Font</key> + <string>HiraKakuProN-W6</string> + <key>Size</key> + <real>30</real> + </dict> + <key>ID</key> + <integer>5028</integer> + <key>Style</key> + <dict> + <key>fill</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + <key>shadow</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + <key>stroke</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + </dict> + <key>Text</key> + <dict> + <key>Align</key> + <integer>0</integer> + <key>Pad</key> + <real>0.0</real> + <key>RTFD</key> + <data> + BAtzdHJlYW10eXBlZIHoA4QBQISE + hBJOU0F0dHJpYnV0ZWRTdHJpbmcA + hIQITlNPYmplY3QAhZKEhIQITlNT + dHJpbmcBlIQBK4HgAeODu0Nocmlz + dGll44KSVW5pdHnjgafkvb/nlKjj + gZnjgovjgZ/jgoHjgatDI+OBq+ab + uOOBjeaPm+OBiOOCkuihjOOBo+OB + nwrjg7tVbml0eeOBp+WLleS9nOak + nOiovOOCkuihjOOBhOOAgeW5s+Wd + hzYwZnBz5YmN5b6M44Gn5YuV5L2c + 5Y+v6IO9CuOAgOODu0NocmlzdGll + IFNoYXJw44KS55So44GE44Gf44Ky + 44O844Og6ZaL55m644GM5Y+v6IO9 + CuODu1Rha2UvUHV0L1BlZWvjgpLl + iKnnlKjjgZfjgZ/jgrLjg7zjg6Dj + gajnm7jmgKfjga7jgojjgYTjg5fj + g63jgrDjg6njg5/jg7PjgrAK5LuK + 5b6M44Gu6Kqy6aGMCuODu1RvcG9s + b2d5TWFuYWdlcuWujOaIkArjg7tD + aHJpc3RpZSBTaGFycOOBruaAp+iD + veaknOiovArjgIDjg7vku5bjga7p + gJrkv6Hjg6njgqTjg5bjg6njg6rj + gajjga7pgJrkv6HpgJ/luqbjgoTo + gJDkuYXmgKcK44CA44O7Q2hyc2l0 + ZSBTaGFycOOCkueUqOOBhOOBnzEw + MOS6uuimj+aooeOBruOCsuODvOOD + oOOBrumWi+eZuoaEAmlJAYHmAJKE + hIQMTlNEaWN0aW9uYXJ5AJSEAWkD + koSWlgdOU0NvbG9yhpKEhIQHTlND + b2xvcgCUhAFjAYQEZmZmZgAAAAGG + koSWlhBOU1BhcmFncmFwaFN0eWxl + hpKEhIQXTlNNdXRhYmxlUGFyYWdy + YXBoU3R5bGUAhIQQTlNQYXJhZ3Jh + cGhTdHlsZQCUhARDQ0BTAACEhIQH + TlNBcnJheQCUmQyShISECU5TVGV4 + dFRhYgCUhAJDZgAchpKEo6IAOIaS + hKOiAFSGkoSjogBwhpKEo6IAgYwA + hpKEo6IAgagAhpKEo6IAgcQAhpKE + o6IAgeAAhpKEo6IAgfwAhpKEo6IA + gRgBhpKEo6IAgTQBhpKEo6IAgVAB + hoYAhpKElpYGTlNGb250hpKEhIQG + TlNGb250HpSZKIQFWzQwY10GAAAA + IAAAAP/+SABpAHIAYQBLAGEAawB1 + AFAAcgBvAE4ALQBXADYAhAFmHpsA + mwGbAJsAhoaG + </data> + <key>Text</key> + <string>{\rtf1\ansi\ansicpg932\cocoartf2513 +\cocoatextscaling0\cocoaplatform0{\fonttbl\f0\fnil\fcharset128 HiraKakuProN-W6;} +{\colortbl;\red255\green255\blue255;\red0\green0\blue0;} +{\*\expandedcolortbl;;\csgenericrgb\c0\c0\c0;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\partightenfactor0 + +\f0\b\fs60 \cf2 \'81\'45Christie\'82\'f0Unity\'82\'c5\'8e\'67\'97\'70\'82\'b7\'82\'e9\'82\'bd\'82\'df\'82\'c9C#\'82\'c9\'8f\'91\'82\'ab\'8a\'b7\'82\'a6\'82\'f0\'8d\'73\'82\'c1\'82\'bd\ +\'81\'45Unity\'82\'c5\'93\'ae\'8d\'ec\'8c\'9f\'8f\'d8\'82\'f0\'8d\'73\'82\'a2\'81\'41\'95\'bd\'8b\'cf60fps\'91\'4f\'8c\'e3\'82\'c5\'93\'ae\'8d\'ec\'89\'c2\'94\'5c\ +\'81\'40\'81\'45Christie Sharp\'82\'f0\'97\'70\'82\'a2\'82\'bd\'83\'51\'81\'5b\'83\'80\'8a\'4a\'94\'ad\'82\'aa\'89\'c2\'94\'5c\ +\'81\'45Take/Put/Peek\'82\'f0\'97\'98\'97\'70\'82\'b5\'82\'bd\'83\'51\'81\'5b\'83\'80\'82\'c6\'91\'8a\'90\'ab\'82\'cc\'82\'e6\'82\'a2\'83\'76\'83\'8d\'83\'4f\'83\'89\'83\'7e\'83\'93\'83\'4f\ +\'8d\'a1\'8c\'e3\'82\'cc\'89\'db\'91\'e8\ +\'81\'45TopologyManager\'8a\'ae\'90\'ac\ +\'81\'45Christie Sharp\'82\'cc\'90\'ab\'94\'5c\'8c\'9f\'8f\'d8\ +\'81\'40\'81\'45\'91\'bc\'82\'cc\'92\'ca\'90\'4d\'83\'89\'83\'43\'83\'75\'83\'89\'83\'8a\'82\'c6\'82\'cc\'92\'ca\'90\'4d\'91\'ac\'93\'78\'82\'e2\'91\'cf\'8b\'76\'90\'ab\ +\'81\'40\'81\'45Chrsite Sharp\'82\'f0\'97\'70\'82\'a2\'82\'bd100\'90\'6c\'8b\'4b\'96\'cd\'82\'cc\'83\'51\'81\'5b\'83\'80\'82\'cc\'8a\'4a\'94\'ad}</string> + <key>VerticalPad</key> + <real>1</real> + </dict> + <key>TextPlacement</key> + <integer>0</integer> + </dict> + <dict> + <key>Class</key> + <string>Group</string> + <key>Graphics</key> + <array> + <dict> + <key>Bounds</key> + <string>{{2002.6771835249242, 1549.8084725565413}, {802.20473168797366, 50.924201221512725}}</string> + <key>Class</key> + <string>ShapedGraphic</string> + <key>FontInfo</key> + <dict> + <key>Color</key> + <dict> + <key>b</key> + <string>1</string> + <key>g</key> + <string>1</string> + <key>r</key> + <string>1</string> + </dict> + <key>Font</key> + <string>HiraKakuProN-W3</string> + <key>Size</key> + <real>46</real> + </dict> + <key>ID</key> + <integer>5030</integer> + <key>Style</key> + <dict> + <key>fill</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + <key>shadow</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + <key>stroke</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + </dict> + <key>Text</key> + <dict> + <key>Align</key> + <integer>0</integer> + <key>Pad</key> + <real>0.0</real> + <key>Text</key> + <string>{\rtf1\ansi\ansicpg932\cocoartf2513 +\cocoatextscaling0\cocoaplatform0{\fonttbl\f0\fnil\fcharset128 HiraKakuProN-W3;} +{\colortbl;\red255\green255\blue255;} +{\*\expandedcolortbl;;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\partightenfactor0 + +\f0\fs92 \cf1 \'82\'dc\'82\'c6\'82\'df\'82\'c6\'8d\'a1\'8c\'e3\'82\'cc\'89\'db\'91\'e8}</string> + <key>VerticalPad</key> + <real>0.0</real> + </dict> + </dict> + <dict> + <key>Class</key> + <string>Group</string> + <key>Graphics</key> + <array> + <dict> + <key>Class</key> + <string>LineGraphic</string> + <key>ID</key> + <integer>5032</integer> + <key>Points</key> + <array> + <string>{1931.8885147672461, 1565.1707480148552}</string> + <string>{1950.5567611693905, 1564.2376659742974}</string> + <string>{1971.5096364431884, 1567.2911708677486}</string> + </array> + <key>Style</key> + <dict> + <key>stroke</key> + <dict> + <key>Color</key> + <dict> + <key>b</key> + <real>1</real> + <key>g</key> + <real>1</real> + <key>r</key> + <real>1</real> + </dict> + <key>HeadArrow</key> + <string>FilledBall</string> + <key>Legacy</key> + <true/> + <key>TailArrow</key> + <string>0</string> + <key>Width</key> + <real>3</real> + </dict> + </dict> + <key>Tail</key> + <dict> + <key>ID</key> + <integer>5033</integer> + <key>Position</key> + <real>0.32640770077705383</real> + </dict> + </dict> + <dict> + <key>Class</key> + <string>LineGraphic</string> + <key>ID</key> + <integer>5033</integer> + <key>Points</key> + <array> + <string>{1925.1727156249158, 1580.2158841257863}</string> + <string>{1936.2131502966972, 1555.4824400723721}</string> + <string>{1938.2653952099181, 1554.5957837295043}</string> + <string>{1959.4208214492714, 1554.5957837295043}</string> + </array> + <key>Style</key> + <dict> + <key>stroke</key> + <dict> + <key>Color</key> + <dict> + <key>b</key> + <real>1</real> + <key>g</key> + <real>1</real> + <key>r</key> + <real>1</real> + </dict> + <key>HeadArrow</key> + <string>FilledBall</string> + <key>Legacy</key> + <true/> + <key>TailArrow</key> + <string>0</string> + <key>Width</key> + <real>3</real> + </dict> + </dict> + <key>Tail</key> + <dict> + <key>ID</key> + <integer>5034</integer> + <key>Position</key> + <real>0.25490197539329529</real> + </dict> + </dict> + <dict> + <key>Class</key> + <string>LineGraphic</string> + <key>ID</key> + <integer>5034</integer> + <key>Points</key> + <array> + <string>{1912.0729627231049, 1579.9865580059916}</string> + <string>{1949.7974776932929, 1580.6469686796961}</string> + <string>{1963.4504264472444, 1579.9865580059916}</string> + </array> + <key>Style</key> + <dict> + <key>stroke</key> + <dict> + <key>Color</key> + <dict> + <key>b</key> + <real>1</real> + <key>g</key> + <real>1</real> + <key>r</key> + <real>1</real> + </dict> + <key>HeadArrow</key> + <string>FilledBall</string> + <key>Legacy</key> + <true/> + <key>TailArrow</key> + <string>0</string> + <key>Width</key> + <real>3</real> + </dict> + </dict> + </dict> + <dict> + <key>Bounds</key> + <string>{{1908.2488463061477, 1541.9285512950962}, {936.31810863689566, 47.436242233737872}}</string> + <key>Class</key> + <string>ShapedGraphic</string> + <key>ID</key> + <integer>5035</integer> + <key>Style</key> + <dict> + <key>fill</key> + <dict> + <key>Color</key> + <dict> + <key>b</key> + <real>0.80000000000000004</real> + <key>g</key> + <real>0.59999999999999998</real> + <key>r</key> + <real>0.20000000000000001</real> + </dict> + <key>FillType</key> + <integer>2</integer> + <key>GradientAngle</key> + <real>90</real> + <key>GradientColor</key> + <dict> + <key>b</key> + <string>0.8</string> + <key>g</key> + <string>0.4</string> + <key>r</key> + <string>0</string> + </dict> + </dict> + <key>shadow</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + <key>stroke</key> + <dict> + <key>Width</key> + <real>0.5</real> + </dict> + </dict> + </dict> + </array> + <key>ID</key> + <integer>5031</integer> + </dict> + </array> + <key>ID</key> + <integer>5029</integer> + </dict> + <dict> + <key>Bounds</key> + <string>{{1907.7165527420721, 1541.9285512950969}, {936.85040220097289, 469.25256931485865}}</string> + <key>Class</key> + <string>ShapedGraphic</string> + <key>FontInfo</key> + <dict> + <key>Size</key> + <real>30</real> + </dict> + <key>ID</key> + <integer>5036</integer> + <key>Style</key> + <dict> + <key>shadow</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + <key>stroke</key> + <dict> + <key>Width</key> + <real>0.5</real> + </dict> + </dict> + </dict> + </array> + <key>ID</key> + <integer>5027</integer> + </dict> + <dict> + <key>Class</key> + <string>Group</string> + <key>Graphics</key> + <array> + <dict> + <key>Bounds</key> + <string>{{959.01056932894892, 1058.016729974162}, {936.31810863689566, 821.35336581780484}}</string> + <key>Class</key> + <string>ShapedGraphic</string> + <key>FontInfo</key> + <dict> + <key>Color</key> + <dict> + <key>b</key> + <string>0</string> + <key>g</key> + <string>0</string> + <key>r</key> + <string>0</string> + </dict> + <key>Font</key> + <string>HiraKakuProN-W6</string> + <key>Size</key> + <real>30</real> + </dict> + <key>ID</key> + <integer>5018</integer> + <key>Style</key> + <dict> + <key>fill</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + <key>shadow</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + <key>stroke</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + </dict> + <key>Text</key> + <dict> + <key>Align</key> + <integer>0</integer> + <key>Pad</key> + <real>0.0</real> + <key>RTFD</key> + <data> + BAtzdHJlYW10eXBlZIHoA4QBQISE + hBJOU0F0dHJpYnV0ZWRTdHJpbmcA + hIQITlNPYmplY3QAhZKEhIQITlNT + dHJpbmcBlIQBK4GoBOODu1VuaXR5 + 44Gv5LiW55WM5Lit44Gn5L2/55So + 44GV44KM44Gm44GE44KL44Ky44O8 + 44Og44Ko44Oz44K444OzCuODu0Mj + 44GM44K144Od44O844OI44GV44KM + 44Gm44GE44KLCuODu+ODleODrOOD + vOODoOWNmOS9jeOBruWHpueQhuOB + jOihjOOCj+OCjOOAgeOCt+ODs+OC + sOODq+OCueODrOODg+ODieOBp+WL + leS9nOOBl+OBpuOBhOOCi+OBn+OC + geS4puWIl+WHpueQhuOBjOiLpuaJ + iwrjgIDjg7vjg5Xjg6zjg7zjg6Dj + gpLjgb7jgZ/jgZDlh6bnkIbjga9J + RW51bWVyYXRvcuOCkuWIqeeUqOOB + l+OBpuOBhOOCiwrjgIDjg7tTZW5k + L1JlY2lldmXjgarjganjgafjga/p + gJrkv6HjgpLoqJjov7DjgZfjgaXj + gonjgYQK44O7Q2hyaXN0aWXjgavj + gojjgormj4/nlLvjgajpnZ7lkIzm + nJ/jgarkuKbliJflh6bnkIbjgoTp + gJrkv6HjgYzlj6/og70K44CA44O7 + VGFrZS9QdXQvUGVla+OCkuWIqeeU + qOOBl+OBn+WIhuaVo+ODl+ODreOC + sOODqeODn+ODs+OCsArjgIDjg7vj + gZPjgozjgonjgpLkvb/jgaPjgabj + g63jg7zjgqvjg6vjgavoqJjov7Dj + gZfjgIHjgZ3jgozjgpLntYTjgb/l + kIjjgo/jgZvjgovjgZPjgajjgavj + gojjgaPjgabliIbmlaPjg5fjg63j + grDjg6njg5/jg7PjgrDjgYzlj6/o + g70KCuODu0phdmHjgpJDI+S4iuOB + p+WRvOOBs+WHuuOBmeaWueW8jwrj + gIDjg7thbm5vdGF0aW9u44GM5Yip + 55So44Gn44GN44Gq44GECuODu1Vu + aXR544Gr44GC44KLamFy44OV44Kh + 44Kk44Or44GL44KJSmF2YeOBruOD + oeOCveODg+ODieOCkuWRvOOBs+WH + uuOBmeapn+iDvQrjgIDjg7tzdHJp + bmfjgafjg6rjgr3jg7zjgrnjg4fj + gqPjg6zjgq/jg4jjg6rjgpLmpJzn + tKLjgZfkvb/nlKgK44CA44O76auY + 6YCf5YyW44GM5rGC44KB44KJ44KM + 44KL5Lim5YiX5YiG5pWj44OX44Ot + 44Kw44Op44Of44Oz44Kw44Gr44Gv + 5LiN6YGpCuODu0phdmHjgahDI+OB + r+iomOi/sOaWueazleOBjOS8vOOB + puOBhOOCi+OBn+OCgeOAgeenu+ak + jeOBjOihjOOBhOOChOOBmeOBhArj + g7tUaHJlYWRQb29s44KSQyPjgafn + tbHkuIDjgafjgY3jgosK44O7Q2hy + aXN0aWXjga9KYXZhOeOBi+OCiemW + i+eZuuOBleOCjOOBpuOBhOOBn+OB + n+OCgeOAgemdnuaOqOWlqOOBquOC + s+ODvOODieOBjOWQq+OBvuOCjOOB + puOBhOOCiwrjgIDjg7tNZXNzYWdl + UGFja+OBruODkOODvOOCuOODp+OD + s+OCouODg+ODl+OAgVRhc2vjgbjj + ga7lr77lv5yGhAJpSQGB8AGShISE + DE5TRGljdGlvbmFyeQCUhAFpA5KE + lpYHTlNDb2xvcoaShISEB05TQ29s + b3IAlIQBYwGEBGZmZmYAAAABhpKE + lpYQTlNQYXJhZ3JhcGhTdHlsZYaS + hISEF05TTXV0YWJsZVBhcmFncmFw + aFN0eWxlAISEEE5TUGFyYWdyYXBo + U3R5bGUAlIQEQ0NAUwAAhISEB05T + QXJyYXkAlJkMkoSEhAlOU1RleHRU + YWIAlIQCQ2YAHIaShKOiADiGkoSj + ogBUhpKEo6IAcIaShKOiAIGMAIaS + hKOiAIGoAIaShKOiAIHEAIaShKOi + AIHgAIaShKOiAIH8AIaShKOiAIEY + AYaShKOiAIE0AYaShKOiAIFQAYaG + AIaShJaWBk5TRm9udIaShISEBk5T + Rm9udB6UmSiEBVs0MGNdBgAAACAA + AAD//kgAaQByAGEASwBhAGsAdQBQ + AHIAbwBOAC0AVwA2AIQBZh6bAJsB + mwCbAIaGhg== + </data> + <key>Text</key> + <string>{\rtf1\ansi\ansicpg932\cocoartf2513 +\cocoatextscaling0\cocoaplatform0{\fonttbl\f0\fnil\fcharset128 HiraKakuProN-W6;} +{\colortbl;\red255\green255\blue255;\red0\green0\blue0;} +{\*\expandedcolortbl;;\csgenericrgb\c0\c0\c0;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\partightenfactor0 + +\f0\b\fs60 \cf2 \'81\'45Unity\'82\'cd\'90\'a2\'8a\'45\'92\'86\'82\'c5\'8e\'67\'97\'70\'82\'b3\'82\'ea\'82\'c4\'82\'a2\'82\'e9\'83\'51\'81\'5b\'83\'80\'83\'47\'83\'93\'83\'57\'83\'93\ +\'81\'45C#\'82\'aa\'83\'54\'83\'7c\'81\'5b\'83\'67\'82\'b3\'82\'ea\'82\'c4\'82\'a2\'82\'e9\ +\'81\'45\'83\'74\'83\'8c\'81\'5b\'83\'80\'92\'50\'88\'ca\'82\'cc\'8f\'88\'97\'9d\'82\'aa\'8d\'73\'82\'ed\'82\'ea\'81\'41\'83\'56\'83\'93\'83\'4f\'83\'8b\'83\'58\'83\'8c\'83\'62\'83\'68\'82\'c5\'93\'ae\'8d\'ec\'82\'b5\'82\'c4\'82\'a2\'82\'e9\'82\'bd\'82\'df\'95\'c0\'97\'f1\'8f\'88\'97\'9d\'82\'aa\'8b\'ea\'8e\'e8\ +\'81\'40\'81\'45\'83\'74\'83\'8c\'81\'5b\'83\'80\'82\'f0\'82\'dc\'82\'bd\'82\'ae\'8f\'88\'97\'9d\'82\'cdIEnumerator\'82\'f0\'97\'98\'97\'70\'82\'b5\'82\'c4\'82\'a2\'82\'e9\ +\'81\'40\'81\'45Send/Recieve\'82\'c8\'82\'c7\'82\'c5\'82\'cd\'92\'ca\'90\'4d\'82\'f0\'8b\'4c\'8f\'71\'82\'b5\'82\'c3\'82\'e7\'82\'a2\ +\'81\'45Christie\'82\'c9\'82\'e6\'82\'e8\'95\'60\'89\'e6\'82\'c6\'94\'f1\'93\'af\'8a\'fa\'82\'c8\'95\'c0\'97\'f1\'8f\'88\'97\'9d\'82\'e2\'92\'ca\'90\'4d\'82\'aa\'89\'c2\'94\'5c\ +\'81\'40\'81\'45Take/Put/Peek\'82\'f0\'97\'98\'97\'70\'82\'b5\'82\'bd\'95\'aa\'8e\'55\'83\'76\'83\'8d\'83\'4f\'83\'89\'83\'7e\'83\'93\'83\'4f\ +\'81\'40\'81\'45\'82\'b1\'82\'ea\'82\'e7\'82\'f0\'8e\'67\'82\'c1\'82\'c4\'83\'8d\'81\'5b\'83\'4a\'83\'8b\'82\'c9\'8b\'4c\'8f\'71\'82\'b5\'81\'41\'82\'bb\'82\'ea\'82\'f0\'91\'67\'82\'dd\'8d\'87\'82\'ed\'82\'b9\'82\'e9\'82\'b1\'82\'c6\'82\'c9\'82\'e6\'82\'c1\'82\'c4\'95\'aa\'8e\'55\'83\'76\'83\'8d\'83\'4f\'83\'89\'83\'7e\'83\'93\'83\'4f\'82\'aa\'89\'c2\'94\'5c\ +\ +\'81\'45Java\'82\'f0C#\'8f\'e3\'82\'c5\'8c\'c4\'82\'d1\'8f\'6f\'82\'b7\'95\'fb\'8e\'ae\ +\'81\'40\'81\'45annotation\'82\'aa\'97\'98\'97\'70\'82\'c5\'82\'ab\'82\'c8\'82\'a2\ +\'81\'45Unity\'82\'c9\'82\'a0\'82\'e9jar\'83\'74\'83\'40\'83\'43\'83\'8b\'82\'a9\'82\'e7Java\'82\'cc\'83\'81\'83\'5c\'83\'62\'83\'68\'82\'f0\'8c\'c4\'82\'d1\'8f\'6f\'82\'b7\'8b\'40\'94\'5c\ +\'81\'40\'81\'45string\'82\'c5\'83\'8a\'83\'5c\'81\'5b\'83\'58\'83\'66\'83\'42\'83\'8c\'83\'4e\'83\'67\'83\'8a\'82\'f0\'8c\'9f\'8d\'f5\'82\'b5\'8e\'67\'97\'70\ +\'81\'40\'81\'45\'8d\'82\'91\'ac\'89\'bb\'82\'aa\'8b\'81\'82\'df\'82\'e7\'82\'ea\'82\'e9\'95\'c0\'97\'f1\'95\'aa\'8e\'55\'83\'76\'83\'8d\'83\'4f\'83\'89\'83\'7e\'83\'93\'83\'4f\'82\'c9\'82\'cd\'95\'73\'93\'4b\ +\'81\'45Java\'82\'c6C#\'82\'cd\'8b\'4c\'8f\'71\'95\'fb\'96\'40\'82\'aa\'8e\'97\'82\'c4\'82\'a2\'82\'e9\'82\'bd\'82\'df\'81\'41\'88\'da\'90\'41\'82\'aa\'8d\'73\'82\'a2\'82\'e2\'82\'b7\'82\'a2\ +\'81\'45ThreadPool\'82\'f0C#\'82\'c5\'93\'9d\'88\'ea\'82\'c5\'82\'ab\'82\'e9\ +\'81\'45Christie\'82\'cdJava9\'82\'a9\'82\'e7\'8a\'4a\'94\'ad\'82\'b3\'82\'ea\'82\'c4\'82\'a2\'82\'bd\'82\'bd\'82\'df\'81\'41\'94\'f1\'90\'84\'8f\'a7\'82\'c8\'83\'52\'81\'5b\'83\'68\'82\'aa\'8a\'dc\'82\'dc\'82\'ea\'82\'c4\'82\'a2\'82\'e9\ +\'81\'40\'81\'45MessagePack\'82\'cc\'83\'6f\'81\'5b\'83\'57\'83\'87\'83\'93\'83\'41\'83\'62\'83\'76\'81\'41Task\'82\'d6\'82\'cc\'91\'ce\'89\'9e}</string> + <key>VerticalPad</key> + <real>1</real> + </dict> + <key>TextPlacement</key> + <integer>0</integer> + </dict> + <dict> + <key>Class</key> + <string>Group</string> + <key>Graphics</key> + <array> + <dict> + <key>Bounds</key> + <string>{{1053.4389065477255, 1007.0925287526497}, {802.20473168797366, 50.924201221512725}}</string> + <key>Class</key> + <string>ShapedGraphic</string> + <key>FontInfo</key> + <dict> + <key>Color</key> + <dict> + <key>b</key> + <string>1</string> + <key>g</key> + <string>1</string> + <key>r</key> + <string>1</string> + </dict> + <key>Font</key> + <string>HiraKakuProN-W3</string> + <key>Size</key> + <real>46</real> + </dict> + <key>ID</key> + <integer>5020</integer> + <key>Style</key> + <dict> + <key>fill</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + <key>shadow</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + <key>stroke</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + </dict> + <key>Text</key> + <dict> + <key>Align</key> + <integer>0</integer> + <key>Pad</key> + <real>0.0</real> + <key>Text</key> + <string>{\rtf1\ansi\ansicpg932\cocoartf2513 +\cocoatextscaling0\cocoaplatform0{\fonttbl\f0\fnil\fcharset128 HiraKakuProN-W3;} +{\colortbl;\red255\green255\blue255;} +{\*\expandedcolortbl;;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\partightenfactor0 + +\f0\fs92 \cf1 C#\'82\'d6\'8f\'91\'82\'ab\'8a\'b7\'82\'a6\'82\'e9\'97\'98\'93\'5f}</string> + <key>VerticalPad</key> + <real>0.0</real> + </dict> + </dict> + <dict> + <key>Class</key> + <string>Group</string> + <key>Graphics</key> + <array> + <dict> + <key>Class</key> + <string>LineGraphic</string> + <key>ID</key> + <integer>5022</integer> + <key>Points</key> + <array> + <string>{982.65023779004753, 1022.4548042109631}</string> + <string>{1001.3184841921918, 1021.5217221704052}</string> + <string>{1022.2713594659901, 1024.5752270638563}</string> + </array> + <key>Style</key> + <dict> + <key>stroke</key> + <dict> + <key>Color</key> + <dict> + <key>b</key> + <real>1</real> + <key>g</key> + <real>1</real> + <key>r</key> + <real>1</real> + </dict> + <key>HeadArrow</key> + <string>FilledBall</string> + <key>Legacy</key> + <true/> + <key>TailArrow</key> + <string>0</string> + <key>Width</key> + <real>3</real> + </dict> + </dict> + <key>Tail</key> + <dict> + <key>ID</key> + <integer>5023</integer> + <key>Position</key> + <real>0.32640770077705383</real> + </dict> + </dict> + <dict> + <key>Class</key> + <string>LineGraphic</string> + <key>ID</key> + <integer>5023</integer> + <key>Points</key> + <array> + <string>{975.93443864771746, 1037.499940321894}</string> + <string>{986.97487331949856, 1012.7664962684798}</string> + <string>{989.02711823271966, 1011.8798399256125}</string> + <string>{1010.1825444720725, 1011.8798399256125}</string> + </array> + <key>Style</key> + <dict> + <key>stroke</key> + <dict> + <key>Color</key> + <dict> + <key>b</key> + <real>1</real> + <key>g</key> + <real>1</real> + <key>r</key> + <real>1</real> + </dict> + <key>HeadArrow</key> + <string>FilledBall</string> + <key>Legacy</key> + <true/> + <key>TailArrow</key> + <string>0</string> + <key>Width</key> + <real>3</real> + </dict> + </dict> + <key>Tail</key> + <dict> + <key>ID</key> + <integer>5024</integer> + <key>Position</key> + <real>0.25490197539329529</real> + </dict> + </dict> + <dict> + <key>Class</key> + <string>LineGraphic</string> + <key>ID</key> + <integer>5024</integer> + <key>Points</key> + <array> + <string>{962.83468574590643, 1037.2706142020993}</string> + <string>{1000.5592007160947, 1037.9310248758038}</string> + <string>{1014.2121494700459, 1037.2706142020993}</string> + </array> + <key>Style</key> + <dict> + <key>stroke</key> + <dict> + <key>Color</key> + <dict> + <key>b</key> + <real>1</real> + <key>g</key> + <real>1</real> + <key>r</key> + <real>1</real> + </dict> + <key>HeadArrow</key> + <string>FilledBall</string> + <key>Legacy</key> + <true/> + <key>TailArrow</key> + <string>0</string> + <key>Width</key> + <real>3</real> + </dict> + </dict> + </dict> + <dict> + <key>Bounds</key> + <string>{{959.01056932894971, 999.21260749120393}, {936.31810863689566, 47.436242233737872}}</string> + <key>Class</key> + <string>ShapedGraphic</string> + <key>ID</key> + <integer>5025</integer> + <key>Style</key> + <dict> + <key>fill</key> + <dict> + <key>Color</key> + <dict> + <key>b</key> + <real>0.80000000000000004</real> + <key>g</key> + <real>0.59999999999999998</real> + <key>r</key> + <real>0.20000000000000001</real> + </dict> + <key>FillType</key> + <integer>2</integer> + <key>GradientAngle</key> + <real>90</real> + <key>GradientColor</key> + <dict> + <key>b</key> + <string>0.8</string> + <key>g</key> + <string>0.4</string> + <key>r</key> + <string>0</string> + </dict> + </dict> + <key>shadow</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + <key>stroke</key> + <dict> + <key>Width</key> + <real>0.5</real> + </dict> + </dict> + </dict> + </array> + <key>ID</key> + <integer>5021</integer> + </dict> + </array> + <key>ID</key> + <integer>5019</integer> + </dict> + <dict> + <key>Bounds</key> + <string>{{958.47827576487316, 999.21260749120484}, {936.85040220097289, 1011.9685131187507}}</string> + <key>Class</key> + <string>ShapedGraphic</string> + <key>FontInfo</key> + <dict> + <key>Size</key> + <real>30</real> + </dict> + <key>ID</key> + <integer>5026</integer> + <key>Style</key> + <dict> + <key>shadow</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + <key>stroke</key> + <dict> + <key>Width</key> + <real>0.5</real> + </dict> + </dict> + </dict> + </array> + <key>ID</key> + <integer>5017</integer> + </dict> + <dict> + <key>Class</key> + <string>Group</string> + <key>Graphics</key> + <array> + <dict> + <key>Bounds</key> + <string>{{1908.2488463061472, 277.07184099876758}, {936.31810863689566, 1245.4887618682865}}</string> + <key>Class</key> + <string>ShapedGraphic</string> + <key>FontInfo</key> + <dict> + <key>Color</key> + <dict> + <key>b</key> + <string>0</string> + <key>g</key> + <string>0</string> + <key>r</key> + <string>0</string> + </dict> + <key>Font</key> + <string>HiraKakuProN-W6</string> + <key>Size</key> + <real>30</real> + </dict> + <key>ID</key> + <integer>5008</integer> + <key>Style</key> + <dict> + <key>fill</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + <key>shadow</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + <key>stroke</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + </dict> + <key>Text</key> + <dict> + <key>Align</key> + <integer>0</integer> + <key>Pad</key> + <real>0.0</real> + <key>Text</key> + <string>{\rtf1\ansi\ansicpg932\cocoartf2513 +\cocoatextscaling0\cocoaplatform0{\fonttbl\f0\fnil\fcharset128 HiraKakuProN-W6;} +{\colortbl;\red255\green255\blue255;\red0\green0\blue0;} +{\*\expandedcolortbl;;\csgenericrgb\c0\c0\c0;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\partightenfactor0 + +\f0\b\fs60 \cf2 \'81\'45Unity\'82\'c5\'82\'cd\'81\'41\'83\'76\'83\'8d\'83\'4f\'83\'89\'83\'80\'82\'cc\'8e\'c0\'8d\'73\'82\'c9\'82\'cdMain\'8a\'d6\'90\'94\'82\'c5\'82\'cd\'82\'c8\'82\'ad\'81\'41MonoBehaviour\'82\'f0\'8c\'70\'8f\'b3\'82\'b5\'82\'c4\'97\'98\'97\'70\'82\'c5\'82\'ab\'82\'e9\'81\'41Start\'8a\'d6\'90\'94\'82\'e2Update\'8a\'d6\'90\'94\'82\'f0\'97\'98\'97\'70\'82\'b7\'82\'e9\ +\ +\ +\ +\ +\ +\ +\ +\ +\ +\ +\ +\ +\ +\ +\ +\ +\ +\ +\ +\ +\'81\'45UnityAPI\'82\'cdMainThread\'8a\'4f\'82\'c5\'82\'cd\'97\'98\'97\'70\'82\'c5\'82\'ab\'82\'c8\'82\'a2\ +\'81\'45\'8c\'9f\'8f\'d8\'82\'cc\'82\'bd\'82\'df\'82\'c9CodeGear\'82\'c5\'8f\'88\'97\'9d\'82\'f0MainThread\'82\'c9\'88\'da\'8f\'f7\'82\'b5GameObject\'82\'f0\'91\'80\'8d\'ec\ +\'81\'45\'8a\'c8\'88\'d5\'93\'49\'82\'c9\'8c\'76\'91\'aa\'82\'f0\'8d\'73\'82\'c1\'82\'bd\'82\'c6\'82\'b1\'82\'eb\'81\'41\'95\'bd\'8b\'cf60fps\'82\'c5\'82\'cc\'93\'ae\'8d\'ec\'82\'f0\'8a\'6d\'94\'46\'82\'c5\'82\'ab\'82\'bd\ +\'81\'45Unity\'82\'c5\'8f\'5c\'95\'aa\'82\'c9\'83\'49\'83\'93\'83\'89\'83\'43\'83\'93\'83\'51\'81\'5b\'83\'80\'82\'cc\'8a\'4a\'94\'ad\'82\'aa\'89\'c2\'94\'5c\'82\'c5\'82\'a0\'82\'e9\'82\'c6\'95\'aa\'82\'a9\'82\'c1\'82\'bd}</string> + <key>VerticalPad</key> + <real>1</real> + </dict> + <key>TextPlacement</key> + <integer>0</integer> + </dict> + <dict> + <key>Class</key> + <string>Group</string> + <key>Graphics</key> + <array> + <dict> + <key>Bounds</key> + <string>{{2002.6771835249242, 226.14763977725465}, {802.20473168797366, 50.924201221512725}}</string> + <key>Class</key> + <string>ShapedGraphic</string> + <key>FontInfo</key> + <dict> + <key>Color</key> + <dict> + <key>b</key> + <string>1</string> + <key>g</key> + <string>1</string> + <key>r</key> + <string>1</string> + </dict> + <key>Font</key> + <string>HiraKakuProN-W3</string> + <key>Size</key> + <real>46</real> + </dict> + <key>ID</key> + <integer>5010</integer> + <key>Style</key> + <dict> + <key>fill</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + <key>shadow</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + <key>stroke</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + </dict> + <key>Text</key> + <dict> + <key>Align</key> + <integer>0</integer> + <key>Pad</key> + <real>0.0</real> + <key>Text</key> + <string>{\rtf1\ansi\ansicpg932\cocoartf2513 +\cocoatextscaling0\cocoaplatform0{\fonttbl\f0\fnil\fcharset128 HiraKakuProN-W3;} +{\colortbl;\red255\green255\blue255;} +{\*\expandedcolortbl;;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\partightenfactor0 + +\f0\fs92 \cf1 Unity\'82\'c5\'82\'cc\'93\'ae\'8d\'ec}</string> + <key>VerticalPad</key> + <real>0.0</real> + </dict> + </dict> + <dict> + <key>Class</key> + <string>Group</string> + <key>Graphics</key> + <array> + <dict> + <key>Class</key> + <string>LineGraphic</string> + <key>ID</key> + <integer>5012</integer> + <key>Points</key> + <array> + <string>{1931.8885147672461, 241.50991523556789}</string> + <string>{1950.5567611693905, 240.57683319501029}</string> + <string>{1971.5096364431884, 243.63033808846149}</string> + </array> + <key>Style</key> + <dict> + <key>stroke</key> + <dict> + <key>Color</key> + <dict> + <key>b</key> + <real>1</real> + <key>g</key> + <real>1</real> + <key>r</key> + <real>1</real> + </dict> + <key>HeadArrow</key> + <string>FilledBall</string> + <key>Legacy</key> + <true/> + <key>TailArrow</key> + <string>0</string> + <key>Width</key> + <real>3</real> + </dict> + </dict> + <key>Tail</key> + <dict> + <key>ID</key> + <integer>5013</integer> + <key>Position</key> + <real>0.32640770077705383</real> + </dict> + </dict> + <dict> + <key>Class</key> + <string>LineGraphic</string> + <key>ID</key> + <integer>5013</integer> + <key>Points</key> + <array> + <string>{1925.1727156249158, 256.55505134649906}</string> + <string>{1936.2131502966972, 231.82160729308475}</string> + <string>{1938.2653952099181, 230.93495095021717}</string> + <string>{1959.4208214492714, 230.93495095021717}</string> + </array> + <key>Style</key> + <dict> + <key>stroke</key> + <dict> + <key>Color</key> + <dict> + <key>b</key> + <real>1</real> + <key>g</key> + <real>1</real> + <key>r</key> + <real>1</real> + </dict> + <key>HeadArrow</key> + <string>FilledBall</string> + <key>Legacy</key> + <true/> + <key>TailArrow</key> + <string>0</string> + <key>Width</key> + <real>3</real> + </dict> + </dict> + <key>Tail</key> + <dict> + <key>ID</key> + <integer>5014</integer> + <key>Position</key> + <real>0.25490197539329529</real> + </dict> + </dict> + <dict> + <key>Class</key> + <string>LineGraphic</string> + <key>ID</key> + <integer>5014</integer> + <key>Points</key> + <array> + <string>{1912.0729627231049, 256.32572522670444}</string> + <string>{1949.7974776932929, 256.98613590040895}</string> + <string>{1963.4504264472444, 256.32572522670444}</string> + </array> + <key>Style</key> + <dict> + <key>stroke</key> + <dict> + <key>Color</key> + <dict> + <key>b</key> + <real>1</real> + <key>g</key> + <real>1</real> + <key>r</key> + <real>1</real> + </dict> + <key>HeadArrow</key> + <string>FilledBall</string> + <key>Legacy</key> + <true/> + <key>TailArrow</key> + <string>0</string> + <key>Width</key> + <real>3</real> + </dict> + </dict> + </dict> + <dict> + <key>Bounds</key> + <string>{{1908.2488463061477, 218.26771851580907}, {936.31810863689566, 47.436242233737872}}</string> + <key>Class</key> + <string>ShapedGraphic</string> + <key>ID</key> + <integer>5015</integer> + <key>Style</key> + <dict> + <key>fill</key> + <dict> + <key>Color</key> + <dict> + <key>b</key> + <real>0.80000000000000004</real> + <key>g</key> + <real>0.59999999999999998</real> + <key>r</key> + <real>0.20000000000000001</real> + </dict> + <key>FillType</key> + <integer>2</integer> + <key>GradientAngle</key> + <real>90</real> + <key>GradientColor</key> + <dict> + <key>b</key> + <string>0.8</string> + <key>g</key> + <string>0.4</string> + <key>r</key> + <string>0</string> + </dict> + </dict> + <key>shadow</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + <key>stroke</key> + <dict> + <key>Width</key> + <real>0.5</real> + </dict> + </dict> + </dict> + </array> + <key>ID</key> + <integer>5011</integer> + </dict> + </array> + <key>ID</key> + <integer>5009</integer> + </dict> + <dict> + <key>Bounds</key> + <string>{{1907.7165527420716, 218.26771851581009}, {936.85040220097289, 1315.6314671312862}}</string> + <key>Class</key> + <string>ShapedGraphic</string> + <key>FontInfo</key> + <dict> + <key>Size</key> + <real>30</real> + </dict> + <key>ID</key> + <integer>5016</integer> + <key>Style</key> + <dict> + <key>shadow</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + <key>stroke</key> + <dict> + <key>Width</key> + <real>0.5</real> + </dict> + </dict> + </dict> + </array> + <key>ID</key> + <integer>5007</integer> + </dict> + <dict> + <key>Class</key> + <string>Group</string> + <key>Graphics</key> + <array> + <dict> + <key>Bounds</key> + <string>{{957.17957446617186, 266.45669533098754}, {936.31810863689566, 710.07874660013238}}</string> + <key>Class</key> + <string>ShapedGraphic</string> + <key>FontInfo</key> + <dict> + <key>Color</key> + <dict> + <key>b</key> + <string>0</string> + <key>g</key> + <string>0</string> + <key>r</key> + <string>0</string> + </dict> + <key>Font</key> + <string>HiraKakuProN-W6</string> + <key>Size</key> + <real>30</real> + </dict> + <key>ID</key> + <integer>4998</integer> + <key>Style</key> + <dict> + <key>fill</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + <key>shadow</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + <key>stroke</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + </dict> + <key>Text</key> + <dict> + <key>Align</key> + <integer>0</integer> + <key>Pad</key> + <real>0.0</real> + <key>RTFD</key> + <data> + BAtzdHJlYW10eXBlZIHoA4QBQISE + hBJOU0F0dHJpYnV0ZWRTdHJpbmcA + hIQITlNPYmplY3QAhZKEhIQITlNT + dHJpbmcBlIQBK4H0AuODu0RhdGFH + ZWFy44KSREdN44Gr5qC857SN44CB + 5Y+W44KK5Ye644GZ44Gf44KB44Gu + QVBJ44GM44GC44KLCuOAgOODu1B1 + dCBRdWV1ZeOBq0RhdGFHZWFy44KS + 6L+95YqgCuOAgOODu1Rha2UgUXVl + dWXjgYvjgonlj5bjgorlh7rjgZcK + 44CA44O7UGVlayBRdWV1ZeOBi+OC + ieWPluOCiuWHuuOBleOBmuiqreOB + v+WHuuOBlwoK44O7Q29kZUdlYXLj + gavoqJjov7DjgZXjgozjgZ/lpInm + lbDjgpJEYXRhR2VhcuOBqOOBl+OB + puaJseOBhuOBn+OCgeOBq+WkieaV + sOOBq2Fubm90YXRpb27jgpLjgaTj + gZHjgosK44O7YW5ub3RhdGlvbuOB + qOOBr+OCr+ODqeOCueOChOODleOC + o+ODvOODq+ODieOAgeODoeOCveOD + g+ODieOBq+OBpOOBkeOCiwrjg7vj + g6bjg7zjgrblrprnvqnlj6/og73j + gaptYXRh6KiI566X5bGe5oCnCuOD + u0NocmlzdGll44Gn6YCa5L+h44OR + 44K/44O844Oz44KS5oyH5a6a44GZ + 44KL6Zqb44Gr5L2/55SoCuOAgOOD + u1Rha2Ug5YWI6aCt44GuRGF0YUdl + YXLjgpLoqq3jgb/ovrzjgb9RdWV1 + ZeOBi+OCieWJiumZpArjgIDjg7tQ + ZWVrIOWFiOmgreOBrkRhdGFHZWFy + 44KS6Kqt44G/6L6844KA44GM5YmK + 6Zmk44Gv44Gb44Ga5Y+C54Wn44GX + 57aa44GR44KLCuOAgOODu1Rha2VG + cm9tIFRha2XjgajlkIzjgZjli5Xk + vZzjgaDjgYzjgIFyZW1vdGXlhYjj + ga5ER03jgpLmjIflrprlj6/og70K + 44CA44O7UGVla0Zyb20gUGVla+OB + qOWQjOOBmOWLleS9nOOBoOOBjOOA + gXJlbW90ZeWFiOOBrkRHTeOCkuaM + h+WumuWPr+iDveOAgIaEAmlJAYF4 + AZKEhIQMTlNEaWN0aW9uYXJ5AJSE + AWkDkoSWlgdOU0NvbG9yhpKEhIQH + TlNDb2xvcgCUhAFjAYQEZmZmZgAA + AAGGkoSWlhBOU1BhcmFncmFwaFN0 + eWxlhpKEhIQXTlNNdXRhYmxlUGFy + YWdyYXBoU3R5bGUAhIQQTlNQYXJh + Z3JhcGhTdHlsZQCUhARDQ0BTAACE + hIQHTlNBcnJheQCUmQyShISECU5T + VGV4dFRhYgCUhAJDZgAchpKEo6IA + OIaShKOiAFSGkoSjogBwhpKEo6IA + gYwAhpKEo6IAgagAhpKEo6IAgcQA + hpKEo6IAgeAAhpKEo6IAgfwAhpKE + o6IAgRgBhpKEo6IAgTQBhpKEo6IA + gVABhoYAhpKElpYGTlNGb250hpKE + hIQGTlNGb250HpSZKIQFWzQwY10G + AAAAIAAAAP/+SABpAHIAYQBLAGEA + awB1AFAAcgBvAE4ALQBXADYAhAFm + HpsAmwGbAJsAhoaG + </data> + <key>Text</key> + <string>{\rtf1\ansi\ansicpg932\cocoartf2513 +\cocoatextscaling0\cocoaplatform0{\fonttbl\f0\fnil\fcharset128 HiraKakuProN-W6;} +{\colortbl;\red255\green255\blue255;\red0\green0\blue0;} +{\*\expandedcolortbl;;\csgenericrgb\c0\c0\c0;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\partightenfactor0 + +\f0\b\fs60 \cf2 \'81\'45DataGear\'82\'f0DGM\'82\'c9\'8a\'69\'94\'5b\'81\'41\'8e\'e6\'82\'e8\'8f\'6f\'82\'b7\'82\'bd\'82\'df\'82\'ccAPI\'82\'aa\'82\'a0\'82\'e9\ +\'81\'40\'81\'45Put Queue\'82\'c9DataGear\'82\'f0\'92\'c7\'89\'c1\ +\'81\'40\'81\'45Take Queue\'82\'a9\'82\'e7\'8e\'e6\'82\'e8\'8f\'6f\'82\'b5\ +\'81\'40\'81\'45Peek Queue\'82\'a9\'82\'e7\'8e\'e6\'82\'e8\'8f\'6f\'82\'b3\'82\'b8\'93\'c7\'82\'dd\'8f\'6f\'82\'b5\ +\ +\'81\'45CodeGear\'82\'c9\'8b\'4c\'8f\'71\'82\'b3\'82\'ea\'82\'bd\'95\'cf\'90\'94\'82\'f0DataGear\'82\'c6\'82\'b5\'82\'c4\'88\'b5\'82\'a4\'82\'bd\'82\'df\'82\'c9\'95\'cf\'90\'94\'82\'c9annotation\'82\'f0\'82\'c2\'82\'af\'82\'e9\ +\'81\'45annotation\'82\'c6\'82\'cd\'83\'4e\'83\'89\'83\'58\'82\'e2\'83\'74\'83\'42\'81\'5b\'83\'8b\'83\'68\'81\'41\'83\'81\'83\'5c\'83\'62\'83\'68\'82\'c9\'82\'c2\'82\'af\'82\'e9\ +\'81\'45\'83\'86\'81\'5b\'83\'55\'92\'e8\'8b\'60\'89\'c2\'94\'5c\'82\'c8mata\'8c\'76\'8e\'5a\'91\'ae\'90\'ab\ +\'81\'45Christie\'82\'c5\'92\'ca\'90\'4d\'83\'70\'83\'5e\'81\'5b\'83\'93\'82\'f0\'8e\'77\'92\'e8\'82\'b7\'82\'e9\'8d\'db\'82\'c9\'8e\'67\'97\'70\ +\'81\'40\'81\'45Take \'90\'e6\'93\'aa\'82\'ccDataGear\'82\'f0\'93\'c7\'82\'dd\'8d\'9e\'82\'ddQueue\'82\'a9\'82\'e7\'8d\'ed\'8f\'9c\ +\'81\'40\'81\'45Peek \'90\'e6\'93\'aa\'82\'ccDataGear\'82\'f0\'93\'c7\'82\'dd\'8d\'9e\'82\'de\'82\'aa\'8d\'ed\'8f\'9c\'82\'cd\'82\'b9\'82\'b8\'8e\'51\'8f\'c6\'82\'b5\'91\'b1\'82\'af\'82\'e9\ +\'81\'40\'81\'45TakeFrom Take\'82\'c6\'93\'af\'82\'b6\'93\'ae\'8d\'ec\'82\'be\'82\'aa\'81\'41remote\'90\'e6\'82\'ccDGM\'82\'f0\'8e\'77\'92\'e8\'89\'c2\'94\'5c\ +\'81\'40\'81\'45PeekFrom Peek\'82\'c6\'93\'af\'82\'b6\'93\'ae\'8d\'ec\'82\'be\'82\'aa\'81\'41remote\'90\'e6\'82\'ccDGM\'82\'f0\'8e\'77\'92\'e8\'89\'c2\'94\'5c\'81\'40}</string> + <key>VerticalPad</key> + <real>1</real> + </dict> + <key>TextPlacement</key> + <integer>0</integer> + </dict> + <dict> + <key>Class</key> + <string>Group</string> + <key>Graphics</key> + <array> + <dict> + <key>Bounds</key> + <string>{{1054.132333897498, 221.9803722856407}, {802.20473168797366, 51.733664314227305}}</string> + <key>Class</key> + <string>ShapedGraphic</string> + <key>FontInfo</key> + <dict> + <key>Color</key> + <dict> + <key>b</key> + <string>1</string> + <key>g</key> + <string>1</string> + <key>r</key> + <string>1</string> + </dict> + <key>Font</key> + <string>HiraKakuProN-W3</string> + <key>Size</key> + <real>46</real> + </dict> + <key>ID</key> + <integer>5000</integer> + <key>Style</key> + <dict> + <key>fill</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + <key>shadow</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + <key>stroke</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + </dict> + <key>Text</key> + <dict> + <key>Align</key> + <integer>0</integer> + <key>Pad</key> + <real>0.0</real> + <key>Text</key> + <string>{\rtf1\ansi\ansicpg932\cocoartf2513 +\cocoatextscaling0\cocoaplatform0{\fonttbl\f0\fnil\fcharset128 HiraKakuProN-W3;} +{\colortbl;\red255\green255\blue255;} +{\*\expandedcolortbl;;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\partightenfactor0 + +\f0\fs92 \cf1 DataGearManager\'82\'ccAPI}</string> + <key>VerticalPad</key> + <real>0.0</real> + </dict> + </dict> + <dict> + <key>Class</key> + <string>Group</string> + <key>Graphics</key> + <array> + <dict> + <key>Class</key> + <string>LineGraphic</string> + <key>ID</key> + <integer>5002</integer> + <key>Points</key> + <array> + <string>{983.30369127435597, 237.67791543601396}</string> + <string>{1002.0119115419645, 236.63892422545831}</string> + <string>{1022.9647868157626, 239.74096595317249}</string> + </array> + <key>Style</key> + <dict> + <key>stroke</key> + <dict> + <key>Color</key> + <dict> + <key>b</key> + <real>1</real> + <key>g</key> + <real>1</real> + <key>r</key> + <real>1</real> + </dict> + <key>HeadArrow</key> + <string>FilledBall</string> + <key>Legacy</key> + <true/> + <key>TailArrow</key> + <string>0</string> + <key>Width</key> + <real>3</real> + </dict> + </dict> + <key>Tail</key> + <dict> + <key>ID</key> + <integer>5003</integer> + <key>Position</key> + <real>0.32640770077705383</real> + </dict> + </dict> + <dict> + <key>Class</key> + <string>LineGraphic</string> + <key>ID</key> + <integer>5003</integer> + <key>Points</key> + <array> + <string>{976.62797858837746, 252.87112534652593}</string> + <string>{987.66830066927093, 227.74453006824373}</string> + <string>{989.72054558249215, 226.84377992383855}</string> + <string>{1010.875971821845, 226.84377992383855}</string> + </array> + <key>Style</key> + <dict> + <key>stroke</key> + <dict> + <key>Color</key> + <dict> + <key>b</key> + <real>1</real> + <key>g</key> + <real>1</real> + <key>r</key> + <real>1</real> + </dict> + <key>HeadArrow</key> + <string>FilledBall</string> + <key>Legacy</key> + <true/> + <key>TailArrow</key> + <string>0</string> + <key>Width</key> + <real>3</real> + </dict> + </dict> + <key>Tail</key> + <dict> + <key>ID</key> + <integer>5004</integer> + <key>Position</key> + <real>0.25490197539329529</real> + </dict> + </dict> + <dict> + <key>Class</key> + <string>LineGraphic</string> + <key>ID</key> + <integer>5004</integer> + <key>Points</key> + <array> + <string>{963.52811309567892, 252.63815198250521}</string> + <string>{1001.2526280658672, 253.30906018103244}</string> + <string>{1014.9055768198184, 252.63815198250521}</string> + </array> + <key>Style</key> + <dict> + <key>stroke</key> + <dict> + <key>Color</key> + <dict> + <key>b</key> + <real>1</real> + <key>g</key> + <real>1</real> + <key>r</key> + <real>1</real> + </dict> + <key>HeadArrow</key> + <string>FilledBall</string> + <key>Legacy</key> + <true/> + <key>TailArrow</key> + <string>0</string> + <key>Width</key> + <real>3</real> + </dict> + </dict> + </dict> + <dict> + <key>Bounds</key> + <string>{{959.70399667872209, 213.97519613002663}, {936.31810863689566, 48.190262648869265}}</string> + <key>Class</key> + <string>ShapedGraphic</string> + <key>ID</key> + <integer>5005</integer> + <key>Style</key> + <dict> + <key>fill</key> + <dict> + <key>Color</key> + <dict> + <key>b</key> + <real>0.80000000000000004</real> + <key>g</key> + <real>0.59999999999999998</real> + <key>r</key> + <real>0.20000000000000001</real> + </dict> + <key>FillType</key> + <integer>2</integer> + <key>GradientAngle</key> + <real>90</real> + <key>GradientColor</key> + <dict> + <key>b</key> + <string>0.8</string> + <key>g</key> + <string>0.4</string> + <key>r</key> + <string>0</string> + </dict> + </dict> + <key>shadow</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + <key>stroke</key> + <dict> + <key>Width</key> + <real>0.5</real> + </dict> + </dict> + </dict> + </array> + <key>ID</key> + <integer>5001</integer> + </dict> + </array> + <key>ID</key> + <integer>4999</integer> + </dict> + <dict> + <key>Bounds</key> + <string>{{959.17170311464542, 213.97519613002697}, {936.85040220097289, 773.89882858113504}}</string> + <key>Class</key> + <string>ShapedGraphic</string> + <key>FontInfo</key> + <dict> + <key>Size</key> + <real>30</real> + </dict> + <key>ID</key> + <integer>5006</integer> + <key>Style</key> + <dict> + <key>shadow</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + <key>stroke</key> + <dict> + <key>Width</key> + <real>0.5</real> + </dict> + </dict> + </dict> + </array> + <key>ID</key> + <integer>4997</integer> + </dict> + <dict> + <key>Bounds</key> + <string>{{36.850394035136603, 1405.9842647252119}, {871.65355121573123, 600.37796287470906}}</string> + <key>Class</key> + <string>ShapedGraphic</string> + <key>ID</key> + <integer>4996</integer> + <key>ImageID</key> + <integer>33</integer> + <key>Style</key> + <dict> + <key>fill</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + <key>shadow</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + <key>stroke</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + </dict> + </dict> + <dict> + <key>Class</key> + <string>Group</string> + <key>Graphics</key> + <array> + <dict> + <key>Bounds</key> + <string>{{13.288199191623164, 903.52853959608785}, {936.31810863689566, 498.20375658660828}}</string> + <key>Class</key> + <string>ShapedGraphic</string> + <key>FontInfo</key> + <dict> + <key>Color</key> + <dict> + <key>b</key> + <string>0</string> + <key>g</key> + <string>0</string> + <key>r</key> + <string>0</string> + </dict> + <key>Font</key> + <string>HiraKakuProN-W6</string> + <key>Size</key> + <real>30</real> + </dict> + <key>ID</key> + <integer>4985</integer> + <key>Style</key> + <dict> + <key>fill</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + <key>shadow</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + <key>stroke</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + </dict> + <key>Text</key> + <dict> + <key>Align</key> + <integer>0</integer> + <key>Pad</key> + <real>0.0</real> + <key>RTFD</key> + <data> + BAtzdHJlYW10eXBlZIHoA4QBQISE + hBJOU0F0dHJpYnV0ZWRTdHJpbmcA + hIQITlNPYmplY3QAhZKEhIQITlNT + dHJpbmcBlIQBK4HbAeODu0Nocmlz + dGll44Go44GvR2VhcuOBqOOBhOOB + huamguW/teOCkuaMgeOBo+OBn+WI + huaVo+ODleODrOODvOODoOODr+OD + vOOCrwrjgIDjg7tDb2RlR2Vhcijj + gq/jg6njgrnjgIHjg6Hjgr3jg4Pj + g4kpCuOAgOODu0RhdGFHZWFyKOWk + ieaVsOODh+ODvOOCvykK44CA44O7 + Q29kZUdlYXJNYW5hZ2VyKENHTSkg + KG5vZGXjgavnm7jlvZPjgIHlhajj + gabjga5HZWFy44KS566h55CGKQrj + gIDjg7tEYXRhR2Vhck1hbmFnZXIo + REdNKSAoREfjgpJRdWV1ZeOBp+eu + oeeQhikK44O7Q29kZUdlYXLlhoXj + gavoqJjov7DjgZXjgozjgZ9EYXRh + R2VhcuOBjOWFqOOBpuaPg+OBhuOB + qENvZGVHZWFy44Gu5Yem55CG44GM + 6ZaL5aeLCuODu0RhdGFHZWFy44Gv + a2V544GoVmFsdWXjgpLjgbLjgajj + gb7jgajjgb7jgorjgajjgZfjgaZE + R03jgatRdWV1ZeOBqOOBl+OBpuag + vOe0jQrjg7vnm7jmiYtub2Rl44Gu + REdN44GucHJveHnjgajjgZfjgabp + gJrkv6GGhAJpSQGBCQGShISEDE5T + RGljdGlvbmFyeQCUhAFpA5KElpYH + TlNDb2xvcoaShISEB05TQ29sb3IA + lIQBYwGEBGZmZmYAAAABhpKElpYQ + TlNQYXJhZ3JhcGhTdHlsZYaShISE + F05TTXV0YWJsZVBhcmFncmFwaFN0 + eWxlAISEEE5TUGFyYWdyYXBoU3R5 + bGUAlIQEQ0NAUwAAhISEB05TQXJy + YXkAlJkMkoSEhAlOU1RleHRUYWIA + lIQCQ2YAHIaShKOiADiGkoSjogBU + hpKEo6IAcIaShKOiAIGMAIaShKOi + AIGoAIaShKOiAIHEAIaShKOiAIHg + AIaShKOiAIH8AIaShKOiAIEYAYaS + hKOiAIE0AYaShKOiAIFQAYaGAIaS + hJaWBk5TRm9udIaShISEBk5TRm9u + dB6UmSiEBVs0MGNdBgAAACAAAAD/ + /kgAaQByAGEASwBhAGsAdQBQAHIA + bwBOAC0AVwA2AIQBZh6bAJsBmwCb + AIaGhg== + </data> + <key>Text</key> + <string>{\rtf1\ansi\ansicpg932\cocoartf2513 +\cocoatextscaling0\cocoaplatform0{\fonttbl\f0\fnil\fcharset128 HiraKakuProN-W6;} +{\colortbl;\red255\green255\blue255;\red0\green0\blue0;} +{\*\expandedcolortbl;;\csgenericrgb\c0\c0\c0;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\partightenfactor0 + +\f0\b\fs60 \cf2 \'81\'45Christie\'82\'c6\'82\'cdGear\'82\'c6\'82\'a2\'82\'a4\'8a\'54\'94\'4f\'82\'f0\'8e\'9d\'82\'c1\'82\'bd\'95\'aa\'8e\'55\'83\'74\'83\'8c\'81\'5b\'83\'80\'83\'8f\'81\'5b\'83\'4e\ +\'81\'40\'81\'45CodeGear(\'83\'4e\'83\'89\'83\'58\'81\'41\'83\'81\'83\'5c\'83\'62\'83\'68)\ +\'81\'40\'81\'45DataGear(\'95\'cf\'90\'94\'83\'66\'81\'5b\'83\'5e)\ +\'81\'40\'81\'45CodeGearManager(CGM) (node\'82\'c9\'91\'8a\'93\'96\'81\'41\'91\'53\'82\'c4\'82\'ccGear\'82\'f0\'8a\'c7\'97\'9d)\ +\'81\'40\'81\'45DataGearManager(DGM) (DG\'82\'f0Queue\'82\'c5\'8a\'c7\'97\'9d)\ +\'81\'45CodeGear\'93\'e0\'82\'c9\'8b\'4c\'8f\'71\'82\'b3\'82\'ea\'82\'bdDataGear\'82\'aa\'91\'53\'82\'c4\'91\'b5\'82\'a4\'82\'c6CodeGear\'82\'cc\'8f\'88\'97\'9d\'82\'aa\'8a\'4a\'8e\'6e\ +\'81\'45DataGear\'82\'cdkey\'82\'c6Value\'82\'f0\'82\'d0\'82\'c6\'82\'dc\'82\'c6\'82\'dc\'82\'e8\'82\'c6\'82\'b5\'82\'c4DGM\'82\'c9Queue\'82\'c6\'82\'b5\'82\'c4\'8a\'69\'94\'5b\ +\'81\'45\'91\'8a\'8e\'e8node\'82\'ccDGM\'82\'ccproxy\'82\'c6\'82\'b5\'82\'c4\'92\'ca\'90\'4d}</string> + <key>VerticalPad</key> + <real>1</real> + </dict> + <key>TextPlacement</key> + <integer>0</integer> + </dict> + <dict> + <key>Class</key> + <string>Group</string> + <key>Graphics</key> + <array> + <dict> + <key>Bounds</key> + <string>{{107.71653641039933, 852.60433837457708}, {802.20473168797366, 50.924201221512725}}</string> + <key>Class</key> + <string>ShapedGraphic</string> + <key>FontInfo</key> + <dict> + <key>Color</key> + <dict> + <key>b</key> + <string>1</string> + <key>g</key> + <string>1</string> + <key>r</key> + <string>1</string> + </dict> + <key>Font</key> + <string>HiraKakuProN-W3</string> + <key>Size</key> + <real>46</real> + </dict> + <key>ID</key> + <integer>4987</integer> + <key>Style</key> + <dict> + <key>fill</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + <key>shadow</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + <key>stroke</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + </dict> + <key>Text</key> + <dict> + <key>Align</key> + <integer>0</integer> + <key>Pad</key> + <real>0.0</real> + <key>Text</key> + <string>{\rtf1\ansi\ansicpg932\cocoartf2513 +\cocoatextscaling0\cocoaplatform0{\fonttbl\f0\fnil\fcharset128 HiraKakuProN-W3;} +{\colortbl;\red255\green255\blue255;} +{\*\expandedcolortbl;;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\partightenfactor0 + +\f0\fs92 \cf1 \'95\'c0\'97\'f1\'95\'aa\'8e\'55\'83\'74\'83\'8c\'81\'5b\'83\'80\'83\'8f\'81\'5b\'83\'4eChristie}</string> + <key>VerticalPad</key> + <real>0.0</real> + </dict> + </dict> + <dict> + <key>Class</key> + <string>Group</string> + <key>Graphics</key> + <array> + <dict> + <key>Class</key> + <string>LineGraphic</string> + <key>ID</key> + <integer>4989</integer> + <key>Points</key> + <array> + <string>{36.927867652721304, 867.9666138328904}</string> + <string>{55.596114054866462, 867.03353179233284}</string> + <string>{76.548989328664504, 870.08703668578391}</string> + </array> + <key>Style</key> + <dict> + <key>stroke</key> + <dict> + <key>Color</key> + <dict> + <key>b</key> + <real>1</real> + <key>g</key> + <real>1</real> + <key>r</key> + <real>1</real> + </dict> + <key>HeadArrow</key> + <string>FilledBall</string> + <key>Legacy</key> + <true/> + <key>TailArrow</key> + <string>0</string> + <key>Width</key> + <real>3</real> + </dict> + </dict> + <key>Tail</key> + <dict> + <key>ID</key> + <integer>4990</integer> + <key>Position</key> + <real>0.32640770077705383</real> + </dict> + </dict> + <dict> + <key>Class</key> + <string>LineGraphic</string> + <key>ID</key> + <integer>4990</integer> + <key>Points</key> + <array> + <string>{30.212068510391518, 883.01174994382154}</string> + <string>{41.252503182172042, 858.27830589040718}</string> + <string>{43.304748095393229, 857.3916495475396}</string> + <string>{64.46017433474654, 857.3916495475396}</string> + </array> + <key>Style</key> + <dict> + <key>stroke</key> + <dict> + <key>Color</key> + <dict> + <key>b</key> + <real>1</real> + <key>g</key> + <real>1</real> + <key>r</key> + <real>1</real> + </dict> + <key>HeadArrow</key> + <string>FilledBall</string> + <key>Legacy</key> + <true/> + <key>TailArrow</key> + <string>0</string> + <key>Width</key> + <real>3</real> + </dict> + </dict> + <key>Tail</key> + <dict> + <key>ID</key> + <integer>4991</integer> + <key>Position</key> + <real>0.25490197539329529</real> + </dict> + </dict> + <dict> + <key>Class</key> + <string>LineGraphic</string> + <key>ID</key> + <integer>4991</integer> + <key>Points</key> + <array> + <string>{17.112315608580438, 882.78242382402686}</string> + <string>{54.836830578768655, 883.44283449773138}</string> + <string>{68.489779332720047, 882.78242382402686}</string> + </array> + <key>Style</key> + <dict> + <key>stroke</key> + <dict> + <key>Color</key> + <dict> + <key>b</key> + <real>1</real> + <key>g</key> + <real>1</real> + <key>r</key> + <real>1</real> + </dict> + <key>HeadArrow</key> + <string>FilledBall</string> + <key>Legacy</key> + <true/> + <key>TailArrow</key> + <string>0</string> + <key>Width</key> + <real>3</real> + </dict> + </dict> + </dict> + <dict> + <key>Bounds</key> + <string>{{13.288199191623846, 844.72441711313149}, {936.31810863689566, 47.436242233737872}}</string> + <key>Class</key> + <string>ShapedGraphic</string> + <key>ID</key> + <integer>4992</integer> + <key>Style</key> + <dict> + <key>fill</key> + <dict> + <key>Color</key> + <dict> + <key>b</key> + <real>0.80000000000000004</real> + <key>g</key> + <real>0.59999999999999998</real> + <key>r</key> + <real>0.20000000000000001</real> + </dict> + <key>FillType</key> + <integer>2</integer> + <key>GradientAngle</key> + <real>90</real> + <key>GradientColor</key> + <dict> + <key>b</key> + <string>0.8</string> + <key>g</key> + <string>0.4</string> + <key>r</key> + <string>0</string> + </dict> + </dict> + <key>shadow</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + <key>stroke</key> + <dict> + <key>Width</key> + <real>0.5</real> + </dict> + </dict> + </dict> + </array> + <key>ID</key> + <integer>4988</integer> + </dict> + </array> + <key>ID</key> + <integer>4986</integer> + </dict> + <dict> + <key>Bounds</key> + <string>{{12.755905627547179, 844.72441711313343}, {936.85040220097289, 1166.456703496822}}</string> + <key>Class</key> + <string>ShapedGraphic</string> + <key>FontInfo</key> + <dict> + <key>Size</key> + <real>30</real> + </dict> + <key>ID</key> + <integer>4993</integer> + <key>Style</key> + <dict> + <key>shadow</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + <key>stroke</key> + <dict> + <key>Width</key> + <real>0.5</real> + </dict> + </dict> + </dict> + </array> + <key>ID</key> + <integer>4984</integer> + </dict> + <dict> + <key>Bounds</key> + <string>{{2639.0551420547827, 21.259842712578809}, {149.29057682701156, 14.648487363211407}}</string> + <key>Class</key> + <string>ShapedGraphic</string> + <key>FontInfo</key> + <dict> + <key>Font</key> + <string>HiraKakuProN-W6</string> + <key>Size</key> + <real>2018</real> + </dict> + <key>ID</key> + <integer>4800</integer> + <key>Style</key> + <dict> + <key>fill</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + <key>shadow</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + <key>stroke</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + </dict> + <key>Text</key> + <dict> + <key>Align</key> + <integer>0</integer> + <key>Pad</key> + <real>0.0</real> + <key>Text</key> + <string>{\rtf1\ansi\ansicpg932\cocoartf2513 +\cocoatextscaling0\cocoaplatform0{\fonttbl\f0\fnil\fcharset128 HiraKakuProN-W6;} +{\colortbl;\red255\green255\blue255;} +{\*\expandedcolortbl;;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\slleading-800\pardirnatural\partightenfactor0 + +\f0\b\fs40 \cf1 2022/2/18}</string> + <key>VerticalPad</key> + <real>0.0</real> + </dict> + </dict> + <dict> + <key>Bounds</key> + <string>{{1396.9579120299818, 1469.1245769703978}, {14.485579649894881, 22}}</string> + <key>Class</key> + <string>ShapedGraphic</string> + <key>FitText</key> + <string>Vertical</string> + <key>Flow</key> + <string>Resize</string> + <key>ID</key> + <integer>4873</integer> + <key>Style</key> + <dict> + <key>fill</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + <key>shadow</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + <key>stroke</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + </dict> + </dict> + <dict> + <key>Class</key> + <string>Group</string> + <key>Graphics</key> + <array> + <dict> + <key>Bounds</key> + <string>{{13.288199191623221, 274.07801991168378}, {936.31810863689566, 557.89049157390036}}</string> + <key>Class</key> + <string>ShapedGraphic</string> + <key>FontInfo</key> + <dict> + <key>Color</key> + <dict> + <key>b</key> + <string>0</string> + <key>g</key> + <string>0</string> + <key>r</key> + <string>0</string> + </dict> + <key>Font</key> + <string>HiraKakuProN-W6</string> + <key>Size</key> + <real>30</real> + </dict> + <key>ID</key> + <integer>4975</integer> + <key>Style</key> + <dict> + <key>fill</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + <key>shadow</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + <key>stroke</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + </dict> + <key>Text</key> + <dict> + <key>Align</key> + <integer>0</integer> + <key>Pad</key> + <real>0.0</real> + <key>Text</key> + <string>{\rtf1\ansi\ansicpg932\cocoartf2513 +\cocoatextscaling0\cocoaplatform0{\fonttbl\f0\fnil\fcharset128 HiraKakuProN-W6;} +{\colortbl;\red255\green255\blue255;\red0\green0\blue0;} +{\*\expandedcolortbl;;\csgenericrgb\c0\c0\c0;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\partightenfactor0 + +\f0\b\fs60 \cf2 \'81\'45\'83\'49\'83\'93\'83\'89\'83\'43\'83\'93\'83\'51\'81\'5b\'83\'80\'82\'c5\'82\'cdGCP\'82\'e2AWS\'82\'c8\'82\'c7\'82\'cc\'8a\'e9\'8b\'c6\'82\'aa\'92\'f1\'8b\'9f\'82\'b7\'82\'e9\'83\'54\'81\'5b\'83\'6f\'82\'aa\'95\'4b\'97\'76\ +\'81\'45\'83\'54\'81\'5b\'83\'6f\'82\'f0\'97\'98\'97\'70\'82\'b5\'82\'bd\'92\'ca\'90\'4d\'82\'cdWAN\'8f\'e3\'82\'c5\'93\'ae\'8d\'ec\'82\'b7\'82\'e9\'82\'bd\'82\'df\'92\'e1\'91\'ac\ +\'81\'45\'83\'86\'81\'5b\'83\'55\'82\'cc\'91\'9d\'89\'c1\'82\'c9\'91\'ce\'89\'9e\'82\'b5\'82\'c2\'82\'c2\'83\'54\'81\'5b\'83\'72\'83\'58\'82\'cc\'83\'58\'83\'50\'81\'5b\'83\'89\'83\'72\'83\'8a\'83\'65\'83\'42\'82\'e0\'8d\'73\'82\'a4\'95\'4b\'97\'76\'82\'aa\'82\'a0\'82\'e9\ +\'81\'40\'81\'45\'83\'58\'83\'50\'81\'5b\'83\'89\'83\'72\'83\'8a\'83\'65\'83\'42\'82\'c6\'82\'cd\'83\'8a\'83\'5c\'81\'5b\'83\'58\'82\'cc\'92\'c7\'89\'c1\'82\'cc\'82\'dd\'82\'c5\'83\'54\'81\'5b\'83\'72\'83\'58\'82\'cc\'8e\'bf\'82\'f0\'88\'db\'8e\'9d\'82\'b7\'82\'e9\'82\'b1\'82\'c6\ +\'81\'45Christie\'82\'f0\'8e\'67\'97\'70\'82\'b7\'82\'e9\'82\'b1\'82\'c6\'82\'c5\'81\'41LAN\'8f\'e3\'82\'c5\'8d\'82\'91\'ac\'92\'ca\'90\'4d\'82\'aa\'89\'c2\'94\'5c\ +\'81\'45TopologyManager\'82\'f0\'8e\'67\'97\'70\'82\'b7\'82\'e9\'82\'b1\'82\'c6\'82\'c5LAN/WAN\'8f\'e3\'82\'c5\'93\'ae\'93\'49\'82\'c9\'83\'6c\'83\'62\'83\'67\'83\'8f\'81\'5b\'83\'4e\'82\'aa\'8d\'5c\'92\'7a\'82\'b3\'82\'ea\'82\'e9\ +\'81\'45\'83\'58\'83\'50\'81\'5b\'83\'89\'83\'72\'83\'8a\'83\'65\'83\'42\'82\'c9\'82\'c2\'82\'a2\'82\'c4\'82\'e0TopologyManager\'82\'cc\'95\'aa\'8e\'55\'83\'8b\'81\'5b\'83\'65\'83\'42\'83\'93\'83\'4f\'82\'c9\'82\'e6\'82\'c1\'82\'c4\'8e\'c0\'8c\'bb\'89\'c2\'94\'5c}</string> + <key>VerticalPad</key> + <real>1</real> + </dict> + <key>TextPlacement</key> + <integer>0</integer> + </dict> + <dict> + <key>Class</key> + <string>Group</string> + <key>Graphics</key> + <array> + <dict> + <key>Bounds</key> + <string>{{107.71653641039939, 223.15381869017108}, {802.20473168797366, 50.924201221512725}}</string> + <key>Class</key> + <string>ShapedGraphic</string> + <key>FontInfo</key> + <dict> + <key>Color</key> + <dict> + <key>b</key> + <string>1</string> + <key>g</key> + <string>1</string> + <key>r</key> + <string>1</string> + </dict> + <key>Font</key> + <string>HiraKakuProN-W3</string> + <key>Size</key> + <real>46</real> + </dict> + <key>ID</key> + <integer>4977</integer> + <key>Style</key> + <dict> + <key>fill</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + <key>shadow</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + <key>stroke</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + </dict> + <key>Text</key> + <dict> + <key>Align</key> + <integer>0</integer> + <key>Pad</key> + <real>0.0</real> + <key>Text</key> + <string>{\rtf1\ansi\ansicpg932\cocoartf2513 +\cocoatextscaling0\cocoaplatform0{\fonttbl\f0\fnil\fcharset128 HiraKakuProN-W3;} +{\colortbl;\red255\green255\blue255;} +{\*\expandedcolortbl;;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\partightenfactor0 + +\f0\fs92 \cf1 \'83\'49\'83\'93\'83\'89\'83\'43\'83\'93\'83\'51\'81\'5b\'83\'80\'82\'c9\'82\'a8\'82\'af\'82\'e9\'83\'66\'81\'5b\'83\'5e\'92\'ca\'90\'4d}</string> + <key>VerticalPad</key> + <real>0.0</real> + </dict> + </dict> + <dict> + <key>Class</key> + <string>Group</string> + <key>Graphics</key> + <array> + <dict> + <key>Class</key> + <string>LineGraphic</string> + <key>ID</key> + <integer>4979</integer> + <key>Points</key> + <array> + <string>{36.927867652721538, 238.51609414848446}</string> + <string>{55.596114054866057, 237.58301210792678}</string> + <string>{76.548989328664135, 240.63651700137788}</string> + </array> + <key>Style</key> + <dict> + <key>stroke</key> + <dict> + <key>Color</key> + <dict> + <key>b</key> + <real>1</real> + <key>g</key> + <real>1</real> + <key>r</key> + <real>1</real> + </dict> + <key>HeadArrow</key> + <string>FilledBall</string> + <key>Legacy</key> + <true/> + <key>TailArrow</key> + <string>0</string> + <key>Width</key> + <real>3</real> + </dict> + </dict> + <key>Tail</key> + <dict> + <key>ID</key> + <integer>4980</integer> + <key>Position</key> + <real>0.32640770077705383</real> + </dict> + </dict> + <dict> + <key>Class</key> + <string>LineGraphic</string> + <key>ID</key> + <integer>4980</integer> + <key>Points</key> + <array> + <string>{30.212068510391461, 253.56123025941548}</string> + <string>{41.252503182172553, 228.82778620600121}</string> + <string>{43.304748095393741, 227.94112986313363}</string> + <string>{64.460174334746483, 227.94112986313363}</string> + </array> + <key>Style</key> + <dict> + <key>stroke</key> + <dict> + <key>Color</key> + <dict> + <key>b</key> + <real>1</real> + <key>g</key> + <real>1</real> + <key>r</key> + <real>1</real> + </dict> + <key>HeadArrow</key> + <string>FilledBall</string> + <key>Legacy</key> + <true/> + <key>TailArrow</key> + <string>0</string> + <key>Width</key> + <real>3</real> + </dict> + </dict> + <key>Tail</key> + <dict> + <key>ID</key> + <integer>4981</integer> + <key>Position</key> + <real>0.25490197539329529</real> + </dict> + </dict> + <dict> + <key>Class</key> + <string>LineGraphic</string> + <key>ID</key> + <integer>4981</integer> + <key>Points</key> + <array> + <string>{17.112315608580378, 253.33190413962086}</string> + <string>{54.836830578768605, 253.99231481332538}</string> + <string>{68.489779332719991, 253.33190413962086}</string> + </array> + <key>Style</key> + <dict> + <key>stroke</key> + <dict> + <key>Color</key> + <dict> + <key>b</key> + <real>1</real> + <key>g</key> + <real>1</real> + <key>r</key> + <real>1</real> + </dict> + <key>HeadArrow</key> + <string>FilledBall</string> + <key>Legacy</key> + <true/> + <key>TailArrow</key> + <string>0</string> + <key>Width</key> + <real>3</real> + </dict> + </dict> + </dict> + <dict> + <key>Bounds</key> + <string>{{13.288199191623789, 215.27389742872546}, {936.31810863689566, 47.436242233737872}}</string> + <key>Class</key> + <string>ShapedGraphic</string> + <key>ID</key> + <integer>4982</integer> + <key>Style</key> + <dict> + <key>fill</key> + <dict> + <key>Color</key> + <dict> + <key>b</key> + <real>0.80000000000000004</real> + <key>g</key> + <real>0.59999999999999998</real> + <key>r</key> + <real>0.20000000000000001</real> + </dict> + <key>FillType</key> + <integer>2</integer> + <key>GradientAngle</key> + <real>90</real> + <key>GradientColor</key> + <dict> + <key>b</key> + <string>0.8</string> + <key>g</key> + <string>0.4</string> + <key>r</key> + <string>0</string> + </dict> + </dict> + <key>shadow</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + <key>stroke</key> + <dict> + <key>Width</key> + <real>0.5</real> + </dict> + </dict> + </dict> + </array> + <key>ID</key> + <integer>4978</integer> + </dict> + </array> + <key>ID</key> + <integer>4976</integer> + </dict> + <dict> + <key>Bounds</key> + <string>{{12.755905627547179, 215.2738974287264}, {936.85040220097289, 616.69461405685774}}</string> + <key>Class</key> + <string>ShapedGraphic</string> + <key>FontInfo</key> + <dict> + <key>Size</key> + <real>30</real> + </dict> + <key>ID</key> + <integer>4983</integer> + <key>Style</key> + <dict> + <key>shadow</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + <key>stroke</key> + <dict> + <key>Width</key> + <real>0.5</real> + </dict> + </dict> + </dict> + </array> + <key>ID</key> + <integer>4974</integer> + </dict> + <dict> + <key>Bounds</key> + <string>{{2423.6220692339843, 102.04724502037828}, {397.14630873461806, 96.707721339814199}}</string> + <key>Class</key> + <string>ShapedGraphic</string> + <key>ID</key> + <integer>3434</integer> + <key>ImageID</key> + <integer>22</integer> + <key>Style</key> + <dict> + <key>fill</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + <key>shadow</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + <key>stroke</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + </dict> + </dict> + <dict> + <key>Bounds</key> + <string>{{2168.5039566830387, 128.9763791229781}, {205.51181288825956, 89.291339392830963}}</string> + <key>Class</key> + <string>ShapedGraphic</string> + <key>FontInfo</key> + <dict> + <key>Color</key> + <dict> + <key>b</key> + <string>1</string> + <key>g</key> + <string>1</string> + <key>r</key> + <string>1</string> + </dict> + <key>Font</key> + <string>HiraKakuProN-W3</string> + <key>Size</key> + <real>13</real> + </dict> + <key>ID</key> + <integer>24</integer> + <key>Style</key> + <dict> + <key>fill</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + <key>shadow</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + <key>stroke</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + </dict> + <key>Text</key> + <dict> + <key>Align</key> + <integer>0</integer> + <key>Pad</key> + <real>0.0</real> + <key>Text</key> + <string>{\rtf1\ansi\ansicpg932\cocoartf2513 +\cocoatextscaling0\cocoaplatform0{\fonttbl\f0\fnil\fcharset128 HiraKakuProN-W3;} +{\colortbl;\red255\green255\blue255;} +{\*\expandedcolortbl;;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\partightenfactor0 + +\f0\fs128 \cf1 \'88\'c0\'93\'63\'97\'ba}</string> + <key>VerticalPad</key> + <real>0.0</real> + </dict> + </dict> + <dict> + <key>Bounds</key> + <string>{{36.850394035136603, 40.752022750004322}, {2167.0866338355336, 66.964513660394985}}</string> + <key>Class</key> + <string>ShapedGraphic</string> + <key>FontInfo</key> + <dict> + <key>Font</key> + <string>HiraKakuProN-W6</string> + <key>Size</key> + <real>110</real> + </dict> + <key>ID</key> + <integer>5</integer> + <key>Style</key> + <dict> + <key>fill</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + <key>shadow</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + <key>stroke</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + </dict> + <key>Text</key> + <dict> + <key>Align</key> + <integer>0</integer> + <key>Pad</key> + <real>0.0</real> + <key>Text</key> + <string>{\rtf1\ansi\ansicpg932\cocoartf2513 +\cocoatextscaling0\cocoaplatform0{\fonttbl\f0\fnil\fcharset128 HiraKakuProN-W6;} +{\colortbl;\red255\green255\blue255;} +{\*\expandedcolortbl;;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\slleading-800\pardirnatural\partightenfactor0 + +\f0\b\fs180 \cf1 \'8c\'70\'91\'b1\'82\'f0\'8e\'67\'97\'70\'82\'b7\'82\'e9\'95\'c0\'97\'f1\'95\'aa\'8e\'55\'83\'74\'83\'8c\'81\'5b\'83\'80\'83\'8f\'81\'5b\'83\'4e\'82\'ccUnity\'8e\'c0\'91\'95}</string> + <key>VerticalPad</key> + <real>0.0</real> + </dict> + </dict> + <dict> + <key>Bounds</key> + <string>{{12.755905627547236, 14.173228475052539}, {2831.8110493154973, 189.7327887044525}}</string> + <key>Class</key> + <string>ShapedGraphic</string> + <key>FontInfo</key> + <dict> + <key>Font</key> + <string>Helvetica</string> + <key>Size</key> + <real>10</real> + </dict> + <key>ID</key> + <integer>23</integer> + <key>Style</key> + <dict> + <key>fill</key> + <dict> + <key>Color</key> + <dict> + <key>b</key> + <real>0.91372500000000001</real> + <key>g</key> + <real>0.62745099999999998</real> + <key>r</key> + <real>0.0</real> + </dict> + <key>FillType</key> + <integer>2</integer> + <key>GradientAngle</key> + <real>90</real> + <key>GradientColor</key> + <dict> + <key>b</key> + <string>0.72549</string> + <key>g</key> + <string>0.419608</string> + <key>r</key> + <string>0</string> + </dict> + </dict> + <key>shadow</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + <key>stroke</key> + <dict> + <key>Width</key> + <real>0.5</real> + </dict> + </dict> + </dict> + </array> + <key>GridInfo</key> + <dict> + <key>GridSpacing</key> + <real>35.433071136474609</real> + <key>ShowsGrid</key> + <string>YES</string> + </dict> + <key>GuidesLocked</key> + <string>NO</string> + <key>GuidesVisible</key> + <string>YES</string> + <key>HPages</key> + <integer>1</integer> + <key>ImageCounter</key> + <integer>34</integer> + <key>ImageLinkBack</key> + <array> + <dict/> + <dict/> + </array> + <key>ImageList</key> + <array> + <string>image33.pdf</string> + <string>image22.pdf</string> + </array> + <key>KeepToScale</key> + <false/> + <key>Layers</key> + <array> + <dict> + <key>Lock</key> + <string>NO</string> + <key>Name</key> + <string>Layer 1</string> + <key>Print</key> + <string>YES</string> + <key>Slices</key> + <string>NO</string> + <key>View</key> + <string>YES</string> + </dict> + </array> + <key>LayoutInfo</key> + <dict> + <key>Animate</key> + <string>NO</string> + <key>circoMinDist</key> + <real>18</real> + <key>circoSeparation</key> + <real>0.0</real> + <key>layoutEngine</key> + <string>dot</string> + <key>neatoLineLength</key> + <real>0.20000000298023224</real> + <key>neatoSeparation</key> + <real>0.0</real> + <key>twopiSeparation</key> + <real>0.0</real> + </dict> + <key>LinksVisible</key> + <string>NO</string> + <key>MagnetsVisible</key> + <string>NO</string> + <key>MasterSheets</key> + <array/> + <key>ModificationDate</key> + <string>2022-02-17 16:03:36 +0000</string> + <key>Modifier</key> + <string>安田亮</string> + <key>NotesVisible</key> + <string>NO</string> + <key>Orientation</key> + <integer>1</integer> + <key>OriginVisible</key> + <string>NO</string> + <key>PageBreaks</key> + <string>YES</string> + <key>PrintInfo</key> + <dict> + <key>NSBottomMargin</key> + <array> + <string>float</string> + <string>41</string> + </array> + <key>NSHorizonalPagination</key> + <array> + <string>coded</string> + <string>BAtzdHJlYW10eXBlZIHoA4QBQISEhAhOU051bWJlcgCEhAdOU1ZhbHVlAISECE5TT2JqZWN0AIWEASqEhAFxlwCG</string> + </array> + <key>NSLeftMargin</key> + <array> + <string>float</string> + <string>18</string> + </array> + <key>NSPaperName</key> + <array> + <string>string</string> + <string>ADA99C75-491B-4B6C-AD03-A113BC153C21</string> + </array> + <key>NSPaperSize</key> + <array> + <string>size</string> + <string>{2063.6220703125, 2919.68505859375}</string> + </array> + <key>NSPrintReverseOrientation</key> + <array> + <string>coded</string> + <string>BAtzdHJlYW10eXBlZIHoA4QBQISEhAhOU051bWJlcgCEhAdOU1ZhbHVlAISECE5TT2JqZWN0AIWEASqEhAFxlwCG</string> + </array> + <key>NSRightMargin</key> + <array> + <string>float</string> + <string>18</string> + </array> + <key>NSTopMargin</key> + <array> + <string>float</string> + <string>18</string> + </array> + </dict> + <key>PrintOnePage</key> + <false/> + <key>ReadOnly</key> + <string>NO</string> + <key>RowAlign</key> + <integer>1</integer> + <key>RowSpacing</key> + <real>36</real> + <key>SheetTitle</key> + <string>Canvas 1</string> + <key>SmartAlignmentGuidesActive</key> + <string>YES</string> + <key>SmartDistanceGuidesActive</key> + <string>YES</string> + <key>UniqueID</key> + <integer>1</integer> + <key>UseEntirePage</key> + <false/> + <key>VPages</key> + <integer>1</integer> + <key>WindowInfo</key> + <dict> + <key>CurrentSheet</key> + <integer>0</integer> + <key>Expanded_Canvases</key> + <array/> + <key>Frame</key> + <string>{{1819, 40}, {1792, 1057}}</string> + <key>ShowInfo</key> + <true/> + <key>Sidebar</key> + <true/> + <key>SidebarWidth</key> + <integer>200</integer> + <key>TopSlabHeight</key> + <real>250</real> + <key>VisibleRegion</key> + <string>{{399.99999999999994, 234.61538461538461}, {2459.6153846153843, 1792.3076923076924}}</string> + <key>Zoom</key> + <real>0.52000000000000002</real> + <key>ZoomValues</key> + <array> + <array> + <string>Canvas 1</string> + <real>0.52000000000000002</real> + <real>1.04</real> + </array> + </array> + </dict> +</dict> +</plist>
--- a/Slide/master-slide.html Mon Feb 14 20:57:33 2022 +0900 +++ b/Slide/master-slide.html Fri Feb 18 01:09:32 2022 +0900 @@ -89,23 +89,19 @@ <div class='slide'> - <h3 id="本研究における成果">本研究における成果</h3> + +<!-- _S9SLIDE_ --> +<h2 id="並列分散フレームワークchristieとunity">並列分散フレームワークChristieとUnity</h2> <ul> - <li>並列分散フレームワークChristieをUnityで動作可能に + <li>Unityとはゲーム開発でよく使用されているゲームエンジン</li> + <li>ChristieとはDataGearのTake/Putを使用した分散フレームワーク</li> + <li>UnityでServer抜きのネットワークゲーム開発を行いたい <ul> - <li>Unity上でp2pを基礎としたオンラインゲームの開発が可能に</li> + <li>Java版を接続するのは困難</li> + <li>C#でChristieを実装した</li> </ul> </li> - <li>Christie Sharpと既存のUnityの通信フレームワークとの機能的な比較を行った - <ul> - <li>Christie Sharpの利点 - <ul> - <li>単体でも並列ライブラリとして機能する</li> - <li>通信切断が起こった場合でもゲームロジックが停止しない</li> - </ul> - </li> - </ul> - </li> + <li>Unityに並列分散処理をスムーズに導入できた</li> </ul> @@ -114,46 +110,23 @@ <div class='slide'> <!-- _S9SLIDE_ --> - - -<h3 id="概要">概要</h3> +<h2 id="christieによるunityネットワークゲーム実装の利点">ChristieによるUnityネットワークゲーム実装の利点</h2> <ul> - <li>オンラインゲームにおける通信にはクライアントサーバ方式が主流 + <li>PUN2では企業ベースのServerが必要(開発がしづらい)</li> + <li>WAN上なので低速 <ul> - <li>データの共有はサーバを経由するため低速</li> + <li>ChristieにするとLAN上での高速通信が可能</li> + <li>TopologyManagerを使うことによりLAN/WANで動的構成される</li> + <li>スケーラビリティーもTopologyManagerで実現できる(分散ルーティング)</li> + <li>Take/Putなので通信切断や遅延に対して対処しやすい</li> </ul> </li> - <li>当研究室で開発を行っているChristie の分散計算を使用することで、高速に通信できると考えた</li> - <li>Christie をUnity で使用するためにC# で書き換えを行った</li> - <li>Christie SharpとUnity既存の通信フレームワークとの機能的な比較を行った</li> -</ul> - - - -</div> - -<div class='slide'> - <!-- _S9SLIDE_ --> - - -<h3 id="オンラインゲームにおけるデータ通信">オンラインゲームにおけるデータ通信</h3> -<ul> - <li>オンラインゲームは複数のプレイヤーが関与する分散プログラム + <li>Unityはフレーム単位の処理なため並列処理が苦手 <ul> - <li>分散プログラムを正しく書くことは難しい - <ul> - <li>ネットワークの変化、故障、性能の多様性を吸収する</li> - <li>スケーラビリティー リソースの追加のみでサービスの質の直感的に維持できる性能基準を備える</li> - </ul> - </li> - <li>Debugも困難な場合が多い</li> + <li>Christieにより画面書き換えと非同期な並列処理や通信が可能</li> </ul> </li> - <li>クライアントの負荷軽減やチート対策のため、クライアントサーバ方式が主流 - <ul> - <li>データの同期にはサーバを経由するためp2pに比べ低速</li> - </ul> - </li> + <li>ChristieのMessagePack(データ通信ライブラリ)のバージョンの問題を解決</li> </ul> @@ -162,25 +135,32 @@ <div class='slide'> <!-- _S9SLIDE_ --> +<h2 id="christie-の計算モデル">Christie の計算モデル</h2> +<ul> + <li>DataGear(通信単位となるオブジェクト)が揃った時点でCodeGearが処理を開始</li> + <li>DataGearは決まったkeyでDataGearManagerにQueueとして格納</li> + <li>相手nodeのDataGearManagerのproxyで通信</li> +</ul> +<center><img src="../Paper/images/Remote_DataGearManager.pdf" alt="message" width="800" height="450" /></center> + -<h3 id="オンラインゲームにおけるデータ通信-1">オンラインゲームにおけるデータ通信</h3> +</div> + +<div class='slide'> + <!-- _S9SLIDE_ --> +<h2 id="datagearのapi">DataGearのAPI</h2> <ul> - <li>当研究室では並列分散通信フレームワークChristie を開発中である + <li>PutでQueueに追加</li> + <li>TakeでQueueからの取り出し</li> + <li>PeekでQueueから取り出さない読み出し <ul> - <li>型のあるDataGear とKey を持つタプル空間、DataGearManager として格納している</li> - <li>他のノードはDGM のproxyを持っており、proxy に書き込むことで通信を実現している</li> - <li>DGM はトポロジーマネージャーによって自動的に構築される - <ul> - <li>プログラム自体はDGM の名前を知っていれば良い</li> - <li>他のノードのIP addressなどを知る必要はない</li> - </ul> - </li> + <li>Takeされない限り同じDataGearを読み出し続ける</li> </ul> </li> - <li>ネットワークが切断されてもゲームは継続可能</li> - <li>本研究ではChristieをC#で再実装を行い、Unityの通信ライブラリとして使用可能にする</li> - <li>既存のUnityの通信ライブラリとの機能面での比較を行い、Christie Sharpのオンラインゲーム向けの通信ライブラリとしての考察を行う</li> + <li>フレームごとにPeekでゲームオブジェクトの状態をUnity側で見れる</li> + <li>通信停止/遅延でもUnityの動作に影響を与えない</li> + <li>スケーラビリティやLAN/WAN構成はTopologyManagerのDGM porxyの管理</li> </ul> @@ -189,65 +169,25 @@ <div class='slide'> <!-- _S9SLIDE_ --> - - -<h3 id="christie-の基礎概念">Christie の基礎概念</h3> +<h2 id="javacのannotation">Java/C#のannotation</h2> <ul> - <li>Christie は当研究室で開発をしている並列分散通信フレームワークである - <ul> - <li>同じく当研究室で開発しているGearsOS に導入予定のため次のような概念を持っている</li> - </ul> - </li> - <li>CodeGear (クラスやスレッド)</li> - <li>DataGear (変数データ)</li> - <li>CodeGearManager (CG,DG,DGMを管理)</li> - <li>DataGearManager (DGを管理,localとremoteの2種類がある, put操作によりDGを格納)</li> + <li>クラスやフィールドあるいはメソッドに付ける</li> + <li>ユーザ定義可能なmeta計算属性</li> + <li>MessagePackで通信可能なフィールドをannotationで指定する</li> + <li>Christieで通信パターンを指定するのにannotationを用いる</li> </ul> -<center><img src="../Paper/images/GearsRelationships.pdf" alt="message" width="550" height="350" /></center> -<center> -各Gearの関係性 -</center> - </div> <div class='slide'> <!-- _S9SLIDE_ --> - - -<h3 id="christie-の基礎概念-1">Christie の基礎概念</h3> -<ul> - <li>全てのCGM はThreadPool と他のCGM をList として共有している</li> - <li>ThreadPool はCPU に合わせた並列度でqueue に入ったThread を逐次実行していく - <ul> - <li>1つのThreadPool で処理を行うことでCPU のコア数に適したThread を管理でき、並列度を下げ流ことを防ぐ</li> - </ul> - </li> - <li>ThreadPoolを共有することメタレベルで全てのCG/DG にアクセス可能</li> -</ul> -<center><img src="../Paper/images/ChristieClass.pdf" alt="message" width="600" height="450" /></center> -<center> -Christie を同一プロセスで複数インスタンス立ち上げた際の接続の構造図 -</center> - - - -</div> - -<div class='slide'> - <!-- _S9SLIDE_ --> - - -<h3 id="christie-の基礎概念-annotationについて">Christie の基礎概念 annotationについて</h3> -<p>DG を取り出すためにCG内に宣言した変数データにannotation をつける。annotationには以下の4つがある。</p> - +<h2 id="dgのannotation">DGのannotation</h2> <ul> <li>Take <ul> <li>先頭のDG を読み込み、そのDG を削除する</li> - <li>DG が複数ある場合Take を使用する</li> </ul> </li> <li>Peek @@ -274,17 +214,63 @@ <div class='slide'> <!-- _S9SLIDE_ --> +<h2 id="christieによる分散プログラミング">Christieによる分散プログラミング</h2> +<ul> + <li>Take/Put/Peekがデータベースのトランザクション</li> + <li>ここではトランザクションはゲームプレイヤー間の合意されたイベント</li> + <li>複数のプレイヤーが関与する分散プログラムをTake/Put/Peekでローカルに記述できる</li> + <li>ローカルな記述を組み合わせて分散プログラムを記述する</li> + <li>ネットワークの変化、故障、性能の多様性を吸収する</li> + <li>Christieのデバッガー(モデル検査など)も使用可能</li> + <li>TopologyManagerで負荷軽減やチート対策が可能</li> +</ul> + + + +</div> + +<div class='slide'> + <!-- _S9SLIDE_ --> +<h2 id="ローカルnodeから見たchristie">ローカルnodeから見たChristie</h2> +<ul> + <li>型のあるDataGear とKey を持つタプル空間、DataGearManager として格納</li> + <li>他のノードのDGM のproxyに書き込むことで通信</li> + <li>CodeGear (クラスやスレッド)</li> + <li>DataGear (変数データ)</li> + <li>CodeGearManager (CG,DG,DGMを管理)</li> +</ul> +<center><img src="../Paper/images/GearsRelationships.pdf" alt="message" width="550" height="350" /></center> + -<h3 id="topology-manager">Topology Manager</h3> +</div> + +<div class='slide'> + <!-- _S9SLIDE_ --> +<h2 id="christie上でnetwork-topologyの形成">Christie上でNetwork Topologyの形成</h2> <ul> - <li>Christie 上でNetwork Topology を形成する - <ul> - <li>参加を表明したノードに名前を与える</li> - <li>必要があればノード同士の配線を自動で行う</li> - </ul> + <li>参加を表明したノードにDataGearManager proxyを決まった名前で作成</li> + <li>ノード同士の配線を指示</li> + <li>分散プログラムの開始終了</li> + <li>Treeなどの動的Topologyは自動的に接続される</li> +</ul> +<center><img src="../Paper/images/DynamicTopology.pdf" alt="message" width="550" height="350" /></center> + + + +</div> + +<div class='slide'> + <!-- _S9SLIDE_ --> +<h2 id="christie-sharp-のコード例">Christie Sharp のコード例</h2> +<ul> + <li>Mainでport10001でChristie フレームワークを起動(CreateCGM)</li> + <li>最初のCodeGearをCodeGearManagerに対して実行する + <pre><code class="language-cs">public static void Main(string[] args) { + StartCountUp start = StartCountUp(createCGM(10001)); +} +</code></pre> </li> - <li>静的Topology と動的Topology 2種類がある</li> </ul> @@ -293,97 +279,115 @@ <div class='slide'> <!-- _S9SLIDE_ --> - - -<h3 id="topology-manager静的topology">Topology Manager 静的Topology</h3> +<h2 id="codegear-startcountup">CodeGear StartCountUp</h2> <ul> - <li>静的Topology は以下のようなdot ファイルを与えることでNode の関係を構築できる</li> - <li>それぞれのNode への通信にはIP address などは使用せずright というlabel を使用することで接続できる</li> -</ul> - -<center>dot 形式による node 間接続の記述</center> -<pre><code class="language-ring.dot">digraph test { - node0 -> node1 [label="right"] - node1 -> node2 [label="right"] - node2 -> node0 [label="right"] + <li>CodeGearはCodeGearManagerを引数として持つ(baseでcgmに対してアクセスを許可)</li> + <li>CodeGearManagerがRun(cgm)をThreadPoolを使って呼び出す + <pre><code class="language-cs:StartCountUp.cs">public class StartCountUp : StartCodeGear { + public StartCountUp(CodeGearManager cgm) : base(cgm) { } + public override void Run(CodeGearManager cgm) { + cgm.Setup(new CountUpper()); // 新しいCodeGearを生成 + CountObject count = new CountObject(1); + put("count", count); // DataGear countをkey countでPut + } } </code></pre> - -<center><img src="../Paper/images/ring.pdf" alt="message" width="480" height="300" /></center> -<center> -ring状の接続 -</center> - - + </div> <div class='slide'> <!-- _S9SLIDE_ --> - +<h2 id="codegear-countupper">CodeGear CountUpper</h2> + </li> + <li>key countのDataGearが来たらCountUpperのRunが実行される + <pre><code class="language-cs:CountUpper.cs">public class CountUpper : CodeGear { + [Take] public CountObject count; // key countをTakeするannotation + public override void Run(CodeGearManager cgm) { + Console.WriteLine(count.number); + if (count.number < 10) { + cgm.Setup(new CountUpper()); // 毎回新しいCodeGearを生成 + count.number += 1; + put("count", count); + } else { + cgm.GetLocalDGM().Finish(); // CodeGearManagerを終了 + } + } +} +</code></pre> + -<h3 id="topology-manager静的topology-1">Topology Manager 静的Topology</h3> -<ul> - <li>動的Topologyは以下の図のように自動的に接続される</li> - <li>現在はTree型の接続のみに対応している</li> +</div> + +<div class='slide'> + <!-- _S9SLIDE_ --> +<h2 id="datagearcountobject">DataGear CountObject</h2> + </li> + <li>MessagePackを使って通信されるDataGear</li> + <li>Take/Put/Peekはこれに対して行われる + <pre><code class="language-cs:CountObject.cs">[MessagePackObject] +public class CountObject { + public int number; + public CountObject(int number) { // コンストラクタ + this.number = number; + } +} +</code></pre> + </li> </ul> -<center><img src="../Paper/images/DynamicTopology.pdf" alt="message" width="1000" height="450" /></center> -<center>動的Topologyの接続手順</center> - </div> <div class='slide'> <!-- _S9SLIDE_ --> - - -<h3 id="christie-のコード例">Christie のコード例</h3> +<h2 id="unityの従来の通信ライブラリ">Unityの従来の通信ライブラリ</h2> <ul> - <li>コンストラクタで与えた数字をインクリメントし、10回printする例題 - <pre><code class="language-java:StartCountup.java">public class StartCountup extends StartCodeGear { - public StartCountup(CodeGearManager cgm) { super(cgm); } - - public static void main(String args[]) { - StartCountup start = StartCountup(createCGM(10001)); - } - - @Override - protected void run(CodeGearManager cgm) { - cgm.setup(new CountUpper()); - CountObject count = new CountObject(1); - put("count", count); - } -} -</code></pre> - <p>```java:CountUpper.java -public class CountUpper extends CodeGear { - @Take - public CountObject count;</p> - - <p>@Override - protected void run(CodeGearManager cgm) { - System.out.println(count);</p> - - <pre><code> if (count < 10) { - cgm.setup(new CountUpper()); - count.number += 1; - put("count", count); - } else { - cgm.getLocalDGM().finish(); - } } } -</code></pre> + <li>Unityはフレーム単位で処理を行う</li> + <li>IEnumeratorでフレームを跨ぐ処理を記述する</li> + <li>Send/Recieveなどでは通信を記述しづらい</li> + <li>Photon Unity Network 2(PUN2) + <ul> + <li>Cloud ServerサービスPhoton Cloudがある</li> + <li>Server側は開発できない</li> + </ul> + </li> + <li>Mirror + <ul> + <li>OSSで開発が行われている</li> + <li>メソッドをServerで実行し結果を反映</li> + </ul> </li> </ul> -<pre><code>```java:CountObject.java -@Message -public class CountObject { - public int number; + + +</div> - public CountObject(int number) { - this.number = number; +<div class='slide'> + <!-- _S9SLIDE_ --> +<h2 id="photon-unity-network2">Photon Unity Network2</h2> +<pre><code class="language-cs">public class PhotonController : MonoBehaviourPunCallbacks { + void Start() { + PhotonNetwork.ConnectUsingSettings(); + } + void FixedUpdate() { + if (photonView.IsMine) { // 自身であるか + float x = Input.GetAxis("Horizontal"); + float z = Input.GetAxis("Vertical"); + CmdMoveSphere(x, z); + } + } + void CmdMoveSphere(float x, float z) { + Vector3 v = new Vector3(x, 0, z); + GetComponent<Rigidbody>().AddForce(v); + } + public override void OnConnectedToMaster() { // Server接続時のcallback + PhotonNetwork.JoinOrCreateRoom("Room", new RoomOptions(), TypedLobby.Default); + } + public override void OnJoinedRoom() { // Room接続時のcallback + PhotonNetwork.Instantiate("Charactor", Vector3.zero, Quaternion.identity); } } </code></pre> @@ -394,11 +398,26 @@ <div class='slide'> <!-- _S9SLIDE_ --> - - -<h3 id="christie-のコード例-1">Christie のコード例</h3> - -<p>シーケンス図を使った説明</p> +<h2 id="mirror">Mirror</h2> +<pre><code class="language-cs">public class PlayerController : NetworkBehaviour { + [SyncVar] float speed = 1f; + public override void OnStartServer() { // Server接続時のcallback + speed = Random.Range(1f, 10f); + } + void FixedUpdate() { + if (isLocalPlayer) { + float x = Input.GetAxis("Horizontal"); + float z = Input.GetAxis("Vertical"); + CmdMoveSphere(x, z); + } + } + [Command] // Server側で実行される + void CmdMoveSphere(float x, float z) { + Vector3 v = new Vector3(x + speed, 0, z + speed); + GetComponent<Rigidbody>().AddForce(v); + } +} +</code></pre> @@ -406,27 +425,26 @@ <div class='slide'> <!-- _S9SLIDE_ --> - - -<h3 id="cへの書き換えの意義">C#への書き換えの意義</h3> +<h2 id="cへの書き換える利点">C#への書き換える利点</h2> <ul> <li>ChristieはJavaで実装されている <ul> <li>C#に書き換えを行うべきか</li> </ul> </li> + <li>JavaをC#上で呼び出す方式 + <ul> + <li>annotationが使用できない</li> + </ul> + </li> <li>Unityはandroidの開発向けにjarファイルからJavaのメソッドをC#上で呼び出せる機能がある <ul> <li>stringを使用してリソースディレクトリから検索し、使用</li> <li>高速化が求められる並列分散プログラミングには不適</li> </ul> </li> - <li>JavaとC#の2つの管理が必要になる - <ul> - <li>C#とJavaは記述方法が非常に似ており、APIもほとんど同様な機能が実装されている</li> - <li>リポジトリをネスト化して対応</li> - </ul> - </li> + <li>記述方法が似ているため移植が行いやすい</li> + <li>ThreadPoolをC#で統一できる</li> </ul> @@ -435,9 +453,7 @@ <div class='slide'> <!-- _S9SLIDE_ --> - - -<h3 id="書き換えの方針">書き換えの方針</h3> +<h2 id="書き換えの方針">書き換えの方針</h2> <ul> <li>C#で記述するChristieをChristie Sharpとする</li> <li>Christie設計時の意図や、互換性を保つためChristieと同じ動作をさせる</li> @@ -456,100 +472,7 @@ <div class='slide'> <!-- _S9SLIDE_ --> - - -<h3 id="java-からの変更点">Java からの変更点</h3> -<ul> - <li>Java とC# は基本的に書き方は変わらない</li> -</ul> - -<pre><code class="language-java:ex.java">Java -public class StartCountup extends StartCodeGear { } - -@Override -protected void run(CodeGearManager cgm) { } - -@Take String countObject; -</code></pre> - -<pre><code class="language-cs:ex.cs">C# -public class StartCountup : StartCodeGear { } - -public override void Run(CodeGearManager cgm) { } - -[Take] string countObject; -</code></pre> - - - -</div> - -<div class='slide'> - <!-- _S9SLIDE_ --> - - -<h3 id="christie-sharp-のコード例">Christie Sharp のコード例</h3> -<pre><code class="language-cs:StartCountUp.cs">public class StartCountUp : StartCodeGear { - public StartCountUp(CodeGearManager cgm) : base(cgm) { } - - public static void Main(string[] args) { - StartCountUp start = StartCountUp(createCGM(10001)); - } - - public override void Run(CodeGearManager cgm) { - cgm.Setup(new CountUpper()); - CountObject count = new CountObject(1); - put("count", count); - } -} -</code></pre> - -<pre><code class="language-cs:CountUpper.cs">public class CountUpper : CodeGear { - [Take] public CountObject count; - - public override void Run(CodeGearManager cgm) { - Console.WriteLine(count.number); - - if (count.number < 10) { - cgm.Setup(new CountUpper()); - count.number += 1; - put("count", count); - } else { - cgm.GetLocalDGM().Finish(); - } - } -} -</code></pre> - -<pre><code class="language-cs:CountObject.cs">[MessagePackObject] -public class CountObject { - public int number; - - public CountObject(int number) { - this.number = number; - } -} -</code></pre> -<!-- -1. Main関数でCGM のインスタンス生成 -2. 2つのCG をsetupして待ち状態にする -3. key:hellowWorld data:"hello" がTake される -4. 変数が揃ったためStartHelloWorld のRun が実行される -5. "hello" がprintされ、再び待ち状態になる。 key:hellow data:"hello"がput される -6. key:hellowWorld data:"world" がTake され、4,5と同様に処理される -7. 変数hello とworld がput され揃ったため、FinishHelloWorld のRun が実行され、プログラムは終了する - ---> - - - -</div> - -<div class='slide'> - <!-- _S9SLIDE_ --> - - -<h3 id="take-annotationの実装">Take annotationの実装</h3> +<h2 id="take-annotationの実装">Take annotationの実装</h2> <ul> <li>Christie ではDGを取得するためにannotation を使用している <ul> @@ -557,16 +480,18 @@ </ul> </li> <li>Take はフィールド変数に対して適用する</li> -</ul> - -<pre><code class="language-java:Take.java">@Target(ElementType.FIELD) + <li>Javaの場合 + <pre><code class="language-java:Take.java">@Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface Take { } </code></pre> - -<pre><code class="language-cs:Take.cs">[AttributeUsage(AttributeTargets.Field)] + </li> + <li>C#の場合 + <pre><code class="language-cs:Take.cs">[AttributeUsage(AttributeTargets.Field)] public class Take : Attribute { } </code></pre> + </li> +</ul> @@ -574,123 +499,67 @@ <div class='slide'> <!-- _S9SLIDE_ --> - - -<h3 id="messagepackの相違点">MessagePackの相違点</h3> +<h2 id="messagepackの相違点">MessagePackの相違点</h2> <ul> - <li>Christie ではMessagePack を使用してデータを圧縮し送受信している + <li>Christie ではMessagePack を使用してデータをシリアライズし送受信している <ul> - <li>インスタンス内のpublic 変数に対して圧縮可能</li> + <li>インスタンス内のpublic 変数に対してシリアライズ可能</li> </ul> </li> - <li>バージョンが古いため、現在はサポートされていない - <ul> - <li>そのため、最新版とは記述方法が異なる</li> - </ul> - </li> - <li>圧縮するクラスには@Message annotatoinをつける</li> - <li>MessagePack インスタンスを作成後、write、read することでデータの圧縮解凍が可能 - <ul> - <li>圧縮されたデータはbyte[] 型になる</li> - </ul> + <li>Java版はバージョンが古いため、現在はサポートされていないため最新版とは記述方法が異なる + <pre><code class="language-java:MessagePackEx.java">public class MessagePackExample { + @Message // 圧縮を行うクラスにつける + public static class MyMessage { + public String name; + public double version; + } + public static void main(String[] args) throws Exception { + MyMessage src = new MyMessage(); + src.name = "msgpack"; + src.version = 0.6; + + MessagePack msgpack = new MessagePack(); + byte[] bytes = msgpack.write(src); // シリアライズ + // Deserialize + MyMessage dst = msgpack.read(bytes, MyMessage.class); // デシリアライズ +} +</code></pre> </li> </ul> -<pre><code class="language-java:MessagePackEx.java">public class MessagePackExample { - @Message - public static class MyMessage { - public String name; - public double version; - } - - public static void main(String[] args) throws Exception { - MyMessage src = new MyMessage(); - src.name = "msgpack"; - src.version = 0.6; - - MessagePack msgpack = new MessagePack(); - // Serialize - byte[] bytes = msgpack.write(src); - // Deserialize - MyMessage dst = msgpack.read(bytes, MyMessage.class); - } -} -</code></pre> - </div> <div class='slide'> <!-- _S9SLIDE_ --> - - -<h3 id="messagepackの相違点-1">MessagePackの相違点</h3> +<h2 id="messagepackの相違点-1">MessagePackの相違点</h2> <ul> <li>C# のMessagePack は複数存在している <ul> - <li>java 版と似たような書き方をするMessagePack-CSharp を選択した</li> - </ul> - </li> - <li>圧縮を行いたいクラスに対してMessagePackObject attribute を付ける</li> - <li>圧縮する変数に対してkey を設定できる - <ul> - <li>解凍時にjson として展開できる</li> - </ul> - </li> - <li>データの圧縮にはMessagePackSerializer.Serialize 関数を用い、byte[] に圧縮される</li> - <li>データの解凍にはMessagePackSerializer.Deserialize 関数を使用する - <ul> - <li>Deserialize 関数はジェネリスク関数であるため<>内に解凍するデータの型情報を記述する</li> - </ul> - </li> -</ul> - -<pre><code class="language-cs.MessagePackEx.cs">[MessagePackObject] + <li>java 版と似たような書き方をするMessagePack-CSharp を選択した + <pre><code class="language-cs">[MessagePackObject] // シリアライズしたいクラスにつける public class MyClass { - [Key(0)] - public int Age { get; set; } - [Key(1)] - public string FirstName { get; set; } - [Key(2)] - public string LastName { get; set; } - - static void Main(string[] args) { - var mc = new MyClass { - Age = 99, - FirstName = "hoge", - LastName = "huga", - }; - - byte[] bytes = MessagePackSerializer.Serialize(mc); - MyClass mc2 = MessagePackSerializer.Deserialize<MyClass>(bytes); - - // [99,"hoge","huga"] - var json = MessagePackSerializer.ConvertToJson(bytes); - Console.WriteLine(json); - } + [Key(0)] // keyを指定 + public int Age { get; set; } + [Key(1)] + public string FirstName { get; set; } + [Key(2)] + public string LastName { get; set; } + static void Main(string[] args) { + var mc = new MyClass { + Age = 99, + FirstName = "hoge", + LastName = "huga", + }; + byte[] bytes = MessagePackSerializer.Serialize(mc); // byte[] にシリアライズ + MyClass mc2 = MessagePackSerializer.Deserialize<MyClass>(bytes); // デシリアライズ + // [99,"hoge","huga"] + var json = MessagePackSerializer.ConvertToJson(bytes); // Jsonとしても展開可能 + } } </code></pre> - - - -</div> - -<div class='slide'> - <!-- _S9SLIDE_ --> - - -<h3 id="threadpoolからtaskへの書き換え">ThreadPoolからTaskへの書き換え</h3> -<ul> - <li>Christie ではThreadPool を使用していた - <ul> - <li>Christie # ではThreadPoolより高機能なTask を用いて書き換えを行った</li> - </ul> - </li> - <li>Task は複雑な非同期処理を通常のコーディングと同じ感覚で直感的に記述できる</li> - <li>裏でThreadPool が動くようになっている - <ul> - <li>大きく動作は変わらない</li> + </li> </ul> </li> </ul> @@ -701,41 +570,47 @@ <div class='slide'> <!-- _S9SLIDE_ --> - - -<h3 id="threadpoolからtaskへの書き換え-1">ThreadPoolからTaskへの書き換え</h3> - -<pre><code class="language-java:PriorityThreadPoolExecutors.java">public class PriorityThreadPoolExecutors { - - private static class PriorityThreadPoolExecutor extends ThreadPoolExecutor { - private static final int DEFAULT_PRIORITY = 0; - private static AtomicLong instanceCounter = new AtomicLong(); - - public PriorityThreadPoolExecutor(int corePoolSize, int maximumPoolSize, - int keepAliveTime, TimeUnit unit) { - super(corePoolSize, maximumPoolSize, keepAliveTime, unit, (BlockingQueue) new PriorityBlockingQueue<ComparableTask>(10, - ComparableTask.comparatorByPriorityAndSequentialOrder())); - } - - @Override - public void execute(Runnable command) { - super.execute(command); - } - } +<h2 id="threadpoolからtaskへの書き換え">ThreadPoolからTaskへの書き換え</h2> +<ul> + <li>Christie ではThreadPool を使用していた + <pre><code class="language-java:PriorityThreadPoolExecutors.java">public class PriorityThreadPoolExecutors { + private static class PriorityThreadPoolExecutor extends ThreadPoolExecutor { + private static final int DEFAULT_PRIORITY = 0; + public PriorityThreadPoolExecutor(int corePoolSize, int maximumPoolSize, // コンストラクタ + int keepAliveTime, TimeUnit unit) { + super(corePoolSize, maximumPoolSize, keepAliveTime, unit, + (BlockingQueue) new PriorityBlockingQueue<ComparableTask>(10, + ComparableTask.comparatorByPriorityAndSequentialOrder())); + } // 優先度によって処理順を入れ替え可能なQueueを指定 + @Override + public void execute(Runnable command) { + super.execute(command); + } + } } </code></pre> + -<pre><code class="language-cs:ThreadPoolExecuters.cs">public class ThreadPoolExecutors { - - public ThreadPoolExecutors(int nWorkerThreads, int nIOThreads) { - ThreadPool.SetMinThreads(nWorkerThreads, nIOThreads); - } - - public void Execute(CodeGearExecutor command) { - Task.Factory.StartNew(() => command.Run()); - } +</div> + +<div class='slide'> + <!-- _S9SLIDE_ --> +<h2 id="threadpoolからtaskへの書き換え-1">ThreadPoolからTaskへの書き換え</h2> + </li> + <li>Christie Sharp ではThreadPoolより高機能なTask を用いて書き換えを行った</li> + <li>Task は複雑な非同期処理を通常のコーディングと同じ感覚で直感的に記述</li> + <li>裏でThreadPool が動作するため大きく動作は変わらない + <pre><code class="language-cs:ThreadPoolExecuters.cs">public class ThreadPoolExecutors { + public ThreadPoolExecutors(int nWorkerThreads, int nIOThreads) { // コンストラクタ + ThreadPool.SetMinThreads(nWorkerThreads, nIOThreads); + } + public void Execute(CodeGearExecutor command) { + Task.Factory.StartNew(() => command.Run()); // Taskを使用 + } } </code></pre> + </li> +</ul> @@ -743,20 +618,72 @@ <div class='slide'> <!-- _S9SLIDE_ --> +<h2 id="christie-sharpのunityのコード例">Christie SharpのUnityのコード例</h2> +<ul> + <li>ゲームオブジェクトの座標をもう1つのゲームオブジェクトに追従させる例題</li> + <li>StartやUpdateはMonoBehaviourを継承する</li> +</ul> + +<pre><code class="language-cs:TransformMoveTest.cs">public class TransformMoveTest : MonoBehaviour { + private CodeGearManager cgm; + public Transform otherTransform; + private Vector3 pos; + void Start() { // ゲーム実行時の最初の1回呼び出し + cgm = StartCodeGear.CreateCgm(10000); + cgm.Setup(new PositionAssignCodeGear()); // 新しいCodeGearの生成 + cgm.GetLocalDGM().Put("transform", transform); + } + public void Update() { // 毎フレーム呼び出し + pos = otherTransform.position; + Vector3 newPos = new Vector3(pos.x + 3, pos.y, pos.z + 3); + cgm.GetLocalDGM().Put("pos", newPos); + } + private void LateUpdate() { // 次のフレーム直前に呼び出し + cgm.Setup(new PositionAssignCodeGear()); + } +} + +</code></pre> -<h3 id="unity">Unity</h3> +</div> + +<div class='slide'> + <!-- _S9SLIDE_ --> +<h2 id="christie-sharpのunityのコード例-1">Christie SharpのUnityのコード例</h2> <ul> - <li>UnityはUnity Technologies が開発を行っているゲームエンジンである + <li>TransformなどのUnity AIPはMainThreadでのみ動作 + <pre><code class="language-cs:PositionAssingCodeGear.cs">public class PositionAssignCodeGear : CodeGear { + [Take] private Vector3 pos; + [Peek] private Transform transform; + public override void Run(CodeGearManager cgm) { + MainThreadDispatcher.Post(_ => { // MainThreadへ処理を移譲 + transform.position = pos; + }, null); + } +} +</code></pre> + </li> +</ul> + + + +</div> + +<div class='slide'> + <!-- _S9SLIDE_ --> +<h2 id="christie-sharpの利点">Christie Sharpの利点</h2> +<ul> + <li>Unityのフレーム同期処理とChristieの並列分散処理が共存 <ul> - <li>世界中で使用されているゲームエンジン</li> - <li>非常に軽く、スペックが低いノートPCでもゲーム開発が可能</li> - </ul> - </li> - <li>プログラミング言語にはC# が採用されている - <ul> - <li>C# のAPI やUnity 向けに拡張されたAPIも使用可能</li> - <li>開発した機能をUnity に組み込むことも可能</li> + <li>CodeGear/DataGearを利用した待ち合わせ処理</li> + <li>CodeGearの処理はTaskによってThreadPoolで行われる</li> + <li>Christieを用いた非同期な並列処理が可能</li> + <li>通信が切断した際にUnityの動作に影響を与えない</li> + <li>通信先の参照データをPeekで待ち合わせないで取得する</li> + <li>Take/PutによりトランザクションとしてDataGearをUpdate</li> + <li>TopologyManagerによりDGMのproxyネットワークが構成される</li> + <li>TopologyManagerにCookieの機能があるため、改良すれば切断から復帰可能</li> </ul> </li> </ul> @@ -767,112 +694,19 @@ <div class='slide'> <!-- _S9SLIDE_ --> - - -<h3 id="christie--on-unityのコード例">Christie # on Unityのコード例</h3> -<pre><code class="language-cs:TransformMoveTest.cs">public class TransformMoveTest : MonoBehaviour { - private CodeGearManager cgm; - public Transform otherTransform; - private Vector3 pos; - - void Start() { - cgm = StartCodeGear.CreateCgm(10000); - cgm.Setup(new PositionAssignCodeGear()); - cgm.GetLocalDGM().Put("transform", transform); - } - - public void Update() { - pos = otherTransform.position; - Vector3 newPos = new Vector3(pos.x + 3, pos.y, pos.z + 3); - cgm.GetLocalDGM().Put("pos", newPos); - } - - private void LateUpdate() { - cgm.Setup(new PositionAssignCodeGear()); - } -} - -</code></pre> - -<pre><code class="language-cs:PositionAssingCodeGear.cs">public class PositionAssignCodeGear : CodeGear { - [Take] private Vector3 pos; - [Peek] private Transform transform; - - public override void Run(CodeGearManager cgm) { - MainThreadDispatcher.Post(_ => { - transform.position = pos; - }, null); - } -} - -</code></pre> - - - -</div> - -<div class='slide'> - <!-- _S9SLIDE_ --> - - -<h3 id="unityで使用されているライブラリとの比較">Unityで使用されているライブラリとの比較</h3> -<p>Unityで使用されている既存のライブラリとして、Photon Unity Networking 2(PUN2)、Mirrorと、Christie # の比較を行う。</p> - -<table> - <thead> - <tr> - <th> </th> - <th>Christie #</th> - <th>PUN2</th> - <th>Mirror</th> - </tr> - </thead> - <tbody> - <tr> - <td>通信方式</td> - <td>p2p</td> - <td>クライアントサーバ方式</td> - <td>クライアントサーバ方式</td> - </tr> - <tr> - <td>プロトコル</td> - <td>TCP</td> - <td>TCP</td> - <td>TCP</td> - </tr> - <tr> - <td>特徴</td> - <td>通信のためのIP address がプログラム直接記述されていない</td> - <td>Photon Cloud でサーバを自前で用意する必要がない</td> - <td>Unity公式でサポートされている RPC が使用可能</td> - </tr> - </tbody> -</table> - - - -</div> - -<div class='slide'> - <!-- _S9SLIDE_ --> - - -<h3 id="christie-sharpの利点">Christie Sharpの利点</h3> +<h2 id="まとめ">まとめ</h2> <ul> - <li>単体でも並列処理が可能 + <li>Christie をUnity で使用するためにC# に書き換えを行った</li> + <li>書き換え方針としては、attribute やMessagePack などC# 独自の機能に対応しつつ元のソースコードと同じ機能になるように実装</li> + <li>Unityで動作検証を行い、正しく動作することを確認した <ul> - <li>CodeGear/DataGearを利用した待ち合わせ処理</li> - <li>CodeGearの処理はTaskによってThreadPoolで行われる</li> - <li>外部のライブラリを使用しなくてもUnityで強力な並列処理が可能</li> + <li>Christie Sharpを利用したゲームの開発が可能</li> + <li>ゲーム班などでネットワークゲームを容易にプログラムできる</li> </ul> </li> - <li>通信が切断した際にゲームロジックが停止しない - <ul> - <li>通信先の参照データをPeekで取得する</li> - <li>DGMでproxyとしてデータはやりとりされているため、データは更新されないが参照は可能</li> - <li>TopologyManagerにCookieの機能があるため、改良すれば切断から復帰可能であると考える</li> - </ul> - </li> + <li>TopologyManagerで自由にネットワーク環境を構築できる</li> + <li>Take/Peek/Putを利用したゲームと相性の良いプログラミング</li> + <li>Unity既存のライブラリとの比較を行った</li> </ul> @@ -881,24 +715,19 @@ <div class='slide'> <!-- _S9SLIDE_ --> - - -<h3 id="まとめ">まとめ</h3> -<ul> - <li>Christie をUnity で使用するためにC# に書き換えを行った</li> - <li>書き換え方針としては、attribute やMessagePack などC# 独自の機能に対応しつつ元のソースコードと同じ機能になるようにした</li> - <li>Unityで動作検証を行い、正しく動作することを確認した</li> - <li>Unity既存のライブラリとの比較を行った</li> -</ul> - -<h3 id="今後の課題">今後の課題</h3> +<h2 id="今後の課題">今後の課題</h2> <ul> <li>TopologyManagerの完成 <ul> <li>2nd keyを用いたTreeMapの通信</li> </ul> </li> - <li>Christie の性能検証を行う</li> + <li>Christie Sharpの性能検証を行う + <ul> + <li>Aliceで動作していた水族館の例題</li> + <li>Christie Sharpを用いた100人規模のゲーム開発</li> + </ul> + </li> </ul>
--- a/Slide/master-slide.md Mon Feb 14 20:57:33 2022 +0900 +++ b/Slide/master-slide.md Fri Feb 18 01:09:32 2022 +0900 @@ -4,86 +4,52 @@ lang: Japanese code-engine: coderay -### 本研究における成果 -* 並列分散フレームワークChristieをUnityで動作可能に - * Unity上でp2pを基礎としたオンラインゲームの開発が可能に - -* Christie Sharpと既存のUnityの通信フレームワークとの機能的な比較を行った - * Christie Sharpの利点 - * 単体でも並列ライブラリとして機能する - * 通信切断が起こった場合でもゲームロジックが停止しない - ---- - -### 概要 -* オンラインゲームにおける通信にはクライアントサーバ方式が主流 - * データの共有はサーバを経由するため低速 -* 当研究室で開発を行っているChristie の分散計算を使用することで、高速に通信できると考えた -* Christie をUnity で使用するためにC# で書き換えを行った -* Christie SharpとUnity既存の通信フレームワークとの機能的な比較を行った - ---- - -### オンラインゲームにおけるデータ通信 -* オンラインゲームは複数のプレイヤーが関与する分散プログラム - * 分散プログラムを正しく書くことは難しい - * ネットワークの変化、故障、性能の多様性を吸収する - * スケーラビリティー リソースの追加のみでサービスの質の直感的に維持できる性能基準を備える - * Debugも困難な場合が多い -* クライアントの負荷軽減やチート対策のため、クライアントサーバ方式が主流 - * データの同期にはサーバを経由するためp2pに比べ低速 - ---- - -### オンラインゲームにおけるデータ通信 -* 当研究室では並列分散通信フレームワークChristie を開発中である - * 型のあるDataGear とKey を持つタプル空間、DataGearManager として格納している - * 他のノードはDGM のproxyを持っており、proxy に書き込むことで通信を実現している - * DGM はトポロジーマネージャーによって自動的に構築される - * プログラム自体はDGM の名前を知っていれば良い - * 他のノードのIP addressなどを知る必要はない -* ネットワークが切断されてもゲームは継続可能 -* 本研究ではChristieをC#で再実装を行い、Unityの通信ライブラリとして使用可能にする -* 既存のUnityの通信ライブラリとの機能面での比較を行い、Christie Sharpのオンラインゲーム向けの通信ライブラリとしての考察を行う - ---- - -### Christie の基礎概念 -* Christie は当研究室で開発をしている並列分散通信フレームワークである - * 同じく当研究室で開発しているGearsOS に導入予定のため次のような概念を持っている - - -* CodeGear (クラスやスレッド) -* DataGear (変数データ) -* CodeGearManager (CG,DG,DGMを管理) -* DataGearManager (DGを管理,localとremoteの2種類がある, put操作によりDGを格納) - -<center><img src="../Paper/images/GearsRelationships.pdf" alt="message" width="550" height="350" /></center> -<center> -各Gearの関係性 -</center> - ---- - -### Christie の基礎概念 -* 全てのCGM はThreadPool と他のCGM をList として共有している -* ThreadPool はCPU に合わせた並列度でqueue に入ったThread を逐次実行していく - * 1つのThreadPool で処理を行うことでCPU のコア数に適したThread を管理でき、並列度を下げ流ことを防ぐ -* ThreadPoolを共有することメタレベルで全てのCG/DG にアクセス可能 -<center><img src="../Paper/images/ChristieClass.pdf" alt="message" width="600" height="450"></center> -<center> -Christie を同一プロセスで複数インスタンス立ち上げた際の接続の構造図 -</center> +## 並列分散フレームワークChristieとUnity +- Unityとはゲーム開発でよく使用されているゲームエンジン +- ChristieとはDataGearのTake/Putを使用した分散フレームワーク +- UnityでServer抜きのネットワークゲーム開発を行いたい + - Java版を接続するのは困難 + - C\#でChristieを実装した +- Unityに並列分散処理をスムーズに導入できた ---- +## ChristieによるUnityネットワークゲーム実装の利点 +- PUN2では企業ベースのServerが必要(開発がしづらい) +- WAN上なので低速 + - ChristieにするとLAN上での高速通信が可能 + - TopologyManagerを使うことによりLAN/WANで動的構成される + - スケーラビリティーもTopologyManagerで実現できる(分散ルーティング) + - Take/Putなので通信切断や遅延に対して対処しやすい +- Unityはフレーム単位の処理なため並列処理が苦手 + - Christieにより画面書き換えと非同期な並列処理や通信が可能 +- ChristieのMessagePack(データ通信ライブラリ)のバージョンの問題を解決 + +## Christie の計算モデル +- DataGear(通信単位となるオブジェクト)が揃った時点でCodeGearが処理を開始 +- DataGearは決まったkeyでDataGearManagerにQueueとして格納 +- 相手nodeのDataGearManagerのproxyで通信 +<center><img src="../Paper/images/Remote_DataGearManager.pdf" alt="message" width="800" height="450" /></center> -### Christie の基礎概念 annotationについて -DG を取り出すためにCG内に宣言した変数データにannotation をつける。annotationには以下の4つがある。 +## DataGearのAPI +- PutでQueueに追加 +- TakeでQueueからの取り出し +- PeekでQueueから取り出さない読み出し + - Takeされない限り同じDataGearを読み出し続ける +- フレームごとにPeekでゲームオブジェクトの状態をUnity側で見れる +- 通信停止/遅延でもUnityの動作に影響を与えない +- スケーラビリティやLAN/WAN構成はTopologyManagerのDGM porxyの管理 +## Java/C\#のannotation +- クラスやフィールドあるいはメソッドに付ける +- ユーザ定義可能なmeta計算属性 +- MessagePackで通信可能なフィールドをannotationで指定する +- Christieで通信パターンを指定するのにannotationを用いる + + + +## DGのannotation * Take * 先頭のDG を読み込み、そのDG を削除する - * DG が複数ある場合Take を使用する * Peek * 先頭のDG を読み込むがDG を削除しない * 操作をしない場合は同じデータを参照し続ける @@ -92,121 +58,154 @@ * PeekFrom * Peek と同じ動作だが、remote 先のDGMを指定できる ---- -### Topology Manager -* Christie 上でNetwork Topology を形成する - * 参加を表明したノードに名前を与える - * 必要があればノード同士の配線を自動で行う - -* 静的Topology と動的Topology 2種類がある - ---- +## Christieによる分散プログラミング +- Take/Put/Peekがデータベースのトランザクション +- ここではトランザクションはゲームプレイヤー間の合意されたイベント +- 複数のプレイヤーが関与する分散プログラムをTake/Put/Peekでローカルに記述できる +- ローカルな記述を組み合わせて分散プログラムを記述する +- ネットワークの変化、故障、性能の多様性を吸収する +- Christieのデバッガー(モデル検査など)も使用可能 +- TopologyManagerで負荷軽減やチート対策が可能 -### Topology Manager 静的Topology -* 静的Topology は以下のようなdot ファイルを与えることでNode の関係を構築できる -* それぞれのNode への通信にはIP address などは使用せずright というlabel を使用することで接続できる +## ローカルnodeから見たChristie +* 型のあるDataGear とKey を持つタプル空間、DataGearManager として格納 +* 他のノードのDGM のproxyに書き込むことで通信 +* CodeGear (クラスやスレッド) +* DataGear (変数データ) +* CodeGearManager (CG,DG,DGMを管理) +<center><img src="../Paper/images/GearsRelationships.pdf" alt="message" width="550" height="350" /></center> -<center>dot 形式による node 間接続の記述</center> -```ring.dot -digraph test { - node0 -> node1 [label="right"] - node1 -> node2 [label="right"] - node2 -> node0 [label="right"] +## Christie上でNetwork Topologyの形成 +- 参加を表明したノードにDataGearManager proxyを決まった名前で作成 +* ノード同士の配線を指示 +- 分散プログラムの開始終了 +* Treeなどの動的Topologyは自動的に接続される +<center><img src="../Paper/images/DynamicTopology.pdf" alt="message" width="550" height="350" /></center> + +## Christie Sharp のコード例 +- Mainでport10001でChristie フレームワークを起動(CreateCGM) +- 最初のCodeGearをCodeGearManagerに対して実行する +```cs +public static void Main(string[] args) { + StartCountUp start = StartCountUp(createCGM(10001)); } ``` -<center><img src="../Paper/images/ring.pdf" alt="message" width="480" height="300"></center> -<center> -ring状の接続 -</center> - - ---- - -### Topology Manager 静的Topology -* 動的Topologyは以下の図のように自動的に接続される -* 現在はTree型の接続のみに対応している - -<center><img src="../Paper/images/DynamicTopology.pdf" alt="message" width="1000" height="450" /></center> -<center>動的Topologyの接続手順</center> - - ---- - -### Christie のコード例 -* コンストラクタで与えた数字をインクリメントし、10回printする例題 -``` java:StartCountup.java -public class StartCountup extends StartCodeGear { - public StartCountup(CodeGearManager cgm) { super(cgm); } - - public static void main(String args[]) { - StartCountup start = StartCountup(createCGM(10001)); - } - - @Override - protected void run(CodeGearManager cgm) { - cgm.setup(new CountUpper()); +## CodeGear StartCountUp +- CodeGearはCodeGearManagerを引数として持つ(baseでcgmに対してアクセスを許可) +- CodeGearManagerがRun(cgm)をThreadPoolを使って呼び出す +```cs:StartCountUp.cs +public class StartCountUp : StartCodeGear { + public StartCountUp(CodeGearManager cgm) : base(cgm) { } + public override void Run(CodeGearManager cgm) { + cgm.Setup(new CountUpper()); // 新しいCodeGearを生成 CountObject count = new CountObject(1); - put("count", count); + put("count", count); // DataGear countをkey countでPut } } ``` -```java:CountUpper.java -public class CountUpper extends CodeGear { - @Take - public CountObject count; - - @Override - protected void run(CodeGearManager cgm) { - System.out.println(count); - - if (count < 10) { - cgm.setup(new CountUpper()); +## CodeGear CountUpper +- key countのDataGearが来たらCountUpperのRunが実行される +```cs:CountUpper.cs +public class CountUpper : CodeGear { + [Take] public CountObject count; // key countをTakeするannotation + public override void Run(CodeGearManager cgm) { + Console.WriteLine(count.number); + if (count.number < 10) { + cgm.Setup(new CountUpper()); // 毎回新しいCodeGearを生成 count.number += 1; put("count", count); } else { - cgm.getLocalDGM().finish(); + cgm.GetLocalDGM().Finish(); // CodeGearManagerを終了 } } } - ``` -```java:CountObject.java -@Message +## DataGear CountObject +- MessagePackを使って通信されるDataGear +- Take/Put/Peekはこれに対して行われる +```cs:CountObject.cs +[MessagePackObject] public class CountObject { public int number; - - public CountObject(int number) { + public CountObject(int number) { // コンストラクタ this.number = number; } } ``` ---- - -### Christie のコード例 - -シーケンス図を使った説明 - - ---- +## Unityの従来の通信ライブラリ +- Unityはフレーム単位で処理を行う +- IEnumeratorでフレームを跨ぐ処理を記述する +- Send/Recieveなどでは通信を記述しづらい +* Photon Unity Network 2(PUN2) + * Cloud ServerサービスPhoton Cloudがある + * Server側は開発できない +* Mirror + * OSSで開発が行われている + * メソッドをServerで実行し結果を反映 -### C\#への書き換えの意義 -* ChristieはJavaで実装されている - * C\#に書き換えを行うべきか +## Photon Unity Network2 +```cs +public class PhotonController : MonoBehaviourPunCallbacks { + void Start() { + PhotonNetwork.ConnectUsingSettings(); + } + void FixedUpdate() { + if (photonView.IsMine) { // 自身であるか + float x = Input.GetAxis("Horizontal"); + float z = Input.GetAxis("Vertical"); + CmdMoveSphere(x, z); + } + } + void CmdMoveSphere(float x, float z) { + Vector3 v = new Vector3(x, 0, z); + GetComponent<Rigidbody>().AddForce(v); + } + public override void OnConnectedToMaster() { // Server接続時のcallback + PhotonNetwork.JoinOrCreateRoom("Room", new RoomOptions(), TypedLobby.Default); + } + public override void OnJoinedRoom() { // Room接続時のcallback + PhotonNetwork.Instantiate("Charactor", Vector3.zero, Quaternion.identity); + } +} +``` -* Unityはandroidの開発向けにjarファイルからJavaのメソッドをC\#上で呼び出せる機能がある - * stringを使用してリソースディレクトリから検索し、使用 - * 高速化が求められる並列分散プログラミングには不適 -* JavaとC\#の2つの管理が必要になる - * C\#とJavaは記述方法が非常に似ており、APIもほとんど同様な機能が実装されている - * リポジトリをネスト化して対応 +## Mirror +```cs +public class PlayerController : NetworkBehaviour { + [SyncVar] float speed = 1f; + public override void OnStartServer() { // Server接続時のcallback + speed = Random.Range(1f, 10f); + } + void FixedUpdate() { + if (isLocalPlayer) { + float x = Input.GetAxis("Horizontal"); + float z = Input.GetAxis("Vertical"); + CmdMoveSphere(x, z); + } + } + [Command] // Server側で実行される + void CmdMoveSphere(float x, float z) { + Vector3 v = new Vector3(x + speed, 0, z + speed); + GetComponent<Rigidbody>().AddForce(v); + } +} +``` ---- +## C\#への書き換える利点 +- ChristieはJavaで実装されている + - C\#に書き換えを行うべきか +- JavaをC\#上で呼び出す方式 + - annotationが使用できない +- Unityはandroidの開発向けにjarファイルからJavaのメソッドをC\#上で呼び出せる機能がある + - stringを使用してリソースディレクトリから検索し、使用 + - 高速化が求められる並列分散プログラミングには不適 +- 記述方法が似ているため移植が行いやすい +- ThreadPoolをC\#で統一できる - -### 書き換えの方針 +## 書き換えの方針 * C\#で記述するChristieをChristie Sharpとする * Christie設計時の意図や、互換性を保つためChristieと同じ動作をさせる * ChristieはJava9から開発されており、非推奨なコードやが含まれている @@ -214,213 +213,83 @@ * MessagePackのバージョンアップ * ThreadPoolからTaskへ変更 - ---- - -### Java からの変更点 -* Java とC# は基本的に書き方は変わらない - - -```java:ex.java -Java -public class StartCountup extends StartCodeGear { } - -@Override -protected void run(CodeGearManager cgm) { } - -@Take String countObject; -``` - -```cs:ex.cs -C# -public class StartCountup : StartCodeGear { } - -public override void Run(CodeGearManager cgm) { } - -[Take] string countObject; -``` - ---- - -### Christie Sharp のコード例 -```cs:StartCountUp.cs -public class StartCountUp : StartCodeGear { - public StartCountUp(CodeGearManager cgm) : base(cgm) { } - - public static void Main(string[] args) { - StartCountUp start = StartCountUp(createCGM(10001)); - } - - public override void Run(CodeGearManager cgm) { - cgm.Setup(new CountUpper()); - CountObject count = new CountObject(1); - put("count", count); - } -} -``` - - -```cs:CountUpper.cs -public class CountUpper : CodeGear { - [Take] public CountObject count; - - public override void Run(CodeGearManager cgm) { - Console.WriteLine(count.number); - - if (count.number < 10) { - cgm.Setup(new CountUpper()); - count.number += 1; - put("count", count); - } else { - cgm.GetLocalDGM().Finish(); - } - } -} -``` - - -```cs:CountObject.cs -[MessagePackObject] -public class CountObject { - public int number; - - public CountObject(int number) { - this.number = number; - } -} -``` -<!-- -1. Main関数でCGM のインスタンス生成 -2. 2つのCG をsetupして待ち状態にする -3. key:hellowWorld data:"hello" がTake される -4. 変数が揃ったためStartHelloWorld のRun が実行される -5. "hello" がprintされ、再び待ち状態になる。 key:hellow data:"hello"がput される -6. key:hellowWorld data:"world" がTake され、4,5と同様に処理される -7. 変数hello とworld がput され揃ったため、FinishHelloWorld のRun が実行され、プログラムは終了する - ---> - ---- - -### Take annotationの実装 +## Take annotationの実装 * Christie ではDGを取得するためにannotation を使用している * C# ではannotation と同様の機能にattribute があり、Take をattribute で実装した - * Take はフィールド変数に対して適用する - - +- Javaの場合 ```java:Take.java @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface Take { } ``` - +- C\#の場合 ```cs:Take.cs [AttributeUsage(AttributeTargets.Field)] public class Take : Attribute { } ``` ---- - -### MessagePackの相違点 -* Christie ではMessagePack を使用してデータを圧縮し送受信している - * インスタンス内のpublic 変数に対して圧縮可能 -* バージョンが古いため、現在はサポートされていない - * そのため、最新版とは記述方法が異なる - -* 圧縮するクラスには@Message annotatoinをつける -* MessagePack インスタンスを作成後、write、read することでデータの圧縮解凍が可能 - * 圧縮されたデータはbyte[] 型になる - +## MessagePackの相違点 +* Christie ではMessagePack を使用してデータをシリアライズし送受信している + * インスタンス内のpublic 変数に対してシリアライズ可能 +* Java版はバージョンが古いため、現在はサポートされていないため最新版とは記述方法が異なる ```java:MessagePackEx.java public class MessagePackExample { - @Message + @Message // 圧縮を行うクラスにつける public static class MyMessage { public String name; public double version; } - public static void main(String[] args) throws Exception { MyMessage src = new MyMessage(); src.name = "msgpack"; src.version = 0.6; MessagePack msgpack = new MessagePack(); - // Serialize - byte[] bytes = msgpack.write(src); + byte[] bytes = msgpack.write(src); // シリアライズ // Deserialize - MyMessage dst = msgpack.read(bytes, MyMessage.class); - } + MyMessage dst = msgpack.read(bytes, MyMessage.class); // デシリアライズ } ``` ---- - -### MessagePackの相違点 +## MessagePackの相違点 * C# のMessagePack は複数存在している * java 版と似たような書き方をするMessagePack-CSharp を選択した - -* 圧縮を行いたいクラスに対してMessagePackObject attribute を付ける -* 圧縮する変数に対してkey を設定できる - * 解凍時にjson として展開できる -* データの圧縮にはMessagePackSerializer.Serialize 関数を用い、byte[] に圧縮される -* データの解凍にはMessagePackSerializer.Deserialize 関数を使用する - * Deserialize 関数はジェネリスク関数であるため<>内に解凍するデータの型情報を記述する - -```cs.MessagePackEx.cs -[MessagePackObject] +```cs +[MessagePackObject] // シリアライズしたいクラスにつける public class MyClass { - [Key(0)] + [Key(0)] // keyを指定 public int Age { get; set; } [Key(1)] public string FirstName { get; set; } [Key(2)] public string LastName { get; set; } - static void Main(string[] args) { var mc = new MyClass { Age = 99, FirstName = "hoge", LastName = "huga", }; - - byte[] bytes = MessagePackSerializer.Serialize(mc); - MyClass mc2 = MessagePackSerializer.Deserialize<MyClass>(bytes); - + byte[] bytes = MessagePackSerializer.Serialize(mc); // byte[] にシリアライズ + MyClass mc2 = MessagePackSerializer.Deserialize<MyClass>(bytes); // デシリアライズ // [99,"hoge","huga"] - var json = MessagePackSerializer.ConvertToJson(bytes); - Console.WriteLine(json); + var json = MessagePackSerializer.ConvertToJson(bytes); // Jsonとしても展開可能 } } ``` ---- - -### ThreadPoolからTaskへの書き換え -* Christie ではThreadPool を使用していた - * Christie # ではThreadPoolより高機能なTask を用いて書き換えを行った - -* Task は複雑な非同期処理を通常のコーディングと同じ感覚で直感的に記述できる -* 裏でThreadPool が動くようになっている - * 大きく動作は変わらない - ---- - -### ThreadPoolからTaskへの書き換え - +## ThreadPoolからTaskへの書き換え +- Christie ではThreadPool を使用していた ```java:PriorityThreadPoolExecutors.java public class PriorityThreadPoolExecutors { - private static class PriorityThreadPoolExecutor extends ThreadPoolExecutor { private static final int DEFAULT_PRIORITY = 0; - private static AtomicLong instanceCounter = new AtomicLong(); - - public PriorityThreadPoolExecutor(int corePoolSize, int maximumPoolSize, + public PriorityThreadPoolExecutor(int corePoolSize, int maximumPoolSize, // コンストラクタ int keepAliveTime, TimeUnit unit) { - super(corePoolSize, maximumPoolSize, keepAliveTime, unit, (BlockingQueue) new PriorityBlockingQueue<ComparableTask>(10, - ComparableTask.comparatorByPriorityAndSequentialOrder())); - } - + super(corePoolSize, maximumPoolSize, keepAliveTime, unit, + (BlockingQueue) new PriorityBlockingQueue<ComparableTask>(10, + ComparableTask.comparatorByPriorityAndSequentialOrder())); + } // 優先度によって処理順を入れ替え可能なQueueを指定 @Override public void execute(Runnable command) { super.execute(command); @@ -428,115 +297,88 @@ } } ``` - - - +## ThreadPoolからTaskへの書き換え +- Christie Sharp ではThreadPoolより高機能なTask を用いて書き換えを行った +- Task は複雑な非同期処理を通常のコーディングと同じ感覚で直感的に記述 +- 裏でThreadPool が動作するため大きく動作は変わらない ```cs:ThreadPoolExecuters.cs public class ThreadPoolExecutors { - - public ThreadPoolExecutors(int nWorkerThreads, int nIOThreads) { + public ThreadPoolExecutors(int nWorkerThreads, int nIOThreads) { // コンストラクタ ThreadPool.SetMinThreads(nWorkerThreads, nIOThreads); } - public void Execute(CodeGearExecutor command) { - Task.Factory.StartNew(() => command.Run()); + Task.Factory.StartNew(() => command.Run()); // Taskを使用 } } ``` ---- - +## Christie SharpのUnityのコード例 +* ゲームオブジェクトの座標をもう1つのゲームオブジェクトに追従させる例題 +* StartやUpdateはMonoBehaviourを継承する -### Unity -* UnityはUnity Technologies が開発を行っているゲームエンジンである - * 世界中で使用されているゲームエンジン - * 非常に軽く、スペックが低いノートPCでもゲーム開発が可能 -* プログラミング言語にはC# が採用されている - * C# のAPI やUnity 向けに拡張されたAPIも使用可能 - * 開発した機能をUnity に組み込むことも可能 - ---- - -### Christie \# on Unityのコード例 ```cs:TransformMoveTest.cs public class TransformMoveTest : MonoBehaviour { private CodeGearManager cgm; public Transform otherTransform; private Vector3 pos; - - void Start() { + void Start() { // ゲーム実行時の最初の1回呼び出し cgm = StartCodeGear.CreateCgm(10000); - cgm.Setup(new PositionAssignCodeGear()); + cgm.Setup(new PositionAssignCodeGear()); // 新しいCodeGearの生成 cgm.GetLocalDGM().Put("transform", transform); } - - public void Update() { + public void Update() { // 毎フレーム呼び出し pos = otherTransform.position; Vector3 newPos = new Vector3(pos.x + 3, pos.y, pos.z + 3); cgm.GetLocalDGM().Put("pos", newPos); } - - private void LateUpdate() { + private void LateUpdate() { // 次のフレーム直前に呼び出し cgm.Setup(new PositionAssignCodeGear()); } } ``` - +## Christie SharpのUnityのコード例 +* TransformなどのUnity AIPはMainThreadでのみ動作 ```cs:PositionAssingCodeGear.cs public class PositionAssignCodeGear : CodeGear { [Take] private Vector3 pos; [Peek] private Transform transform; - public override void Run(CodeGearManager cgm) { - MainThreadDispatcher.Post(_ => { + MainThreadDispatcher.Post(_ => { // MainThreadへ処理を移譲 transform.position = pos; }, null); } } - ``` ---- +## Christie Sharpの利点 +- Unityのフレーム同期処理とChristieの並列分散処理が共存 + - CodeGear/DataGearを利用した待ち合わせ処理 + - CodeGearの処理はTaskによってThreadPoolで行われる + - Christieを用いた非同期な並列処理が可能 + - 通信が切断した際にUnityの動作に影響を与えない + - 通信先の参照データをPeekで待ち合わせないで取得する + - Take/PutによりトランザクションとしてDataGearをUpdate + - TopologyManagerによりDGMのproxyネットワークが構成される + - TopologyManagerにCookieの機能があるため、改良すれば切断から復帰可能 + +## まとめ +* Christie をUnity で使用するためにC# に書き換えを行った +* 書き換え方針としては、attribute やMessagePack などC# 独自の機能に対応しつつ元のソースコードと同じ機能になるように実装 +* Unityで動作検証を行い、正しく動作することを確認した + * Christie Sharpを利用したゲームの開発が可能 + * ゲーム班などでネットワークゲームを容易にプログラムできる +* TopologyManagerで自由にネットワーク環境を構築できる +* Take/Peek/Putを利用したゲームと相性の良いプログラミング +* Unity既存のライブラリとの比較を行った -### Unityで使用されているライブラリとの比較 -Unityで使用されている既存のライブラリとして、Photon Unity Networking 2(PUN2)、Mirrorと、Christie # の比較を行う。 - -| | Christie # | PUN2 | Mirror | -|--- |--- | --- |---| -|通信方式 |p2p |クライアントサーバ方式 | クライアントサーバ方式| -|プロトコル | TCP | TCP | TCP | -|特徴 |通信のためのIP address がプログラム直接記述されていない |Photon Cloud でサーバを自前で用意する必要がない | Unity公式でサポートされている RPC が使用可能| - ---- - -### Christie Sharpの利点 -* 単体でも並列処理が可能 - * CodeGear/DataGearを利用した待ち合わせ処理 - * CodeGearの処理はTaskによってThreadPoolで行われる - * 外部のライブラリを使用しなくてもUnityで強力な並列処理が可能 -* 通信が切断した際にゲームロジックが停止しない - * 通信先の参照データをPeekで取得する - * DGMでproxyとしてデータはやりとりされているため、データは更新されないが参照は可能 - * TopologyManagerにCookieの機能があるため、改良すれば切断から復帰可能であると考える +## 今後の課題 +* TopologyManagerの完成 + * 2nd keyを用いたTreeMapの通信 +* Christie Sharpの性能検証を行う + * Aliceで動作していた水族館の例題 + * Christie Sharpを用いた100人規模のゲーム開発 ---- - - -### まとめ -* Christie をUnity で使用するためにC# に書き換えを行った -* 書き換え方針としては、attribute やMessagePack などC# 独自の機能に対応しつつ元のソースコードと同じ機能になるようにした -* Unityで動作検証を行い、正しく動作することを確認した -* Unity既存のライブラリとの比較を行った - -### 今後の課題 -* TopologyManagerの完成 - * 2nd keyを用いたTreeMapの通信 -* Christie の性能検証を行う - - - -
--- a/riono-master.mm Mon Feb 14 20:57:33 2022 +0900 +++ b/riono-master.mm Fri Feb 18 01:09:32 2022 +0900 @@ -91,9 +91,7 @@ </richcontent> </node> </node> -<node TEXT="annotation" ID="ID_1575265406" CREATED="1620127338849" MODIFIED="1643802654010"> -<cloud COLOR="#f0f0f0" SHAPE="ARC"/> -</node> +<node TEXT="annotation" ID="ID_1575265406" CREATED="1620127338849" MODIFIED="1644841509025"/> <node TEXT="MessagePack" ID="ID_839127787" CREATED="1620127345893" MODIFIED="1620127351486"/> <node TEXT="ThreadからTaskへ" ID="ID_105028350" CREATED="1620127352019" MODIFIED="1620127370790"/> <node TEXT="送信パケットの変更" ID="ID_1310134337" CREATED="1643795005693" MODIFIED="1643795023242"/> @@ -120,6 +118,57 @@ </node> <node TEXT="まとめ" ID="ID_1303888531" CREATED="1619881638327" MODIFIED="1619881642359"/> </node> +<node TEXT="プレゼン" POSITION="right" ID="ID_1974620960" CREATED="1644841528783" MODIFIED="1644841534632"> +<node TEXT="研究の成果" ID="ID_854031978" CREATED="1644841540087" MODIFIED="1644841553718"> +<node TEXT="新しくできるようになったこと" ID="ID_1328679357" CREATED="1644841563620" MODIFIED="1644841573828"> +<node TEXT="Unityに比べて" ID="ID_454115395" CREATED="1644841598320" MODIFIED="1644841611612"> +<node TEXT="Unityは並列処理が弱い" ID="ID_871630554" CREATED="1644841658242" MODIFIED="1644841668340"> +<node TEXT="画面書き換え単位で処理が進む" ID="ID_1358187259" CREATED="1644841674615" MODIFIED="1644841684477"/> +<node TEXT="画面書き換えと非同期な並列処理" ID="ID_101160986" CREATED="1644841687776" MODIFIED="1644841699334"/> +<node TEXT="非同期な処理としての分散計算" ID="ID_1384666478" CREATED="1644841701211" MODIFIED="1644841721939"/> +</node> +</node> +<node TEXT="Unity+通信ライブラリ" ID="ID_1554066335" CREATED="1644841614215" MODIFIED="1644841626905"> +<node TEXT=" PUN2" ID="ID_1255564441" CREATED="1644841988278" MODIFIED="1644841998178"> +<node TEXT="Unity Objectに完全に対応している" ID="ID_1179988392" CREATED="1644842014429" MODIFIED="1644842038772"/> +</node> +<node TEXT="Mirror" ID="ID_1299922410" CREATED="1644842001277" MODIFIED="1644842004160"/> +<node TEXT="比較項目" ID="ID_1472494300" CREATED="1644842055205" MODIFIED="1644842060278"> +<node TEXT="通信モデル" ID="ID_597796749" CREATED="1644842061796" MODIFIED="1644842067593"> +<node TEXT="DG単位の通信" ID="ID_1899600173" CREATED="1644842073476" MODIFIED="1644842091622"/> +<node TEXT="TopologyManager" ID="ID_1437535252" CREATED="1644842092994" MODIFIED="1644842098478"/> +<node TEXT="Dataグラムによる通信の相性が良い" ID="ID_1256665458" CREATED="1644842098632" MODIFIED="1644842160143"/> +</node> +</node> +</node> +<node TEXT="Server" ID="ID_153764757" CREATED="1644841642589" MODIFIED="1644841644976"> +<node TEXT="ゲーム会社がサーバーを立てて管理が通常" ID="ID_1188676264" CREATED="1644841743303" MODIFIED="1644842712020"/> +<node TEXT="TopologyManagerを使うとユーザー間でサーバなしでネットワークゲームができる" ID="ID_1984137247" CREATED="1644841928818" MODIFIED="1644841950352"/> +<node TEXT="チート対策もTopologyManager経由で可能" ID="ID_677735069" CREATED="1644841957765" MODIFIED="1644841975770"/> +</node> +<node TEXT="C#で書き換える利点" ID="ID_1159772395" CREATED="1644841745260" MODIFIED="1644841753101"> +<node TEXT="Javaを呼び出す方式" ID="ID_798969767" CREATED="1644841797785" MODIFIED="1644841820450"> +<node TEXT="アノテーションが使えない" ID="ID_1162048351" CREATED="1644841821127" MODIFIED="1644841826590"/> +</node> +<node TEXT="移植がしやすい" ID="ID_1208767592" CREATED="1644841835626" MODIFIED="1644841842126"/> +<node TEXT="ThreadPoolをC#に統一できる" ID="ID_912830635" CREATED="1644841859276" MODIFIED="1644841897787"/> +</node> +<node TEXT="C#への書き換えの実際" ID="ID_273375351" CREATED="1644842433236" MODIFIED="1644842468959"> +<node TEXT="annotation" ID="ID_1465326074" CREATED="1644842474567" MODIFIED="1644842479720"/> +<node TEXT="MessagePackのバージョン" ID="ID_1673201828" CREATED="1644842480647" MODIFIED="1644842486066"/> +</node> +<node TEXT="結論" ID="ID_782874845" CREATED="1644841792518" MODIFIED="1644842235062"> +<node TEXT="成果" ID="ID_906931944" CREATED="1644842237402" MODIFIED="1644842247540"> +<node TEXT="Unity上でChristieが動作する" ID="ID_1025072226" CREATED="1644842248181" MODIFIED="1644842263446"/> +<node TEXT="ゲーム班で使用可能" ID="ID_411675891" CREATED="1644842266439" MODIFIED="1644842319190"/> +<node TEXT="TopologyManagerで自由にネットワーク環境を構築できる" ID="ID_1238323421" CREATED="1644842321122" MODIFIED="1644842342626"/> +<node TEXT="Take/put/peekを使ったゲームと相性の良いプログラム" ID="ID_925790403" CREATED="1644842343360" MODIFIED="1644842362897"/> +<node TEXT="既存のライブラリと比較して優れている" ID="ID_477160341" CREATED="1644842363524" MODIFIED="1644842403787"/> +</node> +</node> +</node> +</node> +</node> <node TEXT="はじめに" POSITION="left" ID="ID_1644666126" CREATED="1619756384349" MODIFIED="1619756397491"> <node TEXT="ゲームのデータ通信方式" ID="ID_1581711876" CREATED="1619756398687" MODIFIED="1619762332877"> <node TEXT="p2p" ID="ID_1698051729" CREATED="1619762383607" MODIFIED="1619762385444"/>