Introduce CSSAssertSetFailFunc and CSSAsserFail to throw managed exception

Summary:
- Define CSS_ASSERT_FAIL_ENABLED for P/Invoke (Visual Studio project already has it)
- Pass managed delegate pointer to unmanaged side via P/Invoke.
- CSSAssertFail will call the managed delegate when assert failed.
- The delegate will throw managed exception.

Reviewed By: emilsjolander

Differential Revision: D3982084

fbshipit-source-id: 058a87c10ca89238362be4d8759cc00dd0c9b376
This commit is contained in:
Kazuki Sakamoto
2016-10-07 12:31:06 -07:00
committed by Facebook Github Bot
parent 90844d62c5
commit 56f6efdecf
8 changed files with 92 additions and 9 deletions

View File

@@ -219,6 +219,7 @@ void _CSSNodeMarkDirty(const CSSNodeRef node) {
} }
void CSSNodeInsertChild(const CSSNodeRef node, const CSSNodeRef child, const uint32_t index) { void CSSNodeInsertChild(const CSSNodeRef node, const CSSNodeRef child, const uint32_t index) {
CSS_ASSERT(child->parent == NULL, "Child already has a parent, it must be removed first.");
CSSNodeListInsert(node->children, child, index); CSSNodeListInsert(node->children, child, index);
child->parent = node; child->parent = node;
_CSSNodeMarkDirty(node); _CSSNodeMarkDirty(node);
@@ -2295,3 +2296,17 @@ void CSSNodeCalculateLayout(const CSSNodeRef node,
} }
} }
} }
#ifdef CSS_ASSERT_FAIL_ENABLED
static CSSAssertFailFunc gAssertFailFunc;
void CSSAssertSetFailFunc(CSSAssertFailFunc func) {
gAssertFailFunc = func;
}
void CSSAssertFail(const char *message) {
if (gAssertFailFunc) {
(*gAssertFailFunc)(message);
}
}
#endif

View File

@@ -122,6 +122,10 @@ typedef CSSSize (*CSSMeasureFunc)(void *context,
CSSMeasureMode heightMode); CSSMeasureMode heightMode);
typedef void (*CSSPrintFunc)(void *context); typedef void (*CSSPrintFunc)(void *context);
#ifdef CSS_ASSERT_FAIL_ENABLED
typedef void (*CSSAssertFailFunc)(const char *message);
#endif
// CSSNode // CSSNode
WIN_EXPORT CSSNodeRef CSSNodeNew(); WIN_EXPORT CSSNodeRef CSSNodeNew();
WIN_EXPORT void CSSNodeInit(const CSSNodeRef node); WIN_EXPORT void CSSNodeInit(const CSSNodeRef node);
@@ -206,4 +210,10 @@ CSS_NODE_LAYOUT_PROPERTY(float, Width);
CSS_NODE_LAYOUT_PROPERTY(float, Height); CSS_NODE_LAYOUT_PROPERTY(float, Height);
CSS_NODE_LAYOUT_PROPERTY(CSSDirection, Direction); CSS_NODE_LAYOUT_PROPERTY(CSSDirection, Direction);
#ifdef CSS_ASSERT_FAIL_ENABLED
// Assert
WIN_EXPORT void CSSAssertSetFailFunc(CSSAssertFailFunc func);
WIN_EXPORT void CSSAssertFail(const char *message);
#endif
CSS_EXTERN_C_END CSS_EXTERN_C_END

View File

@@ -33,8 +33,16 @@
#define CSS_ABORT() #define CSS_ABORT()
#endif #endif
#define CSS_ASSERT(X, message) \ #if CSS_ASSERT_FAIL_ENABLED
if (!(X)) { \ #define CSS_ERROR_FUNC(message) CSSAssertFail(message)
fprintf(stderr, "%s\n", message); \ #else
CSS_ABORT(); \ #define CSS_ERROR_FUNC(message) fprintf(stderr, "%s", message)
#endif
#ifndef CSS_ASSERT
#define CSS_ASSERT(X, message) \
if (!(X)) { \
CSS_ERROR_FUNC(message); \
CSS_ABORT(); \
} }
#endif

10
csharp/CSSLayout/CSSLayout.vcxproj Normal file → Executable file
View File

@@ -87,7 +87,7 @@
</PrecompiledHeader> </PrecompiledHeader>
<WarningLevel>Level3</WarningLevel> <WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;CSSLAYOUT_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;CSSLAYOUT_EXPORTS;CSS_ASSERT_FAIL_ENABLED;FB_ASSERTIONS_ENABLED=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
</ClCompile> </ClCompile>
<Link> <Link>
@@ -101,7 +101,7 @@
</PrecompiledHeader> </PrecompiledHeader>
<WarningLevel>Level3</WarningLevel> <WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_DEBUG;_WINDOWS;_USRDLL;CSSLAYOUT_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>_DEBUG;_WINDOWS;_USRDLL;CSSLAYOUT_EXPORTS;CSS_ASSERT_FAIL_ENABLED;FB_ASSERTIONS_ENABLED=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
</ClCompile> </ClCompile>
<Link> <Link>
@@ -117,7 +117,7 @@
<Optimization>MaxSpeed</Optimization> <Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;CSSLAYOUT_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;CSSLAYOUT_EXPORTS;CSS_ASSERT_FAIL_ENABLED;FB_ASSERTIONS_ENABLED=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
</ClCompile> </ClCompile>
<Link> <Link>
@@ -135,7 +135,7 @@
<Optimization>MaxSpeed</Optimization> <Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>NDEBUG;_WINDOWS;_USRDLL;CSSLAYOUT_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>NDEBUG;_WINDOWS;_USRDLL;CSSLAYOUT_EXPORTS;CSS_ASSERT_FAIL_ENABLED;FB_ASSERTIONS_ENABLED=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
</ClCompile> </ClCompile>
<Link> <Link>
@@ -174,4 +174,4 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets"> <ImportGroup Label="ExtensionTargets">
</ImportGroup> </ImportGroup>
</Project> </Project>

View File

@@ -0,0 +1,31 @@
/**
* Copyright (c) 2014-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
using System;
namespace Facebook.CSSLayout
{
internal static class CSSAssert
{
public delegate void FailFunc(string message);
private static bool _assertInitialized;
public static void Initialize()
{
if (!_assertInitialized)
{
Native.CSSAssertSetFailFunc((message) => {
throw new InvalidOperationException(message);
});
_assertInitialized = true;
}
}
}
}

View File

@@ -93,6 +93,7 @@ namespace Facebook.CSSLayout
throw new InvalidOperationException("Allready initialized node"); throw new InvalidOperationException("Allready initialized node");
} }
CSSAssert.Initialize();
_cssNode = Native.CSSNodeNew(); _cssNode = Native.CSSNodeNew();
_children = new List<CSSNode>(4); _children = new List<CSSNode>(4);
Native.CSSNodeSetPrintFunc(_cssNode, _printFunc); Native.CSSNodeSetPrintFunc(_cssNode, _printFunc);

View File

@@ -20,6 +20,9 @@ namespace Facebook.CSSLayout
private const string DllName = "CSSLayout"; private const string DllName = "CSSLayout";
#endif #endif
[DllImport(DllName)]
public static extern void CSSAssertSetFailFunc(CSSAssert.FailFunc func);
[DllImport(DllName)] [DllImport(DllName)]
public static extern IntPtr CSSNodeNew(); public static extern IntPtr CSSNodeNew();

View File

@@ -41,6 +41,21 @@ namespace Facebook.CSSLayout
Assert.AreEqual(0, parent.Count); Assert.AreEqual(0, parent.Count);
} }
[Test]
[ExpectedException("System.InvalidOperationException")]
public void TestCannotAddChildToMultipleParents()
{
CSSNode parent1 = new CSSNode();
parent1.Initialize();
CSSNode parent2 = new CSSNode();
parent2.Initialize();
CSSNode child = new CSSNode();
child.Initialize();
parent1.Insert(0, child);
parent2.Insert(0, child);
}
[Test] [Test]
[ExpectedException("System.InvalidOperationException")] [ExpectedException("System.InvalidOperationException")]
public void TestAlreadyInitialize() public void TestAlreadyInitialize()