# HG changeset patch # User riono # Date 1645114172 -32400 # Node ID c269b11bb810217a61b981c555d1c5ee7e716656 # Parent 309de2ffb2bdbf2fb59ce70f3d35fbbdd092605e update slide and add poster diff -r 309de2ffb2bd -r c269b11bb810 Paper/images/Remote_DataGearManager.graffle Binary file Paper/images/Remote_DataGearManager.graffle has changed diff -r 309de2ffb2bd -r c269b11bb810 Paper/images/Remote_DataGearManager.pdf Binary file Paper/images/Remote_DataGearManager.pdf has changed diff -r 309de2ffb2bd -r c269b11bb810 Poster/riono-poster.graffle/data.plist --- /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 @@ + + + + + ActiveLayerIndex + 0 + ApplicationVersion + + com.omnigroup.OmniGraffle6 + 169.23.0.276662 + + AutoAdjust + + BackgroundGraphic + + Bounds + {{0, 0}, {2860.68505859375, 2027.6220703125}} + Class + SolidGraphic + FontInfo + + Font + Helvetica + Size + 28 + + ID + 2 + Style + + stroke + + Draws + NO + + + + BaseZoom + 0 + CanvasOrigin + {0, 0} + ColorProfiles + + + data + + AAACJGFwcGwEAAAAbW50clJHQiBYWVogB+EABwAHAA0AFgAgYWNz + cEFQUEwAAAAAQVBQTAAAAAAAAAAAAAAAAAAAAAAAAPbWAAEAAAAA + 0y1hcHBsyhqVgiV/EE04mRPV0eoVggAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAKZGVzYwAAAPwAAABlY3BydAAAAWQAAAAj + d3RwdAAAAYgAAAAUclhZWgAAAZwAAAAUZ1hZWgAAAbAAAAAUYlhZ + WgAAAcQAAAAUclRSQwAAAdgAAAAgY2hhZAAAAfgAAAAsYlRSQwAA + AdgAAAAgZ1RSQwAAAdgAAAAgZGVzYwAAAAAAAAALRGlzcGxheSBQ + MwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAB0ZXh0AAAAAENvcHlyaWdodCBBcHBsZSBJbmMuLCAyMDE3 + AABYWVogAAAAAAAA81EAAQAAAAEWzFhZWiAAAAAAAACD3wAAPb// + //+7WFlaIAAAAAAAAEq/AACxNwAACrlYWVogAAAAAAAAKDgAABEL + AADIuXBhcmEAAAAAAAMAAAACZmYAAPKnAAANWQAAE9AAAApbc2Yz + MgAAAAAAAQxCAAAF3v//8yYAAAeTAAD9kP//+6L///2jAAAD3AAA + wG4= + + space + 031375ea2e6fd7f8c2ca30fdc720c8d7c8a37a18 + + + ColumnAlign + 1 + ColumnSpacing + 36 + CreationDate + 2012-01-04 16:02:58 +0000 + Creator + Daichi TOMA + DisplayScale + 1.0000 cm = 1.0000 cm + GraphDocumentVersion + 12 + GraphicsList + + + Bounds + {{1920.9282427555847, 1012.5742065735318}, {908.50394525086881, 273.54330956851396}} + Class + ShapedGraphic + FontInfo + + Size + 22 + + ID + 5039 + Style + + fill + + Color + + b + 0.8509600759 + g + 0.99431246520000005 + r + 0.99912756680000003 + space + 031375ea2e6fd7f8c2ca30fdc720c8d7c8a37a18 + + + shadow + + Draws + NO + + + Text + + Align + 0 + RTFD + + 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 + + Text + {\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);\ + \}\ +\}} + + TextPlacement + 0 + + + Bounds + {{1921.8897812171235, 412.94670269960034}, {908.50394525086881, 582.52582606280043}} + Class + ShapedGraphic + FontInfo + + Color + + b + 0.574885 + g + 0.328521 + r + 0 + space + srgb + + Size + 22 + + ID + 5038 + Style + + fill + + Color + + b + 0.8509600759 + g + 0.99431246520000005 + r + 0.99912756680000003 + space + 031375ea2e6fd7f8c2ca30fdc720c8d7c8a37a18 + + + shadow + + Draws + NO + + + Text + + Align + 0 + RTFD + + 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== + + Text + {\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());\ + \}\ +\}} + + TextPlacement + 0 + + + Class + Group + Graphics + + + Bounds + {{1908.2488463061477, 1600.732673778054}, {936.31810863689566, 406.19647828938582}} + Class + ShapedGraphic + FontInfo + + Color + + b + 0 + g + 0 + r + 0 + + Font + HiraKakuProN-W6 + Size + 30 + + ID + 5028 + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + Align + 0 + Pad + 0.0 + RTFD + + 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 + + Text + {\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} + VerticalPad + 1 + + TextPlacement + 0 + + + Class + Group + Graphics + + + Bounds + {{2002.6771835249242, 1549.8084725565413}, {802.20473168797366, 50.924201221512725}} + Class + ShapedGraphic + FontInfo + + Color + + b + 1 + g + 1 + r + 1 + + Font + HiraKakuProN-W3 + Size + 46 + + ID + 5030 + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + Align + 0 + Pad + 0.0 + Text + {\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} + VerticalPad + 0.0 + + + + Class + Group + Graphics + + + Class + LineGraphic + ID + 5032 + Points + + {1931.8885147672461, 1565.1707480148552} + {1950.5567611693905, 1564.2376659742974} + {1971.5096364431884, 1567.2911708677486} + + Style + + stroke + + Color + + b + 1 + g + 1 + r + 1 + + HeadArrow + FilledBall + Legacy + + TailArrow + 0 + Width + 3 + + + Tail + + ID + 5033 + Position + 0.32640770077705383 + + + + Class + LineGraphic + ID + 5033 + Points + + {1925.1727156249158, 1580.2158841257863} + {1936.2131502966972, 1555.4824400723721} + {1938.2653952099181, 1554.5957837295043} + {1959.4208214492714, 1554.5957837295043} + + Style + + stroke + + Color + + b + 1 + g + 1 + r + 1 + + HeadArrow + FilledBall + Legacy + + TailArrow + 0 + Width + 3 + + + Tail + + ID + 5034 + Position + 0.25490197539329529 + + + + Class + LineGraphic + ID + 5034 + Points + + {1912.0729627231049, 1579.9865580059916} + {1949.7974776932929, 1580.6469686796961} + {1963.4504264472444, 1579.9865580059916} + + Style + + stroke + + Color + + b + 1 + g + 1 + r + 1 + + HeadArrow + FilledBall + Legacy + + TailArrow + 0 + Width + 3 + + + + + Bounds + {{1908.2488463061477, 1541.9285512950962}, {936.31810863689566, 47.436242233737872}} + Class + ShapedGraphic + ID + 5035 + Style + + fill + + Color + + b + 0.80000000000000004 + g + 0.59999999999999998 + r + 0.20000000000000001 + + FillType + 2 + GradientAngle + 90 + GradientColor + + b + 0.8 + g + 0.4 + r + 0 + + + shadow + + Draws + NO + + stroke + + Width + 0.5 + + + + + ID + 5031 + + + ID + 5029 + + + Bounds + {{1907.7165527420721, 1541.9285512950969}, {936.85040220097289, 469.25256931485865}} + Class + ShapedGraphic + FontInfo + + Size + 30 + + ID + 5036 + Style + + shadow + + Draws + NO + + stroke + + Width + 0.5 + + + + + ID + 5027 + + + Class + Group + Graphics + + + Bounds + {{959.01056932894892, 1058.016729974162}, {936.31810863689566, 821.35336581780484}} + Class + ShapedGraphic + FontInfo + + Color + + b + 0 + g + 0 + r + 0 + + Font + HiraKakuProN-W6 + Size + 30 + + ID + 5018 + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + Align + 0 + Pad + 0.0 + RTFD + + 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== + + Text + {\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} + VerticalPad + 1 + + TextPlacement + 0 + + + Class + Group + Graphics + + + Bounds + {{1053.4389065477255, 1007.0925287526497}, {802.20473168797366, 50.924201221512725}} + Class + ShapedGraphic + FontInfo + + Color + + b + 1 + g + 1 + r + 1 + + Font + HiraKakuProN-W3 + Size + 46 + + ID + 5020 + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + Align + 0 + Pad + 0.0 + Text + {\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} + VerticalPad + 0.0 + + + + Class + Group + Graphics + + + Class + LineGraphic + ID + 5022 + Points + + {982.65023779004753, 1022.4548042109631} + {1001.3184841921918, 1021.5217221704052} + {1022.2713594659901, 1024.5752270638563} + + Style + + stroke + + Color + + b + 1 + g + 1 + r + 1 + + HeadArrow + FilledBall + Legacy + + TailArrow + 0 + Width + 3 + + + Tail + + ID + 5023 + Position + 0.32640770077705383 + + + + Class + LineGraphic + ID + 5023 + Points + + {975.93443864771746, 1037.499940321894} + {986.97487331949856, 1012.7664962684798} + {989.02711823271966, 1011.8798399256125} + {1010.1825444720725, 1011.8798399256125} + + Style + + stroke + + Color + + b + 1 + g + 1 + r + 1 + + HeadArrow + FilledBall + Legacy + + TailArrow + 0 + Width + 3 + + + Tail + + ID + 5024 + Position + 0.25490197539329529 + + + + Class + LineGraphic + ID + 5024 + Points + + {962.83468574590643, 1037.2706142020993} + {1000.5592007160947, 1037.9310248758038} + {1014.2121494700459, 1037.2706142020993} + + Style + + stroke + + Color + + b + 1 + g + 1 + r + 1 + + HeadArrow + FilledBall + Legacy + + TailArrow + 0 + Width + 3 + + + + + Bounds + {{959.01056932894971, 999.21260749120393}, {936.31810863689566, 47.436242233737872}} + Class + ShapedGraphic + ID + 5025 + Style + + fill + + Color + + b + 0.80000000000000004 + g + 0.59999999999999998 + r + 0.20000000000000001 + + FillType + 2 + GradientAngle + 90 + GradientColor + + b + 0.8 + g + 0.4 + r + 0 + + + shadow + + Draws + NO + + stroke + + Width + 0.5 + + + + + ID + 5021 + + + ID + 5019 + + + Bounds + {{958.47827576487316, 999.21260749120484}, {936.85040220097289, 1011.9685131187507}} + Class + ShapedGraphic + FontInfo + + Size + 30 + + ID + 5026 + Style + + shadow + + Draws + NO + + stroke + + Width + 0.5 + + + + + ID + 5017 + + + Class + Group + Graphics + + + Bounds + {{1908.2488463061472, 277.07184099876758}, {936.31810863689566, 1245.4887618682865}} + Class + ShapedGraphic + FontInfo + + Color + + b + 0 + g + 0 + r + 0 + + Font + HiraKakuProN-W6 + Size + 30 + + ID + 5008 + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + Align + 0 + Pad + 0.0 + Text + {\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} + VerticalPad + 1 + + TextPlacement + 0 + + + Class + Group + Graphics + + + Bounds + {{2002.6771835249242, 226.14763977725465}, {802.20473168797366, 50.924201221512725}} + Class + ShapedGraphic + FontInfo + + Color + + b + 1 + g + 1 + r + 1 + + Font + HiraKakuProN-W3 + Size + 46 + + ID + 5010 + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + Align + 0 + Pad + 0.0 + Text + {\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} + VerticalPad + 0.0 + + + + Class + Group + Graphics + + + Class + LineGraphic + ID + 5012 + Points + + {1931.8885147672461, 241.50991523556789} + {1950.5567611693905, 240.57683319501029} + {1971.5096364431884, 243.63033808846149} + + Style + + stroke + + Color + + b + 1 + g + 1 + r + 1 + + HeadArrow + FilledBall + Legacy + + TailArrow + 0 + Width + 3 + + + Tail + + ID + 5013 + Position + 0.32640770077705383 + + + + Class + LineGraphic + ID + 5013 + Points + + {1925.1727156249158, 256.55505134649906} + {1936.2131502966972, 231.82160729308475} + {1938.2653952099181, 230.93495095021717} + {1959.4208214492714, 230.93495095021717} + + Style + + stroke + + Color + + b + 1 + g + 1 + r + 1 + + HeadArrow + FilledBall + Legacy + + TailArrow + 0 + Width + 3 + + + Tail + + ID + 5014 + Position + 0.25490197539329529 + + + + Class + LineGraphic + ID + 5014 + Points + + {1912.0729627231049, 256.32572522670444} + {1949.7974776932929, 256.98613590040895} + {1963.4504264472444, 256.32572522670444} + + Style + + stroke + + Color + + b + 1 + g + 1 + r + 1 + + HeadArrow + FilledBall + Legacy + + TailArrow + 0 + Width + 3 + + + + + Bounds + {{1908.2488463061477, 218.26771851580907}, {936.31810863689566, 47.436242233737872}} + Class + ShapedGraphic + ID + 5015 + Style + + fill + + Color + + b + 0.80000000000000004 + g + 0.59999999999999998 + r + 0.20000000000000001 + + FillType + 2 + GradientAngle + 90 + GradientColor + + b + 0.8 + g + 0.4 + r + 0 + + + shadow + + Draws + NO + + stroke + + Width + 0.5 + + + + + ID + 5011 + + + ID + 5009 + + + Bounds + {{1907.7165527420716, 218.26771851581009}, {936.85040220097289, 1315.6314671312862}} + Class + ShapedGraphic + FontInfo + + Size + 30 + + ID + 5016 + Style + + shadow + + Draws + NO + + stroke + + Width + 0.5 + + + + + ID + 5007 + + + Class + Group + Graphics + + + Bounds + {{957.17957446617186, 266.45669533098754}, {936.31810863689566, 710.07874660013238}} + Class + ShapedGraphic + FontInfo + + Color + + b + 0 + g + 0 + r + 0 + + Font + HiraKakuProN-W6 + Size + 30 + + ID + 4998 + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + Align + 0 + Pad + 0.0 + RTFD + + 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 + + Text + {\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} + VerticalPad + 1 + + TextPlacement + 0 + + + Class + Group + Graphics + + + Bounds + {{1054.132333897498, 221.9803722856407}, {802.20473168797366, 51.733664314227305}} + Class + ShapedGraphic + FontInfo + + Color + + b + 1 + g + 1 + r + 1 + + Font + HiraKakuProN-W3 + Size + 46 + + ID + 5000 + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + Align + 0 + Pad + 0.0 + Text + {\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} + VerticalPad + 0.0 + + + + Class + Group + Graphics + + + Class + LineGraphic + ID + 5002 + Points + + {983.30369127435597, 237.67791543601396} + {1002.0119115419645, 236.63892422545831} + {1022.9647868157626, 239.74096595317249} + + Style + + stroke + + Color + + b + 1 + g + 1 + r + 1 + + HeadArrow + FilledBall + Legacy + + TailArrow + 0 + Width + 3 + + + Tail + + ID + 5003 + Position + 0.32640770077705383 + + + + Class + LineGraphic + ID + 5003 + Points + + {976.62797858837746, 252.87112534652593} + {987.66830066927093, 227.74453006824373} + {989.72054558249215, 226.84377992383855} + {1010.875971821845, 226.84377992383855} + + Style + + stroke + + Color + + b + 1 + g + 1 + r + 1 + + HeadArrow + FilledBall + Legacy + + TailArrow + 0 + Width + 3 + + + Tail + + ID + 5004 + Position + 0.25490197539329529 + + + + Class + LineGraphic + ID + 5004 + Points + + {963.52811309567892, 252.63815198250521} + {1001.2526280658672, 253.30906018103244} + {1014.9055768198184, 252.63815198250521} + + Style + + stroke + + Color + + b + 1 + g + 1 + r + 1 + + HeadArrow + FilledBall + Legacy + + TailArrow + 0 + Width + 3 + + + + + Bounds + {{959.70399667872209, 213.97519613002663}, {936.31810863689566, 48.190262648869265}} + Class + ShapedGraphic + ID + 5005 + Style + + fill + + Color + + b + 0.80000000000000004 + g + 0.59999999999999998 + r + 0.20000000000000001 + + FillType + 2 + GradientAngle + 90 + GradientColor + + b + 0.8 + g + 0.4 + r + 0 + + + shadow + + Draws + NO + + stroke + + Width + 0.5 + + + + + ID + 5001 + + + ID + 4999 + + + Bounds + {{959.17170311464542, 213.97519613002697}, {936.85040220097289, 773.89882858113504}} + Class + ShapedGraphic + FontInfo + + Size + 30 + + ID + 5006 + Style + + shadow + + Draws + NO + + stroke + + Width + 0.5 + + + + + ID + 4997 + + + Bounds + {{36.850394035136603, 1405.9842647252119}, {871.65355121573123, 600.37796287470906}} + Class + ShapedGraphic + ID + 4996 + ImageID + 33 + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Draws + NO + + + + + Class + Group + Graphics + + + Bounds + {{13.288199191623164, 903.52853959608785}, {936.31810863689566, 498.20375658660828}} + Class + ShapedGraphic + FontInfo + + Color + + b + 0 + g + 0 + r + 0 + + Font + HiraKakuProN-W6 + Size + 30 + + ID + 4985 + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + Align + 0 + Pad + 0.0 + RTFD + + 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== + + Text + {\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} + VerticalPad + 1 + + TextPlacement + 0 + + + Class + Group + Graphics + + + Bounds + {{107.71653641039933, 852.60433837457708}, {802.20473168797366, 50.924201221512725}} + Class + ShapedGraphic + FontInfo + + Color + + b + 1 + g + 1 + r + 1 + + Font + HiraKakuProN-W3 + Size + 46 + + ID + 4987 + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + Align + 0 + Pad + 0.0 + Text + {\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} + VerticalPad + 0.0 + + + + Class + Group + Graphics + + + Class + LineGraphic + ID + 4989 + Points + + {36.927867652721304, 867.9666138328904} + {55.596114054866462, 867.03353179233284} + {76.548989328664504, 870.08703668578391} + + Style + + stroke + + Color + + b + 1 + g + 1 + r + 1 + + HeadArrow + FilledBall + Legacy + + TailArrow + 0 + Width + 3 + + + Tail + + ID + 4990 + Position + 0.32640770077705383 + + + + Class + LineGraphic + ID + 4990 + Points + + {30.212068510391518, 883.01174994382154} + {41.252503182172042, 858.27830589040718} + {43.304748095393229, 857.3916495475396} + {64.46017433474654, 857.3916495475396} + + Style + + stroke + + Color + + b + 1 + g + 1 + r + 1 + + HeadArrow + FilledBall + Legacy + + TailArrow + 0 + Width + 3 + + + Tail + + ID + 4991 + Position + 0.25490197539329529 + + + + Class + LineGraphic + ID + 4991 + Points + + {17.112315608580438, 882.78242382402686} + {54.836830578768655, 883.44283449773138} + {68.489779332720047, 882.78242382402686} + + Style + + stroke + + Color + + b + 1 + g + 1 + r + 1 + + HeadArrow + FilledBall + Legacy + + TailArrow + 0 + Width + 3 + + + + + Bounds + {{13.288199191623846, 844.72441711313149}, {936.31810863689566, 47.436242233737872}} + Class + ShapedGraphic + ID + 4992 + Style + + fill + + Color + + b + 0.80000000000000004 + g + 0.59999999999999998 + r + 0.20000000000000001 + + FillType + 2 + GradientAngle + 90 + GradientColor + + b + 0.8 + g + 0.4 + r + 0 + + + shadow + + Draws + NO + + stroke + + Width + 0.5 + + + + + ID + 4988 + + + ID + 4986 + + + Bounds + {{12.755905627547179, 844.72441711313343}, {936.85040220097289, 1166.456703496822}} + Class + ShapedGraphic + FontInfo + + Size + 30 + + ID + 4993 + Style + + shadow + + Draws + NO + + stroke + + Width + 0.5 + + + + + ID + 4984 + + + Bounds + {{2639.0551420547827, 21.259842712578809}, {149.29057682701156, 14.648487363211407}} + Class + ShapedGraphic + FontInfo + + Font + HiraKakuProN-W6 + Size + 2018 + + ID + 4800 + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + Align + 0 + Pad + 0.0 + Text + {\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} + VerticalPad + 0.0 + + + + Bounds + {{1396.9579120299818, 1469.1245769703978}, {14.485579649894881, 22}} + Class + ShapedGraphic + FitText + Vertical + Flow + Resize + ID + 4873 + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Draws + NO + + + + + Class + Group + Graphics + + + Bounds + {{13.288199191623221, 274.07801991168378}, {936.31810863689566, 557.89049157390036}} + Class + ShapedGraphic + FontInfo + + Color + + b + 0 + g + 0 + r + 0 + + Font + HiraKakuProN-W6 + Size + 30 + + ID + 4975 + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + Align + 0 + Pad + 0.0 + Text + {\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} + VerticalPad + 1 + + TextPlacement + 0 + + + Class + Group + Graphics + + + Bounds + {{107.71653641039939, 223.15381869017108}, {802.20473168797366, 50.924201221512725}} + Class + ShapedGraphic + FontInfo + + Color + + b + 1 + g + 1 + r + 1 + + Font + HiraKakuProN-W3 + Size + 46 + + ID + 4977 + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + Align + 0 + Pad + 0.0 + Text + {\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} + VerticalPad + 0.0 + + + + Class + Group + Graphics + + + Class + LineGraphic + ID + 4979 + Points + + {36.927867652721538, 238.51609414848446} + {55.596114054866057, 237.58301210792678} + {76.548989328664135, 240.63651700137788} + + Style + + stroke + + Color + + b + 1 + g + 1 + r + 1 + + HeadArrow + FilledBall + Legacy + + TailArrow + 0 + Width + 3 + + + Tail + + ID + 4980 + Position + 0.32640770077705383 + + + + Class + LineGraphic + ID + 4980 + Points + + {30.212068510391461, 253.56123025941548} + {41.252503182172553, 228.82778620600121} + {43.304748095393741, 227.94112986313363} + {64.460174334746483, 227.94112986313363} + + Style + + stroke + + Color + + b + 1 + g + 1 + r + 1 + + HeadArrow + FilledBall + Legacy + + TailArrow + 0 + Width + 3 + + + Tail + + ID + 4981 + Position + 0.25490197539329529 + + + + Class + LineGraphic + ID + 4981 + Points + + {17.112315608580378, 253.33190413962086} + {54.836830578768605, 253.99231481332538} + {68.489779332719991, 253.33190413962086} + + Style + + stroke + + Color + + b + 1 + g + 1 + r + 1 + + HeadArrow + FilledBall + Legacy + + TailArrow + 0 + Width + 3 + + + + + Bounds + {{13.288199191623789, 215.27389742872546}, {936.31810863689566, 47.436242233737872}} + Class + ShapedGraphic + ID + 4982 + Style + + fill + + Color + + b + 0.80000000000000004 + g + 0.59999999999999998 + r + 0.20000000000000001 + + FillType + 2 + GradientAngle + 90 + GradientColor + + b + 0.8 + g + 0.4 + r + 0 + + + shadow + + Draws + NO + + stroke + + Width + 0.5 + + + + + ID + 4978 + + + ID + 4976 + + + Bounds + {{12.755905627547179, 215.2738974287264}, {936.85040220097289, 616.69461405685774}} + Class + ShapedGraphic + FontInfo + + Size + 30 + + ID + 4983 + Style + + shadow + + Draws + NO + + stroke + + Width + 0.5 + + + + + ID + 4974 + + + Bounds + {{2423.6220692339843, 102.04724502037828}, {397.14630873461806, 96.707721339814199}} + Class + ShapedGraphic + ID + 3434 + ImageID + 22 + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Draws + NO + + + + + Bounds + {{2168.5039566830387, 128.9763791229781}, {205.51181288825956, 89.291339392830963}} + Class + ShapedGraphic + FontInfo + + Color + + b + 1 + g + 1 + r + 1 + + Font + HiraKakuProN-W3 + Size + 13 + + ID + 24 + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + Align + 0 + Pad + 0.0 + Text + {\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} + VerticalPad + 0.0 + + + + Bounds + {{36.850394035136603, 40.752022750004322}, {2167.0866338355336, 66.964513660394985}} + Class + ShapedGraphic + FontInfo + + Font + HiraKakuProN-W6 + Size + 110 + + ID + 5 + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + Align + 0 + Pad + 0.0 + Text + {\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} + VerticalPad + 0.0 + + + + Bounds + {{12.755905627547236, 14.173228475052539}, {2831.8110493154973, 189.7327887044525}} + Class + ShapedGraphic + FontInfo + + Font + Helvetica + Size + 10 + + ID + 23 + Style + + fill + + Color + + b + 0.91372500000000001 + g + 0.62745099999999998 + r + 0.0 + + FillType + 2 + GradientAngle + 90 + GradientColor + + b + 0.72549 + g + 0.419608 + r + 0 + + + shadow + + Draws + NO + + stroke + + Width + 0.5 + + + + + GridInfo + + GridSpacing + 35.433071136474609 + ShowsGrid + YES + + GuidesLocked + NO + GuidesVisible + YES + HPages + 1 + ImageCounter + 34 + ImageLinkBack + + + + + ImageList + + image33.pdf + image22.pdf + + KeepToScale + + Layers + + + Lock + NO + Name + Layer 1 + Print + YES + Slices + NO + View + YES + + + LayoutInfo + + Animate + NO + circoMinDist + 18 + circoSeparation + 0.0 + layoutEngine + dot + neatoLineLength + 0.20000000298023224 + neatoSeparation + 0.0 + twopiSeparation + 0.0 + + LinksVisible + NO + MagnetsVisible + NO + MasterSheets + + ModificationDate + 2022-02-17 16:03:36 +0000 + Modifier + 安田亮 + NotesVisible + NO + Orientation + 1 + OriginVisible + NO + PageBreaks + YES + PrintInfo + + NSBottomMargin + + float + 41 + + NSHorizonalPagination + + coded + BAtzdHJlYW10eXBlZIHoA4QBQISEhAhOU051bWJlcgCEhAdOU1ZhbHVlAISECE5TT2JqZWN0AIWEASqEhAFxlwCG + + NSLeftMargin + + float + 18 + + NSPaperName + + string + ADA99C75-491B-4B6C-AD03-A113BC153C21 + + NSPaperSize + + size + {2063.6220703125, 2919.68505859375} + + NSPrintReverseOrientation + + coded + BAtzdHJlYW10eXBlZIHoA4QBQISEhAhOU051bWJlcgCEhAdOU1ZhbHVlAISECE5TT2JqZWN0AIWEASqEhAFxlwCG + + NSRightMargin + + float + 18 + + NSTopMargin + + float + 18 + + + PrintOnePage + + ReadOnly + NO + RowAlign + 1 + RowSpacing + 36 + SheetTitle + Canvas 1 + SmartAlignmentGuidesActive + YES + SmartDistanceGuidesActive + YES + UniqueID + 1 + UseEntirePage + + VPages + 1 + WindowInfo + + CurrentSheet + 0 + Expanded_Canvases + + Frame + {{1819, 40}, {1792, 1057}} + ShowInfo + + Sidebar + + SidebarWidth + 200 + TopSlabHeight + 250 + VisibleRegion + {{399.99999999999994, 234.61538461538461}, {2459.6153846153843, 1792.3076923076924}} + Zoom + 0.52000000000000002 + ZoomValues + + + Canvas 1 + 0.52000000000000002 + 1.04 + + + + + diff -r 309de2ffb2bd -r c269b11bb810 Poster/riono-poster.graffle/image22.pdf Binary file Poster/riono-poster.graffle/image22.pdf has changed diff -r 309de2ffb2bd -r c269b11bb810 Poster/riono-poster.graffle/image33.pdf Binary file Poster/riono-poster.graffle/image33.pdf has changed diff -r 309de2ffb2bd -r c269b11bb810 Poster/riono-poster.pdf Binary file Poster/riono-poster.pdf has changed diff -r 309de2ffb2bd -r c269b11bb810 Slide/master-slide.html --- 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 @@
-

本研究における成果

+ + +

並列分散フレームワークChristieとUnity

@@ -114,46 +110,23 @@
- - -

概要

+

ChristieによるUnityネットワークゲーム実装の利点

    -
  • オンラインゲームにおける通信にはクライアントサーバ方式が主流 +
  • PUN2では企業ベースのServerが必要(開発がしづらい)
  • +
  • WAN上なので低速
      -
    • データの共有はサーバを経由するため低速
    • +
    • ChristieにするとLAN上での高速通信が可能
    • +
    • TopologyManagerを使うことによりLAN/WANで動的構成される
    • +
    • スケーラビリティーもTopologyManagerで実現できる(分散ルーティング)
    • +
    • Take/Putなので通信切断や遅延に対して対処しやすい
  • -
  • 当研究室で開発を行っているChristie の分散計算を使用することで、高速に通信できると考えた
  • -
  • Christie をUnity で使用するためにC# で書き換えを行った
  • -
  • Christie SharpとUnity既存の通信フレームワークとの機能的な比較を行った
  • -
- - - -
- -
- - - -

オンラインゲームにおけるデータ通信

-
    -
  • オンラインゲームは複数のプレイヤーが関与する分散プログラム +
  • Unityはフレーム単位の処理なため並列処理が苦手
      -
    • 分散プログラムを正しく書くことは難しい -
        -
      • ネットワークの変化、故障、性能の多様性を吸収する
      • -
      • スケーラビリティー リソースの追加のみでサービスの質の直感的に維持できる性能基準を備える
      • -
      -
    • -
    • Debugも困難な場合が多い
    • +
    • Christieにより画面書き換えと非同期な並列処理や通信が可能
  • -
  • クライアントの負荷軽減やチート対策のため、クライアントサーバ方式が主流 -
      -
    • データの同期にはサーバを経由するためp2pに比べ低速
    • -
    -
  • +
  • ChristieのMessagePack(データ通信ライブラリ)のバージョンの問題を解決
@@ -162,25 +135,32 @@
+

Christie の計算モデル

+
    +
  • DataGear(通信単位となるオブジェクト)が揃った時点でCodeGearが処理を開始
  • +
  • DataGearは決まったkeyでDataGearManagerにQueueとして格納
  • +
  • 相手nodeのDataGearManagerのproxyで通信
  • +
+
message
+ -

オンラインゲームにおけるデータ通信

+
+ +
+ +

DataGearのAPI

    -
  • 当研究室では並列分散通信フレームワークChristie を開発中である +
  • PutでQueueに追加
  • +
  • TakeでQueueからの取り出し
  • +
  • PeekでQueueから取り出さない読み出し
      -
    • 型のあるDataGear とKey を持つタプル空間、DataGearManager として格納している
    • -
    • 他のノードはDGM のproxyを持っており、proxy に書き込むことで通信を実現している
    • -
    • DGM はトポロジーマネージャーによって自動的に構築される -
        -
      • プログラム自体はDGM の名前を知っていれば良い
      • -
      • 他のノードのIP addressなどを知る必要はない
      • -
      -
    • +
    • Takeされない限り同じDataGearを読み出し続ける
  • -
  • ネットワークが切断されてもゲームは継続可能
  • -
  • 本研究ではChristieをC#で再実装を行い、Unityの通信ライブラリとして使用可能にする
  • -
  • 既存のUnityの通信ライブラリとの機能面での比較を行い、Christie Sharpのオンラインゲーム向けの通信ライブラリとしての考察を行う
  • +
  • フレームごとにPeekでゲームオブジェクトの状態をUnity側で見れる
  • +
  • 通信停止/遅延でもUnityの動作に影響を与えない
  • +
  • スケーラビリティやLAN/WAN構成はTopologyManagerのDGM porxyの管理
@@ -189,65 +169,25 @@
- - -

Christie の基礎概念

+

Java/C#のannotation

    -
  • Christie は当研究室で開発をしている並列分散通信フレームワークである -
      -
    • 同じく当研究室で開発しているGearsOS に導入予定のため次のような概念を持っている
    • -
    -
  • -
  • CodeGear (クラスやスレッド)
  • -
  • DataGear (変数データ)
  • -
  • CodeGearManager (CG,DG,DGMを管理)
  • -
  • DataGearManager (DGを管理,localとremoteの2種類がある, put操作によりDGを格納)
  • +
  • クラスやフィールドあるいはメソッドに付ける
  • +
  • ユーザ定義可能なmeta計算属性
  • +
  • MessagePackで通信可能なフィールドをannotationで指定する
  • +
  • Christieで通信パターンを指定するのにannotationを用いる
-
message
-
-各Gearの関係性 -
-
- - -

Christie の基礎概念

-
    -
  • 全てのCGM はThreadPool と他のCGM をList として共有している
  • -
  • ThreadPool はCPU に合わせた並列度でqueue に入ったThread を逐次実行していく -
      -
    • 1つのThreadPool で処理を行うことでCPU のコア数に適したThread を管理でき、並列度を下げ流ことを防ぐ
    • -
    -
  • -
  • ThreadPoolを共有することメタレベルで全てのCG/DG にアクセス可能
  • -
-
message
-
-Christie を同一プロセスで複数インスタンス立ち上げた際の接続の構造図 -
- - - -
- -
- - - -

Christie の基礎概念 annotationについて

-

DG を取り出すためにCG内に宣言した変数データにannotation をつける。annotationには以下の4つがある。

- +

DGのannotation

  • Take
    • 先頭のDG を読み込み、そのDG を削除する
    • -
    • DG が複数ある場合Take を使用する
  • Peek @@ -274,17 +214,63 @@
    +

    Christieによる分散プログラミング

    +
      +
    • Take/Put/Peekがデータベースのトランザクション
    • +
    • ここではトランザクションはゲームプレイヤー間の合意されたイベント
    • +
    • 複数のプレイヤーが関与する分散プログラムをTake/Put/Peekでローカルに記述できる
    • +
    • ローカルな記述を組み合わせて分散プログラムを記述する
    • +
    • ネットワークの変化、故障、性能の多様性を吸収する
    • +
    • Christieのデバッガー(モデル検査など)も使用可能
    • +
    • TopologyManagerで負荷軽減やチート対策が可能
    • +
    + + + +
    + +
    + +

    ローカルnodeから見たChristie

    +
      +
    • 型のあるDataGear とKey を持つタプル空間、DataGearManager として格納
    • +
    • 他のノードのDGM のproxyに書き込むことで通信
    • +
    • CodeGear (クラスやスレッド)
    • +
    • DataGear (変数データ)
    • +
    • CodeGearManager (CG,DG,DGMを管理)
    • +
    +
    message
    + -

    Topology Manager

    +
    + +
    + +

    Christie上でNetwork Topologyの形成

      -
    • Christie 上でNetwork Topology を形成する -
        -
      • 参加を表明したノードに名前を与える
      • -
      • 必要があればノード同士の配線を自動で行う
      • -
      +
    • 参加を表明したノードにDataGearManager proxyを決まった名前で作成
    • +
    • ノード同士の配線を指示
    • +
    • 分散プログラムの開始終了
    • +
    • Treeなどの動的Topologyは自動的に接続される
    • +
    +
    message
    + + + +
    + +
    + +

    Christie Sharp のコード例

    +
      +
    • Mainでport10001でChristie フレームワークを起動(CreateCGM)
    • +
    • 最初のCodeGearをCodeGearManagerに対して実行する +
      public static void Main(string[] args) {
      +  StartCountUp start = StartCountUp(createCGM(10001));
      +}
      +
    • -
    • 静的Topology と動的Topology 2種類がある
    @@ -293,97 +279,115 @@
    - - -

    Topology Manager 静的Topology

    +

    CodeGear StartCountUp

      -
    • 静的Topology は以下のようなdot ファイルを与えることでNode の関係を構築できる
    • -
    • それぞれのNode への通信にはIP address などは使用せずright というlabel を使用することで接続できる
    • -
    - -
    dot 形式による node 間接続の記述
    -
    digraph test {
    -	node0 -> node1 [label="right"]
    -	node1 -> node2 [label="right"]
    -	node2 -> node0 [label="right"]
    +  
  • CodeGearはCodeGearManagerを引数として持つ(baseでcgmに対してアクセスを許可)
  • +
  • CodeGearManagerがRun(cgm)をThreadPoolを使って呼び出す +
    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
    +  }
     }
     
    - -
    message
    -
    -ring状の接続 -
    - - +
  • - +

    CodeGear CountUpper

    +
  • +
  • key countのDataGearが来たらCountUpperのRunが実行される +
    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を終了
    +      }
    +  }
    +}
    +
    + -

    Topology Manager 静的Topology

    -
      -
    • 動的Topologyは以下の図のように自動的に接続される
    • -
    • 現在はTree型の接続のみに対応している
    • +
+ +
+ +

DataGear CountObject

+ +
  • MessagePackを使って通信されるDataGear
  • +
  • Take/Put/Peekはこれに対して行われる +
    [MessagePackObject]
    +public class CountObject {
    +  public int number;
    +  public CountObject(int number) {  // コンストラクタ
    +      this.number = number;
    +  }
    +}
    +
    +
  • -
    message
    -
    動的Topologyの接続手順
    -
    - - -

    Christie のコード例

    +

    Unityの従来の通信ライブラリ

      -
    • コンストラクタで与えた数字をインクリメントし、10回printする例題 -
      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);
      -  }
      -}
      -
      -

      ```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());
      -      count.number += 1;
      -      put("count", count);
      -  } else {
      -      cgm.getLocalDGM().finish();
      -  }   } }
      -
      +
    • Unityはフレーム単位で処理を行う
    • +
    • IEnumeratorでフレームを跨ぐ処理を記述する
    • +
    • Send/Recieveなどでは通信を記述しづらい
    • +
    • Photon Unity Network 2(PUN2) +
        +
      • Cloud ServerサービスPhoton Cloudがある
      • +
      • Server側は開発できない
      • +
      +
    • +
    • Mirror +
        +
      • OSSで開発が行われている
      • +
      • メソッドをServerで実行し結果を反映
      • +
    -
    ```java:CountObject.java
    -@Message
    -public class CountObject {
    -    public int number;
    +
    +
    +
    - public CountObject(int number) { - this.number = number; +
    + +

    Photon Unity Network2

    +
    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);
         }
     }
     
    @@ -394,11 +398,26 @@
    - - -

    Christie のコード例

    - -

    シーケンス図を使った説明

    +

    Mirror

    +
    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);
    +    }
    +}
    +
    @@ -406,27 +425,26 @@
    - - -

    C#への書き換えの意義

    +

    C#への書き換える利点

    • ChristieはJavaで実装されている
      • C#に書き換えを行うべきか
    • +
    • JavaをC#上で呼び出す方式 +
        +
      • annotationが使用できない
      • +
      +
    • Unityはandroidの開発向けにjarファイルからJavaのメソッドをC#上で呼び出せる機能がある
      • stringを使用してリソースディレクトリから検索し、使用
      • 高速化が求められる並列分散プログラミングには不適
    • -
    • JavaとC#の2つの管理が必要になる -
        -
      • C#とJavaは記述方法が非常に似ており、APIもほとんど同様な機能が実装されている
      • -
      • リポジトリをネスト化して対応
      • -
      -
    • +
    • 記述方法が似ているため移植が行いやすい
    • +
    • ThreadPoolをC#で統一できる
    @@ -435,9 +453,7 @@
    - - -

    書き換えの方針

    +

    書き換えの方針

    • C#で記述するChristieをChristie Sharpとする
    • Christie設計時の意図や、互換性を保つためChristieと同じ動作をさせる
    • @@ -456,100 +472,7 @@
      - - -

      Java からの変更点

      -
        -
      • Java とC# は基本的に書き方は変わらない
      • -
      - -
      Java
      -public class StartCountup extends StartCodeGear { }
      -
      -@Override
      -protected void run(CodeGearManager cgm) { }
      -
      -@Take String countObject;
      -
      - -
      C#
      -public class StartCountup : StartCodeGear { }
      -
      -public override void Run(CodeGearManager cgm) { }
      -
      -[Take] string countObject;
      -
      - - - -
      - -
      - - - -

      Christie Sharp のコード例

      -
      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);
      -    }
      -}
      -
      - -
      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();
      -        }
      -    }
      -}
      -
      - -
      [MessagePackObject]
      -public class CountObject {
      -    public int number;
      -
      -    public CountObject(int number) {
      -        this.number = number;
      -    }
      -}
      -
      - - - - -
      - -
      - - - -

      Take annotationの実装

      +

      Take annotationの実装

      • Christie ではDGを取得するためにannotation を使用している
          @@ -557,16 +480,18 @@
      • Take はフィールド変数に対して適用する
      • -
      - -
      @Target(ElementType.FIELD)
      +  
    • Javaの場合 +
      @Target(ElementType.FIELD)
       @Retention(RetentionPolicy.RUNTIME)
       public @interface Take { }
       
      - -
      [AttributeUsage(AttributeTargets.Field)]
      +  
    • +
    • C#の場合 +
      [AttributeUsage(AttributeTargets.Field)]
       public class Take : Attribute { }
       
      +
    • +
    @@ -574,123 +499,67 @@
    - - -

    MessagePackの相違点

    +

    MessagePackの相違点

      -
    • Christie ではMessagePack を使用してデータを圧縮し送受信している +
    • Christie ではMessagePack を使用してデータをシリアライズし送受信している
        -
      • インスタンス内のpublic 変数に対して圧縮可能
      • +
      • インスタンス内のpublic 変数に対してシリアライズ可能
    • -
    • バージョンが古いため、現在はサポートされていない -
        -
      • そのため、最新版とは記述方法が異なる
      • -
      -
    • -
    • 圧縮するクラスには@Message annotatoinをつける
    • -
    • MessagePack インスタンスを作成後、write、read することでデータの圧縮解凍が可能 -
        -
      • 圧縮されたデータはbyte[] 型になる
      • -
      +
    • 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);   // デシリアライズ
      +}
      +
    -
    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);
    -    }
    -}
    -
    -
    - - -

    MessagePackの相違点

    +

    MessagePackの相違点

    • C# のMessagePack は複数存在している
        -
      • java 版と似たような書き方をするMessagePack-CSharp を選択した
      • -
      -
    • -
    • 圧縮を行いたいクラスに対してMessagePackObject attribute を付ける
    • -
    • 圧縮する変数に対してkey を設定できる -
        -
      • 解凍時にjson として展開できる
      • -
      -
    • -
    • データの圧縮にはMessagePackSerializer.Serialize 関数を用い、byte[] に圧縮される
    • -
    • データの解凍にはMessagePackSerializer.Deserialize 関数を使用する -
        -
      • Deserialize 関数はジェネリスク関数であるため<>内に解凍するデータの型情報を記述する
      • -
      -
    • -
    - -
    [MessagePackObject]
    +      
  • java 版と似たような書き方をするMessagePack-CSharp を選択した +
    [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としても展開可能
    +  }
     }
     
    - - - -
  • - -
    - - - -

    ThreadPoolからTaskへの書き換え

    -
      -
    • Christie ではThreadPool を使用していた -
        -
      • Christie # ではThreadPoolより高機能なTask を用いて書き換えを行った
      • -
      -
    • -
    • Task は複雑な非同期処理を通常のコーディングと同じ感覚で直感的に記述できる
    • -
    • 裏でThreadPool が動くようになっている -
        -
      • 大きく動作は変わらない
      • +
    @@ -701,41 +570,47 @@
    - - -

    ThreadPoolからTaskへの書き換え

    - -
    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);
    -        }
    -    }
    +

    ThreadPoolからTaskへの書き換え

    +
      +
    • Christie ではThreadPool を使用していた +
      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);
      +      }
      +  }
       }
       
      + -
      public class ThreadPoolExecutors {
      -    
      -    public ThreadPoolExecutors(int nWorkerThreads, int nIOThreads) {
      -        ThreadPool.SetMinThreads(nWorkerThreads, nIOThreads);
      -    }
      -    
      -    public void Execute(CodeGearExecutor command) {
      -        Task.Factory.StartNew(() => command.Run());
      -    }
      +
    + +
    + +

    ThreadPoolからTaskへの書き換え

    + +
  • Christie Sharp ではThreadPoolより高機能なTask を用いて書き換えを行った
  • +
  • Task は複雑な非同期処理を通常のコーディングと同じ感覚で直感的に記述
  • +
  • 裏でThreadPool が動作するため大きく動作は変わらない +
    public class ThreadPoolExecutors {
    +  public ThreadPoolExecutors(int nWorkerThreads, int nIOThreads) {  // コンストラクタ
    +      ThreadPool.SetMinThreads(nWorkerThreads, nIOThreads);
    +  }
    +  public void Execute(CodeGearExecutor command) {
    +      Task.Factory.StartNew(() => command.Run());  // Taskを使用
    +  }
     }
     
    +
  • + @@ -743,20 +618,72 @@
    +

    Christie SharpのUnityのコード例

    +
      +
    • ゲームオブジェクトの座標をもう1つのゲームオブジェクトに追従させる例題
    • +
    • StartやUpdateはMonoBehaviourを継承する
    • +
    + +
    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());
    +    }
    +}
    +
    +
    -

    Unity

    +
    + +
    + +

    Christie SharpのUnityのコード例

      -
    • UnityはUnity Technologies が開発を行っているゲームエンジンである +
    • TransformなどのUnity AIPはMainThreadでのみ動作 +
      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);
      +  }
      +}
      +
      +
    • +
    + + + +
    + +
    + +

    Christie Sharpの利点

    +
      +
    • Unityのフレーム同期処理とChristieの並列分散処理が共存
        -
      • 世界中で使用されているゲームエンジン
      • -
      • 非常に軽く、スペックが低いノートPCでもゲーム開発が可能
      • -
      -
    • -
    • プログラミング言語にはC# が採用されている -
        -
      • C# のAPI やUnity 向けに拡張されたAPIも使用可能
      • -
      • 開発した機能をUnity に組み込むことも可能
      • +
      • CodeGear/DataGearを利用した待ち合わせ処理
      • +
      • CodeGearの処理はTaskによってThreadPoolで行われる
      • +
      • Christieを用いた非同期な並列処理が可能
      • +
      • 通信が切断した際にUnityの動作に影響を与えない
      • +
      • 通信先の参照データをPeekで待ち合わせないで取得する
      • +
      • Take/PutによりトランザクションとしてDataGearをUpdate
      • +
      • TopologyManagerによりDGMのproxyネットワークが構成される
      • +
      • TopologyManagerにCookieの機能があるため、改良すれば切断から復帰可能
    @@ -767,112 +694,19 @@
    - - -

    Christie # on Unityのコード例

    -
    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());
    -    }
    -}
    -
    -
    - -
    public class PositionAssignCodeGear : CodeGear {
    -    [Take] private Vector3 pos;
    -    [Peek] private Transform transform;
    -
    -    public override void Run(CodeGearManager cgm) {
    -        MainThreadDispatcher.Post(_ => {
    -            transform.position = pos;
    -        }, null);
    -    }
    -}
    -
    -
    - - - -
    - -
    - - - -

    Unityで使用されているライブラリとの比較

    -

    Unityで使用されている既存のライブラリとして、Photon Unity Networking 2(PUN2)、Mirrorと、Christie # の比較を行う。

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     Christie #PUN2Mirror
    通信方式p2pクライアントサーバ方式クライアントサーバ方式
    プロトコルTCPTCPTCP
    特徴通信のためのIP address がプログラム直接記述されていないPhoton Cloud でサーバを自前で用意する必要がないUnity公式でサポートされている RPC が使用可能
    - - - -
    - -
    - - - -

    Christie Sharpの利点

    +

    まとめ

      -
    • 単体でも並列処理が可能 +
    • Christie をUnity で使用するためにC# に書き換えを行った
    • +
    • 書き換え方針としては、attribute やMessagePack などC# 独自の機能に対応しつつ元のソースコードと同じ機能になるように実装
    • +
    • Unityで動作検証を行い、正しく動作することを確認した
        -
      • CodeGear/DataGearを利用した待ち合わせ処理
      • -
      • CodeGearの処理はTaskによってThreadPoolで行われる
      • -
      • 外部のライブラリを使用しなくてもUnityで強力な並列処理が可能
      • +
      • Christie Sharpを利用したゲームの開発が可能
      • +
      • ゲーム班などでネットワークゲームを容易にプログラムできる
    • -
    • 通信が切断した際にゲームロジックが停止しない -
        -
      • 通信先の参照データをPeekで取得する
      • -
      • DGMでproxyとしてデータはやりとりされているため、データは更新されないが参照は可能
      • -
      • TopologyManagerにCookieの機能があるため、改良すれば切断から復帰可能であると考える
      • -
      -
    • +
    • TopologyManagerで自由にネットワーク環境を構築できる
    • +
    • Take/Peek/Putを利用したゲームと相性の良いプログラミング
    • +
    • Unity既存のライブラリとの比較を行った
    @@ -881,24 +715,19 @@
    - - -

    まとめ

    -
      -
    • Christie をUnity で使用するためにC# に書き換えを行った
    • -
    • 書き換え方針としては、attribute やMessagePack などC# 独自の機能に対応しつつ元のソースコードと同じ機能になるようにした
    • -
    • Unityで動作検証を行い、正しく動作することを確認した
    • -
    • Unity既存のライブラリとの比較を行った
    • -
    - -

    今後の課題

    +

    今後の課題

    • TopologyManagerの完成
      • 2nd keyを用いたTreeMapの通信
    • -
    • Christie の性能検証を行う
    • +
    • Christie Sharpの性能検証を行う +
        +
      • Aliceで動作していた水族館の例題
      • +
      • Christie Sharpを用いた100人規模のゲーム開発
      • +
      +
    diff -r 309de2ffb2bd -r c269b11bb810 Slide/master-slide.md --- 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を格納) - -
    message
    -
    -各Gearの関係性 -
    - ---- - -### Christie の基礎概念 -* 全てのCGM はThreadPool と他のCGM をList として共有している -* ThreadPool はCPU に合わせた並列度でqueue に入ったThread を逐次実行していく - * 1つのThreadPool で処理を行うことでCPU のコア数に適したThread を管理でき、並列度を下げ流ことを防ぐ -* ThreadPoolを共有することメタレベルで全てのCG/DG にアクセス可能 -
    message
    -
    -Christie を同一プロセスで複数インスタンス立ち上げた際の接続の構造図 -
    +## 並列分散フレームワーク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で通信 +
    message
    -### 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を管理) +
    message
    -
    dot 形式による node 間接続の記述
    -```ring.dot -digraph test { - node0 -> node1 [label="right"] - node1 -> node2 [label="right"] - node2 -> node0 [label="right"] +## Christie上でNetwork Topologyの形成 +- 参加を表明したノードにDataGearManager proxyを決まった名前で作成 +* ノード同士の配線を指示 +- 分散プログラムの開始終了 +* Treeなどの動的Topologyは自動的に接続される +
    message
    + +## Christie Sharp のコード例 +- Mainでport10001でChristie フレームワークを起動(CreateCGM) +- 最初のCodeGearをCodeGearManagerに対して実行する +```cs +public static void Main(string[] args) { + StartCountUp start = StartCountUp(createCGM(10001)); } ``` -
    message
    -
    -ring状の接続 -
    - - ---- - -### Topology Manager 静的Topology -* 動的Topologyは以下の図のように自動的に接続される -* 現在はTree型の接続のみに対応している - -
    message
    -
    動的Topologyの接続手順
    - - ---- - -### 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().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().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; - } -} -``` - - ---- - -### 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(bytes); - + byte[] bytes = MessagePackSerializer.Serialize(mc);    // byte[] にシリアライズ + MyClass mc2 = MessagePackSerializer.Deserialize(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(10, - ComparableTask.comparatorByPriorityAndSequentialOrder())); - } - + super(corePoolSize, maximumPoolSize, keepAliveTime, unit, + (BlockingQueue) new PriorityBlockingQueue(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 の性能検証を行う - - - - diff -r 309de2ffb2bd -r c269b11bb810 riono-master.mm --- 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 @@ - - - + @@ -120,6 +118,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +